<commit_before>##############################################################################
# Copyright (c) 2013, Lawrence Livermore National Security, LLC.
# Produced at the Lawrence Livermore National Laboratory.
#
# This file is part of Spack.
# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
# LLNL-CODE-647188
#
# For details, see https://github.com/llnl/spack
# Please also see the LICENSE file for our notice and the LGPL.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License (as published by
# the Free Software Foundation) version 2.1 dated February 1999.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
# conditions of the GNU General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
import textwrap
from llnl.util.tty.colify import *
import spack
import spack.fetch_strategy as fs

description = "Get detailed information on a particular package"

def padder(str_list, extra=0):
    """Return a function to pad elements of a list."""
    length = max(len(str(s)) for s in str_list) + extra
    def pad(string):
        string = str(string)
        padding = max(0, length - len(string))
        return string + (padding * ' ')
    return pad

def setup_parser(subparser):
    subparser.add_argument('name', metavar="PACKAGE", help="Name of package to get info for.")

def print_text_info(pkg):
    """Print out a plain text description of a package."""
    print "Package:   ", pkg.name
    print "Homepage:  ", pkg.homepage

    print
    print "Safe versions:  "

    if not pkg.versions:
        print("None")
    else:
        pad = padder(pkg.versions, 4)
        for v in reversed(sorted(pkg.versions)):
            f = fs.for_package_version(pkg, v)
            print "    %s%s" % (pad(v), str(f))

    print
    print "Variants:"
    if not pkg.variants:
        print "None"
    else:
        pad = padder(pkg.variants, 4)

        maxv = max(len(v) for v in sorted(pkg.variants))
        fmt = "%%-%ss%%-10s%%s" % (maxv + 4)

        print "    " + fmt % ('Name',   'Default',   'Description')
        print
        for name in sorted(pkg.variants):
            v = pkg.variants[name]
            default = 'on' if v.default else 'off'

            lines = textwrap.wrap(v.description)
            lines[1:] = ["      " + (" " * maxv) + l for l in lines[1:]]
            desc = "\n".join(lines)

            print "    " + fmt % (name, default, desc)

    print
    print "Dependencies:"
    if pkg.dependencies:
        colify(pkg.dependencies, indent=4)
    else:
        print "    None"

    print
    print "Virtual packages: "
    if pkg.provided:
        for spec, when in pkg.provided.items():
            print "    %s provides %s" % (when, spec)
    else:
        print "    None"

    print
    print "Description:"
    if pkg.__doc__:
        print pkg.format_doc(indent=4)
    else:
        print "    None"

def info(parser, args):
    pkg = spack.repo.get(args.name)
    print_text_info(pkg)
<commit_msg>Fix spack info indentation<commit_after>##############################################################################
# Copyright (c) 2013, Lawrence Livermore National Security, LLC.
# Produced at the Lawrence Livermore National Laboratory.
#
# This file is part of Spack.
# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
# LLNL-CODE-647188
#
# For details, see https://github.com/llnl/spack
# Please also see the LICENSE file for our notice and the LGPL.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License (as published by
# the Free Software Foundation) version 2.1 dated February 1999.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
# conditions of the GNU General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
import textwrap
from llnl.util.tty.colify import *
import spack
import spack.fetch_strategy as fs

description = "Get detailed information on a particular package"

def padder(str_list, extra=0):
    """Return a function to pad elements of a list."""
    length = max(len(str(s)) for s in str_list) + extra
    def pad(string):
        string = str(string)
        padding = max(0, length - len(string))
        return string + (padding * ' ')
    return pad

def setup_parser(subparser):
    subparser.add_argument('name', metavar="PACKAGE", help="Name of package to get info for.")

def print_text_info(pkg):
    """Print out a plain text description of a package."""
    print "Package:   ", pkg.name
    print "Homepage:  ", pkg.homepage

    print
    print "Safe versions:  "

    if not pkg.versions:
        print("    None")
    else:
        pad = padder(pkg.versions, 4)
        for v in reversed(sorted(pkg.versions)):
            f = fs.for_package_version(pkg, v)
            print "    %s%s" % (pad(v), str(f))

    print
    print "Variants:"
    if not pkg.variants:
        print "    None"
    else:
        pad = padder(pkg.variants, 4)

        maxv = max(len(v) for v in sorted(pkg.variants))
        fmt = "%%-%ss%%-10s%%s" % (maxv + 4)

        print "    " + fmt % ('Name',   'Default',   'Description')
        print
        for name in sorted(pkg.variants):
            v = pkg.variants[name]
            default = 'on' if v.default else 'off'

            lines = textwrap.wrap(v.description)
            lines[1:] = ["      " + (" " * maxv) + l for l in lines[1:]]
            desc = "\n".join(lines)

            print "    " + fmt % (name, default, desc)

    print
    print "Dependencies:"
    if pkg.dependencies:
        colify(pkg.dependencies, indent=4)
    else:
        print "    None"

    print
    print "Virtual packages: "
    if pkg.provided:
        for spec, when in pkg.provided.items():
            print "    %s provides %s" % (when, spec)
    else:
        print "    None"

    print
    print "Description:"
    if pkg.__doc__:
        print pkg.format_doc(indent=4)
    else:
        print "    None"

def info(parser, args):
    pkg = spack.repo.get(args.name)
    print_text_info(pkg)
<|endoftext|>


<commit_before># Copyright 2013-2019 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)

import os
import re
import itertools
import shutil
import tempfile

import llnl.util.filesystem
import llnl.util.tty as tty

import spack.error
import spack.spec
import spack.architecture
import spack.util.executable
import spack.compilers
from spack.util.environment import filter_system_paths

__all__ = ['Compiler']

def _verify_executables(*paths):
    for path in paths:
        if not os.path.isfile(path) and os.access(path, os.X_OK):
            raise CompilerAccessError(path)

@llnl.util.lang.memoized
def get_compiler_version_output(compiler_path, version_arg):
    """Invokes the compiler at a given path passing a single
    version argument and returns the output.

    Args:
        compiler_path (path): path of the compiler to be invoked
        version_arg (str): the argument used to extract version information
    """
    compiler = spack.util.executable.Executable(compiler_path)
    output = compiler(version_arg, output=str, error=str)
    return output

def tokenize_flags(flags_str):
    """Given a compiler flag specification as a string, this returns a list
       where the entries are the flags. For compiler options which set values
       using the syntax "-flag value", this function groups flags and their
       values together. Any token not preceded by a "-" is considered the
       value of a prior flag."""
    tokens = flags_str.split()
    if not tokens:
        return []
    flag = tokens[0]
    flags = []
    for token in tokens[1:]:
        if not token.startswith('-'):
            flag += ' ' + token
        else:
            flags.append(flag)
            flag = token
    flags.append(flag)
    return flags

#: regex for parsing linker lines
_LINKER_LINE = re.compile(
    r'^( *|.*[/\\])'
    r'(link|ld|([^/\\]+-)?ld|collect2)'
    r'[^/\\]*( |$)')

#: components of linker lines to ignore
_LINKER_LINE_IGNORE = re.compile(r'(collect2 version|^[A-Za-z0-9_]+=|/ldfe )')

#: regex to match linker search paths
_LINK_DIR_ARG = re.compile(r'^-L(.:)?(?P<dir>[/\\].*)')

#: regex to match linker library path arguments
_LIBPATH_ARG = re.compile(r'^[-/](LIBPATH|libpath):(?P<dir>.*)')

def is_subdirectory(path, prefix):
    path = os.path.abspath(path)
    prefix = os.path.abspath(prefix) + os.path.sep
    return path.startswith(prefix)

def _parse_implicit_rpaths(string):
    """Parse implicit link paths from compiler debug output.

    This gives the compiler runtime library paths that we need to add to
    the RPATH of generated binaries and libraries.  It allows us to
    ensure, e.g., that codes load the right libstdc++ for their compiler.
    """
    lib_search_paths = False
    raw_link_dirs = []
    tty.debug('parsing implicit link info')
    for line in string.splitlines():
        if lib_search_paths:
            if line.startswith('\t'):
                raw_link_dirs.append(line[1:])
                continue
            else:
                lib_search_paths = False
        elif line.startswith('Library search paths:'):
            lib_search_paths = True

        if not _LINKER_LINE.match(line):
            continue
        if _LINKER_LINE_IGNORE.match(line):
            continue
        tty.debug('linker line: %s' % line)

        next_arg = False
        for arg in line.split():
            if arg in ('-L', '-Y'):
                next_arg = True
                continue

            if next_arg:
                raw_link_dirs.append(arg)
                next_arg = False
                continue

            link_dir_arg = _LINK_DIR_ARG.match(arg)
            if link_dir_arg:
                link_dir = link_dir_arg.group('dir')
                tty.debug('linkdir: %s' % link_dir)
                raw_link_dirs.append(link_dir)

            link_dir_arg = _LIBPATH_ARG.match(arg)
            if link_dir_arg:
                link_dir = link_dir_arg.group('dir')
                tty.debug('libpath: %s', link_dir)
                raw_link_dirs.append(link_dir)
    tty.debug('found raw link dirs: %s' % ', '.join(raw_link_dirs))

    implicit_link_dirs = list()
    visited = set()
    for link_dir in raw_link_dirs:
        normalized_path = os.path.abspath(link_dir)
        if normalized_path not in visited:
            implicit_link_dirs.append(normalized_path)
            visited.add(normalized_path)
    implicit_link_dirs = filter_system_paths(implicit_link_dirs)

    # Additional filtering: we also want to exclude paths that are
    # subdirectories of /usr/lib/ and /lib/
    implicit_link_dirs = list(
        path for path in implicit_link_dirs
        if not any(is_subdirectory(path, d) for d in ['/lib/', '/usr/lib/']))

    tty.debug('found link dirs: %s' % ', '.join(implicit_link_dirs))
    return implicit_link_dirs

class Compiler(object):
    """This class encapsulates a Spack "compiler", which includes C,
       C++, and Fortran compilers.  Subclasses should implement
       support for specific compilers, their possible names, arguments,
       and how to identify the particular type of compiler."""

    # Subclasses use possible names of C compiler
    cc_names = []

    # Subclasses use possible names of C++ compiler
    cxx_names = []

    # Subclasses use possible names of Fortran 77 compiler
    f77_names = []

    # Subclasses use possible names of Fortran 90 compiler
    fc_names = []

    # Optional prefix regexes for searching for this type of compiler.
    # Prefixes are sometimes used for toolchains, e.g. 'powerpc-bgq-linux-'
    prefixes = []

    # Optional suffix regexes for searching for this type of compiler.
    # Suffixes are used by some frameworks, e.g. macports uses an '-mp-X.Y'
    # version suffix for gcc.
    suffixes = [r'-.*']

    #: Compiler argument that produces version information
    version_argument = '-dumpversion'

    #: Regex used to extract version from compiler's output
    version_regex = '(.*)'

    # Default flags used by a compiler to set an rpath
    @property
    def cc_rpath_arg(self):
        return '-Wl,-rpath,'

    @property
    def cxx_rpath_arg(self):
        return '-Wl,-rpath,'

    @property
    def f77_rpath_arg(self):
        return '-Wl,-rpath,'

    @property
    def fc_rpath_arg(self):
        return '-Wl,-rpath,'
    # Cray PrgEnv name that can be used to load this compiler
    PrgEnv = None
    # Name of module used to switch versions of this compiler
    PrgEnv_compiler = None

    def __init__(self, cspec, operating_system, target,
                 paths, modules=[], alias=None, environment=None,
                 extra_rpaths=None, implicit_rpaths=None,
                 **kwargs):
        self.spec = cspec
        self.operating_system = str(operating_system)
        self.target = target
        self.modules = modules
        self.alias = alias
        self.extra_rpaths = extra_rpaths
        self.implicit_rpaths = implicit_rpaths

        def check(exe):
            if exe is None:
                return None
            _verify_executables(exe)
            return exe

        self.cc  = check(paths[0])
        self.cxx = check(paths[1])
        if len(paths) > 2:
            self.f77 = check(paths[2])
            if len(paths) == 3:
                self.fc = self.f77
            else:
                self.fc  = check(paths[3])

        self.environment = environment
        self.extra_rpaths = extra_rpaths or []

        # Unfortunately have to make sure these params are accepted
        # in the same order they are returned by sorted(flags)
        # in compilers/__init__.py
        self.flags = {}
        for flag in spack.spec.FlagMap.valid_compiler_flags():
            value = kwargs.get(flag, None)
            if value is not None:
                self.flags[flag] = tokenize_flags(value)

    @property
    def version(self):
        return self.spec.version

    @classmethod
    def verbose_flag(cls):
        """
        This property should be overridden in the compiler subclass if a
        verbose flag is available.

        If it is not overridden, it is assumed to not be supported.
        """

    @classmethod
    def parse_implicit_rpaths(cls, string):
        """Parses link paths out of compiler debug output.

        Args:
            string (str): compiler debug output as a string

        Returns:
            (list of str): implicit link paths parsed from the compiler output

        Subclasses can override this to customize.
        """
        return _parse_implicit_rpaths(string)

    @classmethod
    def determine_implicit_rpaths(cls, paths):
        first_compiler = next((c for c in paths if c), None)
        if not first_compiler:
            return []

        try:
            tmpdir = tempfile.mkdtemp(prefix='spack-implicit-link-info')
            fout = os.path.join(tmpdir, 'output')
            fin = os.path.join(tmpdir, 'main.c')

            with open(fin, 'w+') as csource:
                csource.write(
                    'int main(int argc, char* argv[]) { '
                    '(void)argc; (void)argv; return 0; }\n')
            compiler_exe = spack.util.executable.Executable(first_compiler)
            output = str(compiler_exe(cls.verbose_flag(), fin, '-o', fout,
                                      output=str, error=str))  # str for py2

            return cls.parse_implicit_rpaths(output)
        finally:
            shutil.rmtree(tmpdir, ignore_errors=True)

    # This property should be overridden in the compiler subclass if
    # OpenMP is supported by that compiler
    @property
    def openmp_flag(self):
        # If it is not overridden, assume it is not supported and warn the user
        raise UnsupportedCompilerFlag(self, "OpenMP", "openmp_flag")

    # This property should be overridden in the compiler subclass if
    # C++98 is not the default standard for that compiler
    @property
    def cxx98_flag(self):
        return ""

    # This property should be overridden in the compiler subclass if
    # C++11 is supported by that compiler
    @property
    def cxx11_flag(self):
        # If it is not overridden, assume it is not supported and warn the user
        raise UnsupportedCompilerFlag(self,
                                      "the C++11 standard",
                                      "cxx11_flag")

    # This property should be overridden in the compiler subclass if
    # C++14 is supported by that compiler
    @property
    def cxx14_flag(self):
        # If it is not overridden, assume it is not supported and warn the user
        raise UnsupportedCompilerFlag(self,
                                      "the C++14 standard",
                                      "cxx14_flag")

    # This property should be overridden in the compiler subclass if
    # C++17 is supported by that compiler
    @property
    def cxx17_flag(self):
        # If it is not overridden, assume it is not supported and warn the user
        raise UnsupportedCompilerFlag(self,
                                      "the C++17 standard",
                                      "cxx17_flag")

    # This property should be overridden in the compiler subclass if
    # C99 is supported by that compiler
    @property
    def c99_flag(self):
        # If it is not overridden, assume it is not supported and warn the user
        raise UnsupportedCompilerFlag(self,
                                      "the C99 standard",
                                      "c99_flag")

    # This property should be overridden in the compiler subclass if
    # C11 is supported by that compiler
    @property
    def c11_flag(self):
        # If it is not overridden, assume it is not supported and warn the user
        raise UnsupportedCompilerFlag(self,
                                      "the C11 standard",
                                      "c11_flag")

    #
    # Compiler classes have methods for querying the version of
    # specific compiler executables.  This is used when discovering compilers.
    #
    # Compiler *instances* are just data objects, and can only be
    # constructed from an actual set of executables.
    #
    @classmethod
    def default_version(cls, cc):
        """Override just this to override all compiler version functions."""
        output = get_compiler_version_output(cc, cls.version_argument)
        return cls.extract_version_from_output(output)

    @classmethod
    @llnl.util.lang.memoized
    def extract_version_from_output(cls, output):
        """Extracts the version from compiler's output."""
        match = re.search(cls.version_regex, output)
        return match.group(1) if match else 'unknown'

    @classmethod
    def cc_version(cls, cc):
        return cls.default_version(cc)

    @classmethod
    def cxx_version(cls, cxx):
        return cls.default_version(cxx)

    @classmethod
    def f77_version(cls, f77):
        return cls.default_version(f77)

    @classmethod
    def fc_version(cls, fc):
        return cls.default_version(fc)

    @classmethod
    def search_regexps(cls, language):
        # Compile all the regular expressions used for files beforehand.
        # This searches for any combination of <prefix><name><suffix>
        # defined for the compiler
        compiler_names = getattr(cls, '{0}_names'.format(language))
        prefixes = [''] + cls.prefixes
        suffixes = [''] + cls.suffixes
        regexp_fmt = r'^({0}){1}({2})$'
        return [
            re.compile(regexp_fmt.format(prefix, re.escape(name), suffix))
            for prefix, name, suffix in
            itertools.product(prefixes, compiler_names, suffixes)
        ]

    def setup_custom_environment(self, pkg, env):
        """Set any environment variables necessary to use the compiler."""
        pass

    def __repr__(self):
        """Return a string representation of the compiler toolchain."""
        return self.__str__()

    def __str__(self):
        """Return a string representation of the compiler toolchain."""
        return "%s(%s)" % (
            self.name, '\n     '.join((str(s) for s in (
                self.cc, self.cxx, self.f77, self.fc, self.modules,
                str(self.operating_system)))))

class CompilerAccessError(spack.error.SpackError):

    def __init__(self, path):
        super(CompilerAccessError, self).__init__(
            "'%s' is not a valid compiler." % path)

class InvalidCompilerError(spack.error.SpackError):

    def __init__(self):
        super(InvalidCompilerError, self).__init__(
            "Compiler has no executables.")

class UnsupportedCompilerFlag(spack.error.SpackError):

    def __init__(self, compiler, feature, flag_name, ver_string=None):
        super(UnsupportedCompilerFlag, self).__init__(
            "{0} ({1}) does not support {2} (as compiler.{3})."
            .format(compiler.name,
                    ver_string if ver_string else compiler.version,
                    feature,
                    flag_name),
            "If you think it should, please edit the compiler.{0} subclass to"
            .format(compiler.name) +
            " implement the {0} property and submit a pull request or issue."
            .format(flag_name)
        )
<commit_msg>Allow build to proceed with failed compiler lib detection (#12756)<commit_after># Copyright 2013-2019 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)

import os
import re
import itertools
import shutil
import tempfile

import llnl.util.filesystem
import llnl.util.tty as tty

import spack.error
import spack.spec
import spack.architecture
import spack.util.executable
import spack.compilers
from spack.util.environment import filter_system_paths

__all__ = ['Compiler']

def _verify_executables(*paths):
    for path in paths:
        if not os.path.isfile(path) and os.access(path, os.X_OK):
            raise CompilerAccessError(path)

@llnl.util.lang.memoized
def get_compiler_version_output(compiler_path, version_arg):
    """Invokes the compiler at a given path passing a single
    version argument and returns the output.

    Args:
        compiler_path (path): path of the compiler to be invoked
        version_arg (str): the argument used to extract version information
    """
    compiler = spack.util.executable.Executable(compiler_path)
    output = compiler(version_arg, output=str, error=str)
    return output

def tokenize_flags(flags_str):
    """Given a compiler flag specification as a string, this returns a list
       where the entries are the flags. For compiler options which set values
       using the syntax "-flag value", this function groups flags and their
       values together. Any token not preceded by a "-" is considered the
       value of a prior flag."""
    tokens = flags_str.split()
    if not tokens:
        return []
    flag = tokens[0]
    flags = []
    for token in tokens[1:]:
        if not token.startswith('-'):
            flag += ' ' + token
        else:
            flags.append(flag)
            flag = token
    flags.append(flag)
    return flags

#: regex for parsing linker lines
_LINKER_LINE = re.compile(
    r'^( *|.*[/\\])'
    r'(link|ld|([^/\\]+-)?ld|collect2)'
    r'[^/\\]*( |$)')

#: components of linker lines to ignore
_LINKER_LINE_IGNORE = re.compile(r'(collect2 version|^[A-Za-z0-9_]+=|/ldfe )')

#: regex to match linker search paths
_LINK_DIR_ARG = re.compile(r'^-L(.:)?(?P<dir>[/\\].*)')

#: regex to match linker library path arguments
_LIBPATH_ARG = re.compile(r'^[-/](LIBPATH|libpath):(?P<dir>.*)')

def is_subdirectory(path, prefix):
    path = os.path.abspath(path)
    prefix = os.path.abspath(prefix) + os.path.sep
    return path.startswith(prefix)

def _parse_implicit_rpaths(string):
    """Parse implicit link paths from compiler debug output.

    This gives the compiler runtime library paths that we need to add to
    the RPATH of generated binaries and libraries.  It allows us to
    ensure, e.g., that codes load the right libstdc++ for their compiler.
    """
    lib_search_paths = False
    raw_link_dirs = []
    tty.debug('parsing implicit link info')
    for line in string.splitlines():
        if lib_search_paths:
            if line.startswith('\t'):
                raw_link_dirs.append(line[1:])
                continue
            else:
                lib_search_paths = False
        elif line.startswith('Library search paths:'):
            lib_search_paths = True

        if not _LINKER_LINE.match(line):
            continue
        if _LINKER_LINE_IGNORE.match(line):
            continue
        tty.debug('linker line: %s' % line)

        next_arg = False
        for arg in line.split():
            if arg in ('-L', '-Y'):
                next_arg = True
                continue

            if next_arg:
                raw_link_dirs.append(arg)
                next_arg = False
                continue

            link_dir_arg = _LINK_DIR_ARG.match(arg)
            if link_dir_arg:
                link_dir = link_dir_arg.group('dir')
                tty.debug('linkdir: %s' % link_dir)
                raw_link_dirs.append(link_dir)

            link_dir_arg = _LIBPATH_ARG.match(arg)
            if link_dir_arg:
                link_dir = link_dir_arg.group('dir')
                tty.debug('libpath: %s', link_dir)
                raw_link_dirs.append(link_dir)
    tty.debug('found raw link dirs: %s' % ', '.join(raw_link_dirs))

    implicit_link_dirs = list()
    visited = set()
    for link_dir in raw_link_dirs:
        normalized_path = os.path.abspath(link_dir)
        if normalized_path not in visited:
            implicit_link_dirs.append(normalized_path)
            visited.add(normalized_path)
    implicit_link_dirs = filter_system_paths(implicit_link_dirs)

    # Additional filtering: we also want to exclude paths that are
    # subdirectories of /usr/lib/ and /lib/
    implicit_link_dirs = list(
        path for path in implicit_link_dirs
        if not any(is_subdirectory(path, d) for d in ['/lib/', '/usr/lib/']))

    tty.debug('found link dirs: %s' % ', '.join(implicit_link_dirs))
    return implicit_link_dirs

class Compiler(object):
    """This class encapsulates a Spack "compiler", which includes C,
       C++, and Fortran compilers.  Subclasses should implement
       support for specific compilers, their possible names, arguments,
       and how to identify the particular type of compiler."""

    # Subclasses use possible names of C compiler
    cc_names = []

    # Subclasses use possible names of C++ compiler
    cxx_names = []

    # Subclasses use possible names of Fortran 77 compiler
    f77_names = []

    # Subclasses use possible names of Fortran 90 compiler
    fc_names = []

    # Optional prefix regexes for searching for this type of compiler.
    # Prefixes are sometimes used for toolchains, e.g. 'powerpc-bgq-linux-'
    prefixes = []

    # Optional suffix regexes for searching for this type of compiler.
    # Suffixes are used by some frameworks, e.g. macports uses an '-mp-X.Y'
    # version suffix for gcc.
    suffixes = [r'-.*']

    #: Compiler argument that produces version information
    version_argument = '-dumpversion'

    #: Regex used to extract version from compiler's output
    version_regex = '(.*)'

    # Default flags used by a compiler to set an rpath
    @property
    def cc_rpath_arg(self):
        return '-Wl,-rpath,'

    @property
    def cxx_rpath_arg(self):
        return '-Wl,-rpath,'

    @property
    def f77_rpath_arg(self):
        return '-Wl,-rpath,'

    @property
    def fc_rpath_arg(self):
        return '-Wl,-rpath,'
    # Cray PrgEnv name that can be used to load this compiler
    PrgEnv = None
    # Name of module used to switch versions of this compiler
    PrgEnv_compiler = None

    def __init__(self, cspec, operating_system, target,
                 paths, modules=[], alias=None, environment=None,
                 extra_rpaths=None, implicit_rpaths=None,
                 **kwargs):
        self.spec = cspec
        self.operating_system = str(operating_system)
        self.target = target
        self.modules = modules
        self.alias = alias
        self.extra_rpaths = extra_rpaths
        self.implicit_rpaths = implicit_rpaths

        def check(exe):
            if exe is None:
                return None
            _verify_executables(exe)
            return exe

        self.cc  = check(paths[0])
        self.cxx = check(paths[1])
        if len(paths) > 2:
            self.f77 = check(paths[2])
            if len(paths) == 3:
                self.fc = self.f77
            else:
                self.fc  = check(paths[3])

        self.environment = environment
        self.extra_rpaths = extra_rpaths or []

        # Unfortunately have to make sure these params are accepted
        # in the same order they are returned by sorted(flags)
        # in compilers/__init__.py
        self.flags = {}
        for flag in spack.spec.FlagMap.valid_compiler_flags():
            value = kwargs.get(flag, None)
            if value is not None:
                self.flags[flag] = tokenize_flags(value)

    @property
    def version(self):
        return self.spec.version

    @classmethod
    def verbose_flag(cls):
        """
        This property should be overridden in the compiler subclass if a
        verbose flag is available.

        If it is not overridden, it is assumed to not be supported.
        """

    @classmethod
    def parse_implicit_rpaths(cls, string):
        """Parses link paths out of compiler debug output.

        Args:
            string (str): compiler debug output as a string

        Returns:
            (list of str): implicit link paths parsed from the compiler output

        Subclasses can override this to customize.
        """
        return _parse_implicit_rpaths(string)

    @classmethod
    def determine_implicit_rpaths(cls, paths):
        first_compiler = next((c for c in paths if c), None)
        if not first_compiler:
            return []

        try:
            tmpdir = tempfile.mkdtemp(prefix='spack-implicit-link-info')
            fout = os.path.join(tmpdir, 'output')
            fin = os.path.join(tmpdir, 'main.c')

            with open(fin, 'w+') as csource:
                csource.write(
                    'int main(int argc, char* argv[]) { '
                    '(void)argc; (void)argv; return 0; }\n')
            compiler_exe = spack.util.executable.Executable(first_compiler)
            output = str(compiler_exe(cls.verbose_flag(), fin, '-o', fout,
                                      output=str, error=str))  # str for py2

            return cls.parse_implicit_rpaths(output)
        except spack.util.executable.ProcessError as pe:
            tty.debug('ProcessError: Command exited with non-zero status: ' +
                      pe.long_message)
            return []
        finally:
            shutil.rmtree(tmpdir, ignore_errors=True)

    # This property should be overridden in the compiler subclass if
    # OpenMP is supported by that compiler
    @property
    def openmp_flag(self):
        # If it is not overridden, assume it is not supported and warn the user
        raise UnsupportedCompilerFlag(self, "OpenMP", "openmp_flag")

    # This property should be overridden in the compiler subclass if
    # C++98 is not the default standard for that compiler
    @property
    def cxx98_flag(self):
        return ""

    # This property should be overridden in the compiler subclass if
    # C++11 is supported by that compiler
    @property
    def cxx11_flag(self):
        # If it is not overridden, assume it is not supported and warn the user
        raise UnsupportedCompilerFlag(self,
                                      "the C++11 standard",
                                      "cxx11_flag")

    # This property should be overridden in the compiler subclass if
    # C++14 is supported by that compiler
    @property
    def cxx14_flag(self):
        # If it is not overridden, assume it is not supported and warn the user
        raise UnsupportedCompilerFlag(self,
                                      "the C++14 standard",
                                      "cxx14_flag")

    # This property should be overridden in the compiler subclass if
    # C++17 is supported by that compiler
    @property
    def cxx17_flag(self):
        # If it is not overridden, assume it is not supported and warn the user
        raise UnsupportedCompilerFlag(self,
                                      "the C++17 standard",
                                      "cxx17_flag")

    # This property should be overridden in the compiler subclass if
    # C99 is supported by that compiler
    @property
    def c99_flag(self):
        # If it is not overridden, assume it is not supported and warn the user
        raise UnsupportedCompilerFlag(self,
                                      "the C99 standard",
                                      "c99_flag")

    # This property should be overridden in the compiler subclass if
    # C11 is supported by that compiler
    @property
    def c11_flag(self):
        # If it is not overridden, assume it is not supported and warn the user
        raise UnsupportedCompilerFlag(self,
                                      "the C11 standard",
                                      "c11_flag")

    #
    # Compiler classes have methods for querying the version of
    # specific compiler executables.  This is used when discovering compilers.
    #
    # Compiler *instances* are just data objects, and can only be
    # constructed from an actual set of executables.
    #
    @classmethod
    def default_version(cls, cc):
        """Override just this to override all compiler version functions."""
        output = get_compiler_version_output(cc, cls.version_argument)
        return cls.extract_version_from_output(output)

    @classmethod
    @llnl.util.lang.memoized
    def extract_version_from_output(cls, output):
        """Extracts the version from compiler's output."""
        match = re.search(cls.version_regex, output)
        return match.group(1) if match else 'unknown'

    @classmethod
    def cc_version(cls, cc):
        return cls.default_version(cc)

    @classmethod
    def cxx_version(cls, cxx):
        return cls.default_version(cxx)

    @classmethod
    def f77_version(cls, f77):
        return cls.default_version(f77)

    @classmethod
    def fc_version(cls, fc):
        return cls.default_version(fc)

    @classmethod
    def search_regexps(cls, language):
        # Compile all the regular expressions used for files beforehand.
        # This searches for any combination of <prefix><name><suffix>
        # defined for the compiler
        compiler_names = getattr(cls, '{0}_names'.format(language))
        prefixes = [''] + cls.prefixes
        suffixes = [''] + cls.suffixes
        regexp_fmt = r'^({0}){1}({2})$'
        return [
            re.compile(regexp_fmt.format(prefix, re.escape(name), suffix))
            for prefix, name, suffix in
            itertools.product(prefixes, compiler_names, suffixes)
        ]

    def setup_custom_environment(self, pkg, env):
        """Set any environment variables necessary to use the compiler."""
        pass

    def __repr__(self):
        """Return a string representation of the compiler toolchain."""
        return self.__str__()

    def __str__(self):
        """Return a string representation of the compiler toolchain."""
        return "%s(%s)" % (
            self.name, '\n     '.join((str(s) for s in (
                self.cc, self.cxx, self.f77, self.fc, self.modules,
                str(self.operating_system)))))

class CompilerAccessError(spack.error.SpackError):

    def __init__(self, path):
        super(CompilerAccessError, self).__init__(
            "'%s' is not a valid compiler." % path)

class InvalidCompilerError(spack.error.SpackError):

    def __init__(self):
        super(InvalidCompilerError, self).__init__(
            "Compiler has no executables.")

class UnsupportedCompilerFlag(spack.error.SpackError):

    def __init__(self, compiler, feature, flag_name, ver_string=None):
        super(UnsupportedCompilerFlag, self).__init__(
            "{0} ({1}) does not support {2} (as compiler.{3})."
            .format(compiler.name,
                    ver_string if ver_string else compiler.version,
                    feature,
                    flag_name),
            "If you think it should, please edit the compiler.{0} subclass to"
            .format(compiler.name) +
            " implement the {0} property and submit a pull request or issue."
            .format(flag_name)
        )
<|endoftext|>


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

from datetime import datetime

import mongoengine
import requests

import json

SPOTIFY_API = 'https://api.spotify.com/v1'

class Track(mongoengine.Document):
    id = mongoengine.StringField(primary_key=True)
    name = mongoengine.StringField(required=True)
    artist = mongoengine.StringField(required=True)
    album = mongoengine.StringField(required=True)
    uri = mongoengine.StringField(required=True)
    preview_url = mongoengine.StringField(required=True)
    image = mongoengine.StringField(required=True)

    @staticmethod
    def get_from_spotify(query):
        request_url = '{}/search'.format(SPOTIFY_API)
        response = requests.get(request_url, params={'q': query, 'type': 'track'}).json()

        items = response['tracks']['items']
        if not items:
            return None
        raw_track_data = items[0]

        track_data = dict()
        for attr in ['id', 'name', 'uri', 'preview_url']:
            track_data[attr] = raw_track_data[attr]
        track_data['artist'] = raw_track_data['artists'][0]['name']
        track_data['album'] = raw_track_data['album']['name']
        track_data['image'] = raw_track_data['album']['images'][0]['url']

        return Track(**track_data)

class Photo(mongoengine.Document):
    file = mongoengine.FileField(required=True)

class Submission(mongoengine.Document):
    date = mongoengine.DateTimeField(default=datetime.now)
    photo = mongoengine.ReferenceField(Photo)
    track = mongoengine.ReferenceField(Track)

if __name__ == '__main__':
    db = mongoengine.connect('test_db')
    track = Track.get_from_spotify('maskinen krossa alla fönster')
    track.save()
    print track.__dict__<commit_msg>Updated model, uses echonest<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

from datetime import datetime

import mongoengine
from pyechonest import config as echonest_config
from pyechonest import song as echonest_song
from pyechonest import artist as echonest_artist
import requests

import config

echonest_config.ECHO_NEST_API_KEY = config.echo_nest_api_key
SPOTIFY_API = 'https://api.spotify.com/v1'

class Track(mongoengine.Document):
    id = mongoengine.StringField(primary_key=True)
    name = mongoengine.StringField(required=True)
    artist_id = mongoengine.StringField(required=True)
    artist_name = mongoengine.StringField(required=True)
    album = mongoengine.StringField(required=True)
    uri = mongoengine.StringField(required=True)
    preview_url = mongoengine.StringField(required=True)
    image = mongoengine.StringField(required=True)
    genres = mongoengine.ListField(mongoengine.StringField())
    audio_summary = mongoengine.DictField()

    @staticmethod
    def get_from_spotify(artist, title):
        # Getting data from spotify
        request_url = '{}/search'.format(SPOTIFY_API)
        query = '{} {}'.format(artist, title)
        response = requests.get(request_url, params={'q': query, 'type': 'track'}).json()

        items = response['tracks']['items']
        if not items:
            print "Couldn't find '{} - {}' on Spotify".format(artist, title)
            return None
        raw_track_data = items[0]

        track_data = dict()
        for attr in ['id', 'name', 'uri', 'preview_url']:
            track_data[attr] = raw_track_data[attr]
        track_data['artist_name'] = raw_track_data['artists'][0]['name']
        track_data['artist_id'] = raw_track_data['artists'][0]['id']
        track_data['album'] = raw_track_data['album']['name']
        track_data['image'] = raw_track_data['album']['images'][0]['url']

        # EchoNest enrichement
        songs = echonest_song.search(artist=artist, title=title)
        if not songs:
            print "Couldn't find '{} - {}' on EchoNest".format(artist, title)
            return None
        song = songs[0]
        track_data['audio_summary'] = song.audio_summary
        artist = echonest_artist.search(name=song.artist_name)[0]
        track_data['genres'] = [t['name'] for t in artist.terms]

        return Track(**track_data)

class Photo(mongoengine.Document):
    file = mongoengine.FileField(required=True)

class Submission(mongoengine.Document):
    date = mongoengine.DateTimeField(default=datetime.now)
    photo = mongoengine.ReferenceField(Photo)
    track = mongoengine.ReferenceField(Track)

if __name__ == '__main__':
    db = mongoengine.connect('test_db')
    track = Track.get_from_spotify('maskinen', 'krossa alla fönster')
    track.save()
    print track.__dict__<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
import datetime
import time
from flask import url_for
from flaskext.mail.message import Message
from mongoengine import fields, Document
from mongoengine.queryset import QuerySet

def get_week_number(when=None):
    if not when:
        when = datetime.date.today()
    return when.isocalendar()[1]

def get_year_number(when=None):
    if not when:
        when = datetime.date.today()
    return when.isocalendar()[0]

def get_day_number(when=None):
    if not when:
        when = datetime.date.today()
    return when.isocalendar()[2]

class UserQuerySet(QuerySet):
    def total_hugs(self):
        return self.sum('hugs_received')

    def average_hugs_given(self):
        return self.filter(hugs_given__gt=0).average('hugs_given')

    def average_hugs_received(self):
        return self.filter(hugs_received__gt=0).average('hugs_received')

class User(Document):
    name = fields.StringField(unique=True, unique_with='network')
    network = fields.StringField(default='github')
    access_token = fields.StringField(required=False)
    is_admin = fields.BooleanField(default=False)
    hugs_received = fields.IntField(default=0)
    hugs_given = fields.IntField(default=0)
    avatar_url = fields.StringField(required=False)
    notifications = fields.BooleanField(default=False)
    email = fields.EmailField(required=False)

    meta = {'queryset_class': UserQuerySet}

    def __unicode__(self):
        return self.name

    @property
    def url(self):
        return url_for('user', username=self.name, network=self.network)

    @property
    def network_url(self):
        return getattr(self, '%s_url' % self.network)

    @property
    def github_url(self):
        return 'https://github.com/%s' % self.name

    def can_hug(self):
        from app import app
        return app.debug or self.get_today_hugged() is None

    def hug(self, receiver):
        hug = Hug.objects.create(hugger=self, hugged=receiver)
        self.hugs_given += 1
        self.save()
        receiver.hugs_received += 1
        receiver.save()
        return hug

    def get_today_hugged(self):
        try:
            return Hug.objects.get(hugger=self, week=get_week_number(), year=get_year_number(), day=get_day_number())
        except Hug.DoesNotExist:
            return None

    def get_this_week_hugged(self):
        try:
            return Hug.objects.get(hugger=self, week=get_week_number(), year=get_year_number())
        except Hug.DoesNotExist:
            return None

    def get_this_week_hugged_by(self):
        return Hug.objects.filter(hugged=self, week=get_week_number(), year=get_year_number())

    def get_unsubscribe_token(self):
        from app import signer
        return signer.dumps({'name': self.name, 'network': self.network, 'action': 'unsubscribe'})

    def to_dict(self, follow=False):
        data = {
            'name': self.name,
            'network': self.network,
            'hugs_received': self.hugs_received,
            'hugs_given': self.hugs_given,
            'avatar_url': self.avatar_url,
            'url': self.url,
        }
        if follow:
            data['hugs'] = [hug.to_dict(False) for hug in Hug.objects.filter(hugger=self).select_related()]
        return data

class HugQuerySet(QuerySet):
    def hugs_this_week(self):
        return self.filter(week=get_week_number(), year=get_year_number()).count()

    def hugs_last_week(self):
        last_week = datetime.date.today() - datetime.timedelta(days=7)
        return self.filter(week=get_week_number(last_week), year=get_year_number(last_week)).count()

    def get_recent(self, num):
        return self.order_by('created').limit(num)

class Hug(Document):
    hugger = fields.ReferenceField(User, unique_with=['year', 'week', 'day'])
    hugged = fields.ReferenceField(User)
    created = fields.DateTimeField(default=datetime.datetime.now)
    week = fields.IntField(default=get_week_number)
    year = fields.IntField(default=get_year_number)
    day = fields.IntField(default=get_day_number)

    meta = {'queryset_class': HugQuerySet}

    def __unicode__(self):
        return u'%s -> %s' % (self.hugger, self.hugged)

    def notify_receiver(self):
        """
        Notify the receiver
        """
        from app import mail
        body = """Hi %(hugged)s,

        You've just been hugged by %(hugger)s on https://www.githugs.org.

        Your GitHugs team.

        PS: If you don't want these notifications, click %(unsubscribe_url)s""" % {
            'hugged': self.hugged,
            'hugger': self.hugger,
            'unsubscribe_url': 'https://www.githugs.org%s' % url_for('unsubscribe', token=self.hugged.get_unsubscribe_token())
        }
        message = Message(
            subject="You have been hugged",
            sender="hugs@githugs.org",
            recipients=[self.hugged.email],
            body=body,
        )
        mail.send(message)

    def to_dict(self, follow=False):
        data = {
            'created': time.mktime(self.created.timetuple()),
            'week': self.week,
            'year': self.year,
        }
        if follow:
            data['hugger'] = self.hugger.to_dict()
            data['hugged'] = self.hugged.to_dict()
        else:
            data['hugger'] = self.hugger.name
            data['hugged'] = self.hugged.name
        return data
<commit_msg>that didn't work anyway<commit_after># -*- coding: utf-8 -*-
import datetime
import time
from flask import url_for
from flaskext.mail.message import Message
from mongoengine import fields, Document
from mongoengine.queryset import QuerySet

def get_week_number(when=None):
    if not when:
        when = datetime.date.today()
    return when.isocalendar()[1]

def get_year_number(when=None):
    if not when:
        when = datetime.date.today()
    return when.isocalendar()[0]

def get_day_number(when=None):
    if not when:
        when = datetime.date.today()
    return when.isocalendar()[2]

class UserQuerySet(QuerySet):
    def total_hugs(self):
        return self.sum('hugs_received')

    def average_hugs_given(self):
        return self.filter(hugs_given__gt=0).average('hugs_given')

    def average_hugs_received(self):
        return self.filter(hugs_received__gt=0).average('hugs_received')

class User(Document):
    name = fields.StringField(unique=True, unique_with='network')
    network = fields.StringField(default='github')
    access_token = fields.StringField(required=False)
    is_admin = fields.BooleanField(default=False)
    hugs_received = fields.IntField(default=0)
    hugs_given = fields.IntField(default=0)
    avatar_url = fields.StringField(required=False)
    notifications = fields.BooleanField(default=False)
    email = fields.EmailField(required=False)

    meta = {'queryset_class': UserQuerySet}

    def __unicode__(self):
        return self.name

    @property
    def url(self):
        return url_for('user', username=self.name, network=self.network)

    @property
    def network_url(self):
        return getattr(self, '%s_url' % self.network)

    @property
    def github_url(self):
        return 'https://github.com/%s' % self.name

    def can_hug(self):
        return self.get_today_hugged() is None

    def hug(self, receiver):
        hug = Hug.objects.create(hugger=self, hugged=receiver)
        self.hugs_given += 1
        self.save()
        receiver.hugs_received += 1
        receiver.save()
        return hug

    def get_today_hugged(self):
        try:
            return Hug.objects.get(hugger=self, week=get_week_number(), year=get_year_number(), day=get_day_number())
        except Hug.DoesNotExist:
            return None

    def get_this_week_hugged(self):
        try:
            return Hug.objects.get(hugger=self, week=get_week_number(), year=get_year_number())
        except Hug.DoesNotExist:
            return None

    def get_this_week_hugged_by(self):
        return Hug.objects.filter(hugged=self, week=get_week_number(), year=get_year_number())

    def get_unsubscribe_token(self):
        from app import signer
        return signer.dumps({'name': self.name, 'network': self.network, 'action': 'unsubscribe'})

    def to_dict(self, follow=False):
        data = {
            'name': self.name,
            'network': self.network,
            'hugs_received': self.hugs_received,
            'hugs_given': self.hugs_given,
            'avatar_url': self.avatar_url,
            'url': self.url,
        }
        if follow:
            data['hugs'] = [hug.to_dict(False) for hug in Hug.objects.filter(hugger=self).select_related()]
        return data

class HugQuerySet(QuerySet):
    def hugs_this_week(self):
        return self.filter(week=get_week_number(), year=get_year_number()).count()

    def hugs_last_week(self):
        last_week = datetime.date.today() - datetime.timedelta(days=7)
        return self.filter(week=get_week_number(last_week), year=get_year_number(last_week)).count()

    def get_recent(self, num):
        return self.order_by('created').limit(num)

class Hug(Document):
    hugger = fields.ReferenceField(User, unique_with=['year', 'week', 'day'])
    hugged = fields.ReferenceField(User)
    created = fields.DateTimeField(default=datetime.datetime.now)
    week = fields.IntField(default=get_week_number)
    year = fields.IntField(default=get_year_number)
    day = fields.IntField(default=get_day_number)

    meta = {'queryset_class': HugQuerySet}

    def __unicode__(self):
        return u'%s -> %s' % (self.hugger, self.hugged)

    def notify_receiver(self):
        """
        Notify the receiver
        """
        from app import mail
        body = """Hi %(hugged)s,

        You've just been hugged by %(hugger)s on https://www.githugs.org.

        Your GitHugs team.

        PS: If you don't want these notifications, click %(unsubscribe_url)s""" % {
            'hugged': self.hugged,
            'hugger': self.hugger,
            'unsubscribe_url': 'https://www.githugs.org%s' % url_for('unsubscribe', token=self.hugged.get_unsubscribe_token())
        }
        message = Message(
            subject="You have been hugged",
            sender="hugs@githugs.org",
            recipients=[self.hugged.email],
            body=body,
        )
        mail.send(message)

    def to_dict(self, follow=False):
        data = {
            'created': time.mktime(self.created.timetuple()),
            'week': self.week,
            'year': self.year,
        }
        if follow:
            data['hugger'] = self.hugger.to_dict()
            data['hugged'] = self.hugged.to_dict()
        else:
            data['hugger'] = self.hugger.name
            data['hugged'] = self.hugged.name
        return data
<|endoftext|>


<commit_before>"""
Class: models.py
----------------
Contains the different epidemic models.
"""

from collections import Counter
import random

def init_conflict(team_nodes, node_team):
  """
  Function: init_conflict
  -----------------------
  Initializes nodes for the teams. If two teams choose the same node then no
  team gets that node.

  team_nodes: A mapping of a team name to the nodes they chose.
  node_team: Mapping of nodes to their team.
  returns: An initial diff.
  """
  diff = {}

  for (team, nodes) in team_nodes.items():
    for node in nodes:
      # More than one team has chosen a node. They cancel out.
      if node_team[node] is not None:
        node_team[node] = "__CONFLICT__"
        diff[node] = "__CONFLICT__"
      else:
        node_team[node] = team
        diff[node] = team
  # Now set all the conflicts back to None since no team gets those nodes.
  for (node, team) in node_team.items():
    if team == "__CONFLICT__":
      node_team[node] = None

  return diff

def next_majority_all(adj_list, node_team, node):
  """
  Function: next_majority_all
  ---------------------------
  Computes the next color for a node. The node takes on the color the
  majority of its neighbors have (including uncolored nodes).

  adj_list: The adjacency list.
  node_team: Mapping of nodes to their team.
  node: The node to compute the next color for.
  returns: A tuple containing a boolean of whether or not the node's color
           changed, and the node's current/new color.
  """
  # Get the neighbors and find the team that covers the most neighbors.
  neighbors = adj_list[node]
  team_count = Counter([node_team[x] for x in neighbors])
  most_common = team_count.most_common(1)[0]

  # Convert if there is a majority team.
  if most_common[0] is not None and most_common[1] >= len(neighbors) / 2.0:
    return (True, most_common[0])

  return (False, node_team[node])

def next_majority_colored(adj_list, node_team, node):
  """
  Function: next_majority_colored
  -------------------------------
  Computes the next color for a node. The node takes on the color that
  the majority of its colored neighbors have.

  adj_list: The adjacency list.
  node_team: Mapping of nodes to their team.
  node: The node to compute the next color for.
  returns: A tuple containing a boolean of whether or not the node's color
           changed, and the node's current/new color.
  """
  # Get the neighbors and find the color that covers most neighbors.
  neighbors = adj_list[node]
  colored_neighbors = filter(None, [node_team[x] for x in neighbors])
  team_count = Counter(colored_neighbors)

  most_common = team_count.most_common(1)
  if len(most_common) > 0 and most_common[0][1] >= len(colored_neighbors) / 2.0:
    return (True, most_common[0][0])

  return (False, node_team[node])

def next_random_weighing(adj_list, node_team, node):
  """
  Function: next_random_weighing
  ------------------------------
  Computes the next color for a node. The node randomly takes on a color of one
  of its neighbors, where the probability of this occuring is proportional to
  the number of neighbors with the same color.

  adj_list: The adjacency list.
  node_team: Mapping of nodes to their team.
  node: The node to compute the next color for.
  returns: A tuple containing a boolean of whether or not te node's color
           changed, and the node's current/new color.
  """
  # Get the neighbors and the colors of those neighbors.
  neighbors = adj_list[node]
  colored_neighbors = filter(None, [node_team[x] for x in neighbors])
  team_count = Counter(colored_neighbors)

  if len(team_count) > 0:
    probs = reduce(lambda x, y: x + y, [[x[0]] * int(x[1]) for x in team_count.items()])
    return (True, random.choice(probs))

  return (False, node_team[node])
<commit_msg>Added random seed to model.<commit_after>"""
Class: models.py
----------------
Contains the different epidemic models.
"""

from collections import Counter
import random

SEED = 121121121

def init_conflict(team_nodes, node_team):
  """
  Function: init_conflict
  -----------------------
  Initializes nodes for the teams. If two teams choose the same node then no
  team gets that node.

  team_nodes: A mapping of a team name to the nodes they chose.
  node_team: Mapping of nodes to their team.
  returns: An initial diff.
  """
  diff = {}

  for (team, nodes) in team_nodes.items():
    for node in nodes:
      # More than one team has chosen a node. They cancel out.
      if node_team[node] is not None:
        node_team[node] = "__CONFLICT__"
        diff[node] = "__CONFLICT__"
      else:
        node_team[node] = team
        diff[node] = team
  # Now set all the conflicts back to None since no team gets those nodes.
  for (node, team) in node_team.items():
    if team == "__CONFLICT__":
      node_team[node] = None

  return diff

def next_majority_all(adj_list, node_team, node):
  """
  Function: next_majority_all
  ---------------------------
  Computes the next color for a node. The node takes on the color the
  majority of its neighbors have (including uncolored nodes).

  adj_list: The adjacency list.
  node_team: Mapping of nodes to their team.
  node: The node to compute the next color for.
  returns: A tuple containing a boolean of whether or not the node's color
           changed, and the node's current/new color.
  """
  # Get the neighbors and find the team that covers the most neighbors.
  neighbors = adj_list[node]
  team_count = Counter([node_team[x] for x in neighbors])
  most_common = team_count.most_common(1)[0]

  # Convert if there is a majority team.
  if most_common[0] is not None and most_common[1] >= len(neighbors) / 2.0:
    return (True, most_common[0])

  return (False, node_team[node])

def next_majority_colored(adj_list, node_team, node):
  """
  Function: next_majority_colored
  -------------------------------
  Computes the next color for a node. The node takes on the color that
  the majority of its colored neighbors have.

  adj_list: The adjacency list.
  node_team: Mapping of nodes to their team.
  node: The node to compute the next color for.
  returns: A tuple containing a boolean of whether or not the node's color
           changed, and the node's current/new color.
  """
  # Get the neighbors and find the color that covers most neighbors.
  neighbors = adj_list[node]
  colored_neighbors = filter(None, [node_team[x] for x in neighbors])
  team_count = Counter(colored_neighbors)

  most_common = team_count.most_common(1)
  if len(most_common) > 0 and most_common[0][1] >= len(colored_neighbors) / 2.0:
    return (True, most_common[0][0])

  return (False, node_team[node])

def next_random_weighing(adj_list, node_team, node):
  """
  Function: next_random_weighing
  ------------------------------
  Computes the next color for a node. The node randomly takes on a color of one
  of its neighbors, where the probability of this occuring is proportional to
  the number of neighbors with the same color.

  adj_list: The adjacency list.
  node_team: Mapping of nodes to their team.
  node: The node to compute the next color for.
  returns: A tuple containing a boolean of whether or not te node's color
           changed, and the node's current/new color.
  """
  random.seed(SEED)

  # Get the neighbors and the colors of those neighbors.
  neighbors = adj_list[node]
  colored_neighbors = filter(None, [node_team[x] for x in neighbors])
  team_count = Counter(colored_neighbors)

  if len(team_count) > 0:
    probs = reduce(lambda x, y: x + y, [[x[0]] * int(x[1]) for x in team_count.items()])
    return (True, random.choice(probs))

  return (False, node_team[node])
<|endoftext|>


<commit_before>"""
Models for code snippets and related data.

Most of these models also have custom managers defined which add
convenient shortcuts for repetitive or common bits of logic; see
``managers.py`` in this directory.

"""

import datetime, re
from django.db import connection, models
from django.template.defaultfilters import slugify
from django.contrib.auth.models import User
import managers
from markdown import markdown
from pygments import highlight, lexers, formatters

RATING_CHOICES = (
    (-1, 'Not useful'),
    (1, 'Useful')
    )

class Language(models.Model):
    """
    A language in which a Snippet can be written.

    The ``language_code`` field should be set to an alias of a
    Pygments lexer which is capable of processing this language.

    The ``file_extension`` and ``mime_type`` fields will be used when
    users download Snippets, to set the filename and HTTP Content-Type
    of the download appropriately.

    """
    name = models.CharField(maxlength=50)
    slug = models.SlugField(editable=False)
    language_code = models.CharField(maxlength=50,
                                     help_text="This should be an alias of a Pygments lexer which can handle this language.")
    file_extension = models.CharField(maxlength=10,
                                      help_text="The file extension to use when downloading Snippets in this Language; leave out the dot.")
    mime_type = models.CharField(maxlength=100,
                                 help_text="The HTTP Content-Type to use when downloading Snippets in this Language.")

    class Meta:
        ordering = ('name',)

    class Admin:
        fields = (
            ('Language information', {
            'fields': ('name', 'language_code')}),
            ('File type information', {
            'fields': ('file_extension', 'mime_type')}),
            )

    def save(self):
        if not self.id:
            self.slug = slugify(self.name)
        super(Language, self).save()

    def get_absolute_url(self):
        return ('cab.views.snippets.snippets_by_language', (), { 'slug': self.slug })
    get_absolute_url = models.permalink(get_absolute_url)

    def __str__(self):
        return self.name

    def get_lexer(self):
        """
        Returns an instance of the Pygments lexer for this language.

        """
        return lexers.get_lexer_by_name(self.language_code)

class Tag(models.Model):
    """
    A descriptive tag to be applied to a Snippet.

    """
    name = models.CharField(maxlength=50, unique=True)
    slug = models.SlugField(editable=False)

    class Meta:
        ordering = ('name',)

    class Admin:
        pass

    def save(self):
        if not self.id:
            self.slug = slugify(self.name)
        super(Tag, self).save()

    def get_absolute_url(self):
        return ('cab.views.snippets.snippets_by_tag', () { 'slug': self.slug })
    get_absolute_url = models.permalink(get_absolute_url)

    def __str__(self):
        return self.name

class Snippet(models.Model):
    """
    A snippet of code in some Language.

    This is slightly denormalized in two ways:

      1. Because it's wasteful to run Pygments over the code each time
         the Snippet is viewed, it is instead run on save, and two
         copies of the code -- one the original input, the other
         highlighted by Pygments -- are stored.

      2. For much the same reason, Markdown is run over the Snippet's
         description on save, instead of on each view, and the result
         is stored in a separate column.

    Also, Tags are added through the ``tag_list`` field which, after
    the Snippet has been saved, will be iterated over to set up the
    relationships to actual Tag objects.

    """

    title = models.CharField(maxlength=250)
    language = models.ForeignKey(Language)
    description = models.TextField(help_text="Accepts Markdown syntax.")
    description_html = models.TextField(editable=False)
    code = models.TextField()
    highlighted_code = models.TextField(editable=False)

    pub_date = models.DateTimeField(editable=False)
    updated_date = models.DateTimeField(editable=False)

    author = models.ForeignKey(User)
    tag_list = models.CharField(maxlength=250,
                                help_text="Separate tags with spaces. Maximum 250 characters.")
    tags = models.ManyToManyField(Tag, editable=False)
    original = models.ForeignKey('self', null=True, blank=True,
                                 help_text="Optional. Fill this in if this Snippet is based on another.")

    objects = managers.SnippetsManager()

    class Meta:
        ordering = ('-pub_date',)

    class Admin:
        fields = (
            ('Metadata', {
            'fields': ('title', 'language', 'author', 'tag_list', 'original')}),
            ('None', {
             'fields': ('description', 'code')}),
            )

    def save(self):
        if not self.id:
            self.pub_date = datetime.datetime.now()
        self.updated_date = datetime.datetime.now()
        # Use safe_mode in Markdown to prevent arbitrary tags.
        self.description_html = markdown(self.description, safe_mode=True)
        self.highlighted_code = self.highlight()
        self.tag_list = self.tag_list.lower() # Normalize to lower-case
        super(Snippet, self).save()

        # Now that the Snippet is saved, deal with the tags.
        current_tags = list(self.tags.all()) # We only want to query this once.

        # Splitting to get the new tag list is tricky, because people
        # will stick commas and other whitespace in the darndest places.
        new_tag_list = [t for t in re.split('[\s,]+', self.tag_list) if t]

        # First, clear out tags that aren't on the Snippet anymore.
        for tag in current_tags:
            if tag.name not in new_tag_list:
                self.tags.remove(tag)

        # Then add any new tags.
        for tag_name in new_tag_list:
            if tag_name not in [tag.name for tag in current_tags]:
                tag, created = Tag.objects.get_or_create(name=tag_name)
                self.tags.add(tag)

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return ('cab.views.snippets.snippet_detail', (), { 'snippet_id': str(self.id) })
    get_absolute_url = models.permalink(get_absolute_url)

    def highlight(self):
        """
        Returns this Snippet's originally-input code, highlighted via
        Pygments.

        """
        return highlight(self.code,
                         self.language.get_lexer(),
                         formatters.HtmlFormatter(linenos=True))

class Rating(models.Model):
    """
    A particular User's rating of a particular Snippet.

    """
    snippet = models.ForeignKey(Snippet)
    user = models.ForeignKey(User)
    date = models.DateTimeField(editable=False)
    score = models.IntegerField(choices=RATING_CHOICES)

    objects = managers.RatingsManager()

    class Admin:
        pass

    def save(self):
        if not self.id:
            self.date = datetime.datetime.now()
        super(Rating, self).save()

    def __str__(self):
        return "%s rating '%s'" % (self.user.username, self.snippet.title)

class Bookmark(models.Model):
    """
    A Snippet bookmarked by a User.

    """
    snippet = models.ForeignKey(Snippet)
    user = models.ForeignKey(User)
    date = models.DateTimeField(editable=False)

    objects = managers.BookmarksManager()

    class Meta:
        ordering = ('date',)

    class Admin:
        pass

    def save(self):
        if not self.id:
            self.date = datetime.datetime.now()
        super(Bookmark, self).save()

    def __str__(self):
        return "%s bookmarked by %s" % (self.snippet.title, self.user.username)
<commit_msg>Typo<commit_after>"""
Models for code snippets and related data.

Most of these models also have custom managers defined which add
convenient shortcuts for repetitive or common bits of logic; see
``managers.py`` in this directory.

"""

import datetime, re
from django.db import connection, models
from django.template.defaultfilters import slugify
from django.contrib.auth.models import User
import managers
from markdown import markdown
from pygments import highlight, lexers, formatters

RATING_CHOICES = (
    (-1, 'Not useful'),
    (1, 'Useful')
    )

class Language(models.Model):
    """
    A language in which a Snippet can be written.

    The ``language_code`` field should be set to an alias of a
    Pygments lexer which is capable of processing this language.

    The ``file_extension`` and ``mime_type`` fields will be used when
    users download Snippets, to set the filename and HTTP Content-Type
    of the download appropriately.

    """
    name = models.CharField(maxlength=50)
    slug = models.SlugField(editable=False)
    language_code = models.CharField(maxlength=50,
                                     help_text="This should be an alias of a Pygments lexer which can handle this language.")
    file_extension = models.CharField(maxlength=10,
                                      help_text="The file extension to use when downloading Snippets in this Language; leave out the dot.")
    mime_type = models.CharField(maxlength=100,
                                 help_text="The HTTP Content-Type to use when downloading Snippets in this Language.")

    class Meta:
        ordering = ('name',)

    class Admin:
        fields = (
            ('Language information', {
            'fields': ('name', 'language_code')}),
            ('File type information', {
            'fields': ('file_extension', 'mime_type')}),
            )

    def save(self):
        if not self.id:
            self.slug = slugify(self.name)
        super(Language, self).save()

    def get_absolute_url(self):
        return ('cab.views.snippets.snippets_by_language', (), { 'slug': self.slug })
    get_absolute_url = models.permalink(get_absolute_url)

    def __str__(self):
        return self.name

    def get_lexer(self):
        """
        Returns an instance of the Pygments lexer for this language.

        """
        return lexers.get_lexer_by_name(self.language_code)

class Tag(models.Model):
    """
    A descriptive tag to be applied to a Snippet.

    """
    name = models.CharField(maxlength=50, unique=True)
    slug = models.SlugField(editable=False)

    class Meta:
        ordering = ('name',)

    class Admin:
        pass

    def save(self):
        if not self.id:
            self.slug = slugify(self.name)
        super(Tag, self).save()

    def get_absolute_url(self):
        return ('cab.views.snippets.snippets_by_tag', (), { 'slug': self.slug })
    get_absolute_url = models.permalink(get_absolute_url)

    def __str__(self):
        return self.name

class Snippet(models.Model):
    """
    A snippet of code in some Language.

    This is slightly denormalized in two ways:

      1. Because it's wasteful to run Pygments over the code each time
         the Snippet is viewed, it is instead run on save, and two
         copies of the code -- one the original input, the other
         highlighted by Pygments -- are stored.

      2. For much the same reason, Markdown is run over the Snippet's
         description on save, instead of on each view, and the result
         is stored in a separate column.

    Also, Tags are added through the ``tag_list`` field which, after
    the Snippet has been saved, will be iterated over to set up the
    relationships to actual Tag objects.

    """

    title = models.CharField(maxlength=250)
    language = models.ForeignKey(Language)
    description = models.TextField(help_text="Accepts Markdown syntax.")
    description_html = models.TextField(editable=False)
    code = models.TextField()
    highlighted_code = models.TextField(editable=False)

    pub_date = models.DateTimeField(editable=False)
    updated_date = models.DateTimeField(editable=False)

    author = models.ForeignKey(User)
    tag_list = models.CharField(maxlength=250,
                                help_text="Separate tags with spaces. Maximum 250 characters.")
    tags = models.ManyToManyField(Tag, editable=False)
    original = models.ForeignKey('self', null=True, blank=True,
                                 help_text="Optional. Fill this in if this Snippet is based on another.")

    objects = managers.SnippetsManager()

    class Meta:
        ordering = ('-pub_date',)

    class Admin:
        fields = (
            ('Metadata', {
            'fields': ('title', 'language', 'author', 'tag_list', 'original')}),
            ('None', {
             'fields': ('description', 'code')}),
            )

    def save(self):
        if not self.id:
            self.pub_date = datetime.datetime.now()
        self.updated_date = datetime.datetime.now()
        # Use safe_mode in Markdown to prevent arbitrary tags.
        self.description_html = markdown(self.description, safe_mode=True)
        self.highlighted_code = self.highlight()
        self.tag_list = self.tag_list.lower() # Normalize to lower-case
        super(Snippet, self).save()

        # Now that the Snippet is saved, deal with the tags.
        current_tags = list(self.tags.all()) # We only want to query this once.

        # Splitting to get the new tag list is tricky, because people
        # will stick commas and other whitespace in the darndest places.
        new_tag_list = [t for t in re.split('[\s,]+', self.tag_list) if t]

        # First, clear out tags that aren't on the Snippet anymore.
        for tag in current_tags:
            if tag.name not in new_tag_list:
                self.tags.remove(tag)

        # Then add any new tags.
        for tag_name in new_tag_list:
            if tag_name not in [tag.name for tag in current_tags]:
                tag, created = Tag.objects.get_or_create(name=tag_name)
                self.tags.add(tag)

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return ('cab.views.snippets.snippet_detail', (), { 'snippet_id': str(self.id) })
    get_absolute_url = models.permalink(get_absolute_url)

    def highlight(self):
        """
        Returns this Snippet's originally-input code, highlighted via
        Pygments.

        """
        return highlight(self.code,
                         self.language.get_lexer(),
                         formatters.HtmlFormatter(linenos=True))

class Rating(models.Model):
    """
    A particular User's rating of a particular Snippet.

    """
    snippet = models.ForeignKey(Snippet)
    user = models.ForeignKey(User)
    date = models.DateTimeField(editable=False)
    score = models.IntegerField(choices=RATING_CHOICES)

    objects = managers.RatingsManager()

    class Admin:
        pass

    def save(self):
        if not self.id:
            self.date = datetime.datetime.now()
        super(Rating, self).save()

    def __str__(self):
        return "%s rating '%s'" % (self.user.username, self.snippet.title)

class Bookmark(models.Model):
    """
    A Snippet bookmarked by a User.

    """
    snippet = models.ForeignKey(Snippet)
    user = models.ForeignKey(User)
    date = models.DateTimeField(editable=False)

    objects = managers.BookmarksManager()

    class Meta:
        ordering = ('date',)

    class Admin:
        pass

    def save(self):
        if not self.id:
            self.date = datetime.datetime.now()
        super(Bookmark, self).save()

    def __str__(self):
        return "%s bookmarked by %s" % (self.snippet.title, self.user.username)
<|endoftext|>


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

"""
$Id$

Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
See the file 'doc/COPYING' for copying permission
"""

from lib.core.common import dataToStdout
from lib.core.common import isTechniqueAvailable
from lib.core.common import readInput
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
from lib.core.enums import DBMS
from lib.core.enums import PAYLOAD
from lib.core.exception import sqlmapUnsupportedFeatureException
from lib.core.shell import autoCompletion
from lib.takeover.udf import UDF
from lib.takeover.web import Web
from lib.takeover.xp_cmdshell import xp_cmdshell

class Abstraction(Web, UDF, xp_cmdshell):
    """
    This class defines an abstraction layer for OS takeover functionalities
    to UDF / xp_cmdshell objects
    """

    def __init__(self):
        self.envInitialized = False
        self.alwaysRetrieveCmdOutput = False

        UDF.__init__(self)
        Web.__init__(self)
        xp_cmdshell.__init__(self)

    def execCmd(self, cmd, silent=False):
        if self.webBackdoorUrl and not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
            self.webBackdoorRunCmd(cmd)

        elif kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ):
            self.udfExecCmd(cmd, silent=silent)

        elif kb.dbms == DBMS.MSSQL:
            self.xpCmdshellExecCmd(cmd, silent=silent)

        else:
            errMsg = "Feature not yet implemented for the back-end DBMS"
            raise sqlmapUnsupportedFeatureException, errMsg

    def evalCmd(self, cmd, first=None, last=None):
        if self.webBackdoorUrl and not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
            return self.webBackdoorRunCmd(cmd)

        elif kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ):
            return self.udfEvalCmd(cmd, first, last)

        elif kb.dbms == DBMS.MSSQL:
            return self.xpCmdshellEvalCmd(cmd, first, last)

        else:
            errMsg = "Feature not yet implemented for the back-end DBMS"
            raise sqlmapUnsupportedFeatureException, errMsg

    def runCmd(self, cmd):
        getOutput = None

        if not self.alwaysRetrieveCmdOutput:
            message   = "do you want to retrieve the command standard "
            message  += "output? [Y/n/a] "
            getOutput = readInput(message, default="Y")

            if getOutput in ("a", "A"):
                self.alwaysRetrieveCmdOutput = True

        if not getOutput or getOutput in ("y", "Y") or self.alwaysRetrieveCmdOutput:
            output = self.evalCmd(cmd)

            if output:
                conf.dumper.string("command standard output", output)
            else:
                dataToStdout("No output\n")
        else:
            self.execCmd(cmd)

    def shell(self):
        if self.webBackdoorUrl and not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
            infoMsg  = "calling OS shell. To quit type "
            infoMsg += "'x' or 'q' and press ENTER"
            logger.info(infoMsg)

        else:
            if kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ):
                infoMsg  = "going to use injected sys_eval and sys_exec "
                infoMsg += "user-defined functions for operating system "
                infoMsg += "command execution"
                logger.info(infoMsg)

            elif kb.dbms == DBMS.MSSQL:
                infoMsg  = "going to use xp_cmdshell extended procedure for "
                infoMsg += "operating system command execution"
                logger.info(infoMsg)

            else:
                errMsg = "feature not yet implemented for the back-end DBMS"
                raise sqlmapUnsupportedFeatureException, errMsg

            infoMsg  = "calling %s OS shell. To quit type " % kb.os or "Windows"
            infoMsg += "'x' or 'q' and press ENTER"
            logger.info(infoMsg)

        autoCompletion(osShell=True)

        while True:
            command = None

            try:
                command = raw_input("os-shell> ")
            except KeyboardInterrupt:
                print
                errMsg = "user aborted"
                logger.error(errMsg)
            except EOFError:
                print
                errMsg = "exit"
                logger.error(errMsg)
                break

            if not command:
                continue

            if command.lower() in ( "x", "q", "exit", "quit" ):
                break

            self.runCmd(command)

    def initEnv(self, mandatory=True, detailed=False, web=False):
        if self.envInitialized:
            return

        if web:
            self.webInit()
        else:
            self.checkDbmsOs(detailed)

            if mandatory and not self.isDba():
                warnMsg  = "the functionality requested might not work because "
                warnMsg += "the session user is not a database administrator"
                logger.warn(warnMsg)

            if kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ):
                self.udfInjectSys()
            elif kb.dbms == DBMS.MSSQL:
                if mandatory:
                    self.xpCmdshellInit()
            else:
                errMsg = "feature not yet implemented for the back-end DBMS"
                raise sqlmapUnsupportedFeatureException(errMsg)

        self.envInitialized = True
<commit_msg>minor fix<commit_after>#!/usr/bin/env python

"""
$Id$

Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
See the file 'doc/COPYING' for copying permission
"""

from lib.core.common import dataToStdout
from lib.core.common import isTechniqueAvailable
from lib.core.common import readInput
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
from lib.core.enums import DBMS
from lib.core.enums import PAYLOAD
from lib.core.exception import sqlmapUnsupportedFeatureException
from lib.core.shell import autoCompletion
from lib.takeover.udf import UDF
from lib.takeover.web import Web
from lib.takeover.xp_cmdshell import xp_cmdshell

class Abstraction(Web, UDF, xp_cmdshell):
    """
    This class defines an abstraction layer for OS takeover functionalities
    to UDF / xp_cmdshell objects
    """

    def __init__(self):
        self.envInitialized = False
        self.alwaysRetrieveCmdOutput = False

        UDF.__init__(self)
        Web.__init__(self)
        xp_cmdshell.__init__(self)

    def execCmd(self, cmd, silent=False):
        if self.webBackdoorUrl and not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
            self.webBackdoorRunCmd(cmd)

        elif kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ):
            self.udfExecCmd(cmd, silent=silent)

        elif kb.dbms == DBMS.MSSQL:
            self.xpCmdshellExecCmd(cmd, silent=silent)

        else:
            errMsg = "Feature not yet implemented for the back-end DBMS"
            raise sqlmapUnsupportedFeatureException, errMsg

    def evalCmd(self, cmd, first=None, last=None):
        if self.webBackdoorUrl and not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
            return self.webBackdoorRunCmd(cmd)

        elif kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ):
            return self.udfEvalCmd(cmd, first, last)

        elif kb.dbms == DBMS.MSSQL:
            return self.xpCmdshellEvalCmd(cmd, first, last)

        else:
            errMsg = "Feature not yet implemented for the back-end DBMS"
            raise sqlmapUnsupportedFeatureException, errMsg

    def runCmd(self, cmd):
        getOutput = None

        if not self.alwaysRetrieveCmdOutput:
            message   = "do you want to retrieve the command standard "
            message  += "output? [Y/n/a] "
            getOutput = readInput(message, default="Y")

            if getOutput in ("a", "A"):
                self.alwaysRetrieveCmdOutput = True

        if not getOutput or getOutput in ("y", "Y") or self.alwaysRetrieveCmdOutput:
            output = self.evalCmd(cmd)

            if output:
                conf.dumper.string("command standard output", output)
            else:
                dataToStdout("No output\n")
        else:
            self.execCmd(cmd)

    def shell(self):
        if self.webBackdoorUrl and not isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED):
            infoMsg  = "calling OS shell. To quit type "
            infoMsg += "'x' or 'q' and press ENTER"
            logger.info(infoMsg)

        else:
            if kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ):
                infoMsg  = "going to use injected sys_eval and sys_exec "
                infoMsg += "user-defined functions for operating system "
                infoMsg += "command execution"
                logger.info(infoMsg)

            elif kb.dbms == DBMS.MSSQL:
                infoMsg  = "going to use xp_cmdshell extended procedure for "
                infoMsg += "operating system command execution"
                logger.info(infoMsg)

            else:
                errMsg = "feature not yet implemented for the back-end DBMS"
                raise sqlmapUnsupportedFeatureException, errMsg

            infoMsg  = "calling %s OS shell. To quit type " % (kb.os or "Windows")
            infoMsg += "'x' or 'q' and press ENTER"
            logger.info(infoMsg)

        autoCompletion(osShell=True)

        while True:
            command = None

            try:
                command = raw_input("os-shell> ")
            except KeyboardInterrupt:
                print
                errMsg = "user aborted"
                logger.error(errMsg)
            except EOFError:
                print
                errMsg = "exit"
                logger.error(errMsg)
                break

            if not command:
                continue

            if command.lower() in ( "x", "q", "exit", "quit" ):
                break

            self.runCmd(command)

    def initEnv(self, mandatory=True, detailed=False, web=False):
        if self.envInitialized:
            return

        if web:
            self.webInit()
        else:
            self.checkDbmsOs(detailed)

            if mandatory and not self.isDba():
                warnMsg  = "the functionality requested might not work because "
                warnMsg += "the session user is not a database administrator"
                logger.warn(warnMsg)

            if kb.dbms in ( DBMS.MYSQL, DBMS.PGSQL ):
                self.udfInjectSys()
            elif kb.dbms == DBMS.MSSQL:
                if mandatory:
                    self.xpCmdshellInit()
            else:
                errMsg = "feature not yet implemented for the back-end DBMS"
                raise sqlmapUnsupportedFeatureException(errMsg)

        self.envInitialized = True
<|endoftext|>