<commit_before>import collections
import operator
import re
import urllib.parse

import lxml.cssselect
import lxml.etree

from sacad.cover import CoverImageFormat, CoverSourceQuality, CoverSourceResult
from sacad.sources.base import CoverSource

class CoverLibCoverSourceResult(CoverSourceResult):

  def __init__(self, *args, **kwargs):
    super().__init__(*args, source_quality=CoverSourceQuality.NORMAL, **kwargs)

class CoverLibCoverSource(CoverSource):

  """ Cover source that scrapes the coverlib.com site. """

  BASE_URL = "http://coverlib.com/"

  def getSearchUrl(self, album, artist):
    """ See CoverSource.getSearchUrl. """
    url = "%ssearch/" % (__class__.BASE_URL)
    params = collections.OrderedDict()
    params["q"] = "%s %s" % (artist.lower(), album.lower())
    params["Sektion"] = "2"
    return __class__.assembleUrl(url, params)

  def updateHttpHeaders(self, headers):
    """ See CoverSource.updateHttpHeaders. """
    pass

  def parseResults(self, api_data):
    """ See CoverSource.parseResults. """
    results = []

    # parse page
    parser = lxml.etree.HTMLParser()
    html = lxml.etree.XML(api_data.decode("latin-1"), parser)
    album_selector = lxml.cssselect.CSSSelector("div.panel-body div.row")
    cover_selector = lxml.cssselect.CSSSelector("div.col-lg-3")
    info_selector = lxml.cssselect.CSSSelector("p.visible-lg-block.thumbdescr")
    link_selector = lxml.cssselect.CSSSelector("a.dallery-item")
    size_regex = re.compile("Size: ([0-9.]+) x ([0-9.]+)px")

    rank = 1
    for album in album_selector(html):
      try:
        cover = cover_selector(album)[0]  # first cover is front cover
      except IndexError:
        # no results
        break
      desc = info_selector(cover)[0]
      desc_txt = lxml.etree.tostring(desc, encoding="unicode", method="text")

      # get resolution
      re_match = size_regex.search(desc_txt)
      size = tuple(map(int,
                       map(operator.methodcaller("replace", ".", ""),
                           re_match.group(1, 2))))

      # get thumbnail url
      link = link_selector(cover)[0]
      thumbnail_url = link.find("img").get("src")
      if not urllib.parse.urlparse(thumbnail_url).netloc:
        # make relative url absolute
        thumbnail_url = urllib.parse.urljoin(__class__.BASE_URL, thumbnail_url)

      # deduce img url without downloading subpage
      cover_id = int(thumbnail_url.rsplit(".", 1)[0].rsplit("/", 1)[1])
      cover_name = link.get("href").rsplit(".", 1)[0].rsplit("/", 1)[1]
      img_url = "%sDownload/%u/%s-Front.JPG" % (__class__.BASE_URL, cover_id, cover_name)

      # assume format is always jpg
      format = CoverImageFormat.JPEG

      # add result
      results.append(CoverLibCoverSourceResult(img_url,
                                               size,
                                               format,
                                               thumbnail_url=thumbnail_url,
                                               source=self,
                                               rank=rank))
      rank += 1

    return results
<commit_msg>Remove obsolete CoverLib source file<commit_after><|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""
Support for Linux LVM2
"""
from __future__ import absolute_import, print_function, unicode_literals

# Import python libs
import logging
import os.path

# Import salt libs
import salt.utils.path
from salt.exceptions import CommandExecutionError
from salt.ext import six

# Set up logger
log = logging.getLogger(__name__)

# Define the module's virtual name
__virtualname__ = "lvm"

def __virtual__():
    """
    Only load the module if lvm is installed
    """
    if salt.utils.path.which("lvm"):
        return __virtualname__
    return (
        False,
        "The linux_lvm execution module cannot be loaded: the lvm binary is not in the path.",
    )

def version():
    """
    Return LVM version from lvm version

    CLI Example:

    .. code-block:: bash

        salt '*' lvm.version
    """
    cmd = "lvm version"
    out = __salt__["cmd.run"](cmd).splitlines()
    ret = out[0].split(": ")
    return ret[1].strip()

def fullversion():
    """
    Return all version info from lvm version

    CLI Example:

    .. code-block:: bash

        salt '*' lvm.fullversion
    """
    ret = {}
    cmd = "lvm version"
    out = __salt__["cmd.run"](cmd).splitlines()
    for line in out:
        comps = line.split(":")
        ret[comps[0].strip()] = comps[1].strip()
    return ret

def pvdisplay(pvname="", real=False, quiet=False):
    """
    Return information about the physical volume(s)

    pvname
        physical device name

    real
        dereference any symlinks and report the real device

        .. versionadded:: 2015.8.7

    quiet
        if the physical volume is not present, do not show any error

    CLI Examples:

    .. code-block:: bash

        salt '*' lvm.pvdisplay
        salt '*' lvm.pvdisplay /dev/md0
    """
    ret = {}
    cmd = ["pvdisplay", "-c"]
    if pvname:
        cmd.append(pvname)
    cmd_ret = __salt__["cmd.run_all"](cmd, python_shell=False, ignore_retcode=quiet)

    if cmd_ret["retcode"] != 0:
        return {}

    out = cmd_ret["stdout"].splitlines()
    for line in out:
        if "is a new physical volume" not in line:
            comps = line.strip().split(":")
            if real:
                device = os.path.realpath(comps[0])
            else:
                device = comps[0]
            ret[device] = {
                "Physical Volume Device": comps[0],
                "Volume Group Name": comps[1],
                "Physical Volume Size (kB)": comps[2],
                "Internal Physical Volume Number": comps[3],
                "Physical Volume Status": comps[4],
                "Physical Volume (not) Allocatable": comps[5],
                "Current Logical Volumes Here": comps[6],
                "Physical Extent Size (kB)": comps[7],
                "Total Physical Extents": comps[8],
                "Free Physical Extents": comps[9],
                "Allocated Physical Extents": comps[10],
            }
            if real:
                ret[device]["Real Physical Volume Device"] = device
    return ret

def vgdisplay(vgname="", quiet=False):
    """
    Return information about the volume group(s)

    vgname
        volume group name

    quiet
        if the volume group is not present, do not show any error

    CLI Examples:

    .. code-block:: bash

        salt '*' lvm.vgdisplay
        salt '*' lvm.vgdisplay nova-volumes
    """
    ret = {}
    cmd = ["vgdisplay", "-c"]
    if vgname:
        cmd.append(vgname)
    cmd_ret = __salt__["cmd.run_all"](cmd, python_shell=False, ignore_retcode=quiet)

    if cmd_ret["retcode"] != 0:
        return {}

    out = cmd_ret["stdout"].splitlines()
    for line in out:
        comps = line.strip().split(":")
        ret[comps[0]] = {
            "Volume Group Name": comps[0],
            "Volume Group Access": comps[1],
            "Volume Group Status": comps[2],
            "Internal Volume Group Number": comps[3],
            "Maximum Logical Volumes": comps[4],
            "Current Logical Volumes": comps[5],
            "Open Logical Volumes": comps[6],
            "Maximum Logical Volume Size": comps[7],
            "Maximum Physical Volumes": comps[8],
            "Current Physical Volumes": comps[9],
            "Actual Physical Volumes": comps[10],
            "Volume Group Size (kB)": comps[11],
            "Physical Extent Size (kB)": comps[12],
            "Total Physical Extents": comps[13],
            "Allocated Physical Extents": comps[14],
            "Free Physical Extents": comps[15],
            "UUID": comps[16],
        }
    return ret

def lvdisplay(lvname="", quiet=False):
    """
    Return information about the logical volume(s)

    lvname
        logical device name

    quiet
        if the logical volume is not present, do not show any error

    CLI Examples:

    .. code-block:: bash

        salt '*' lvm.lvdisplay
        salt '*' lvm.lvdisplay /dev/vg_myserver/root
    """
    ret = {}
    cmd = ["lvdisplay", "-c"]
    if lvname:
        cmd.append(lvname)
    cmd_ret = __salt__["cmd.run_all"](cmd, python_shell=False, ignore_retcode=quiet)

    if cmd_ret["retcode"] != 0:
        return {}

    out = cmd_ret["stdout"].splitlines()
    for line in out:
        comps = line.strip().split(":")
        ret[comps[0]] = {
            "Logical Volume Name": comps[0],
            "Volume Group Name": comps[1],
            "Logical Volume Access": comps[2],
            "Logical Volume Status": comps[3],
            "Internal Logical Volume Number": comps[4],
            "Open Logical Volumes": comps[5],
            "Logical Volume Size": comps[6],
            "Current Logical Extents Associated": comps[7],
            "Allocated Logical Extents": comps[8],
            "Allocation Policy": comps[9],
            "Read Ahead Sectors": comps[10],
            "Major Device Number": comps[11],
            "Minor Device Number": comps[12],
        }
    return ret

def pvcreate(devices, override=True, force=True, **kwargs):
    """
    Set a physical device to be used as an LVM physical volume

    override
        Skip devices, if they are already LVM physical volumes

    CLI Examples:

    .. code-block:: bash

        salt mymachine lvm.pvcreate /dev/sdb1,/dev/sdb2
        salt mymachine lvm.pvcreate /dev/sdb1 dataalignmentoffset=7s
    """
    if not devices:
        return "Error: at least one device is required"
    if isinstance(devices, six.string_types):
        devices = devices.split(",")

    cmd = ["pvcreate"]

    if force:
        cmd.append("--yes")
    else:
        cmd.append("-qq")

    for device in devices:
        if not os.path.exists(device):
            raise CommandExecutionError("{0} does not exist".format(device))
        if not pvdisplay(device, quiet=True):
            cmd.append(device)
        elif not override:
            raise CommandExecutionError(
                'Device "{0}" is already an LVM physical volume.'.format(device)
            )

    if not cmd[2:]:
        # All specified devices are already LVM volumes
        return True

    valid = (
        "metadatasize",
        "dataalignment",
        "dataalignmentoffset",
        "pvmetadatacopies",
        "metadatacopies",
        "metadataignore",
        "restorefile",
        "norestorefile",
        "labelsector",
        "setphysicalvolumesize",
    )
    no_parameter = ("force", "norestorefile")
    for var in kwargs:
        if kwargs[var] and var in valid:
            cmd.extend(["--{0}".format(var), kwargs[var]])
        elif kwargs[var] and var in no_parameter:
            cmd.append("--{0}".format(var))

    out = __salt__["cmd.run_all"](cmd, python_shell=False)
    if out.get("retcode"):
        raise CommandExecutionError(out.get("stderr"))

    # Verify pvcreate was successful
    for device in devices:
        if not pvdisplay(device):
            raise CommandExecutionError('Device "{0}" was not affected.'.format(device))

    return True

def pvremove(devices, override=True, force=True):
    """
    Remove a physical device being used as an LVM physical volume

    override
        Skip devices, if they are already not used as LVM physical volumes

    CLI Examples:

    .. code-block:: bash

        salt mymachine lvm.pvremove /dev/sdb1,/dev/sdb2
    """
    if isinstance(devices, six.string_types):
        devices = devices.split(",")

    cmd = ["pvremove"]

    if force:
        cmd.append("--yes")
    else:
        cmd.append("-qq")

    for device in devices:
        if pvdisplay(device):
            cmd.append(device)
        elif not override:
            raise CommandExecutionError("{0} is not a physical volume".format(device))

    if not cmd[2:]:
        # Nothing to do
        return True

    out = __salt__["cmd.run_all"](cmd, python_shell=False)
    if out.get("retcode"):
        raise CommandExecutionError(out.get("stderr"))

    # Verify pvremove was successful
    for device in devices:
        if pvdisplay(device, quiet=True):
            raise CommandExecutionError('Device "{0}" was not affected.'.format(device))

    return True

def vgcreate(vgname, devices, force=False, **kwargs):
    """
    Create an LVM volume group

    CLI Examples:

    .. code-block:: bash

        salt mymachine lvm.vgcreate my_vg /dev/sdb1,/dev/sdb2
        salt mymachine lvm.vgcreate my_vg /dev/sdb1 clustered=y
    """
    if not vgname or not devices:
        return "Error: vgname and device(s) are both required"
    if isinstance(devices, six.string_types):
        devices = devices.split(",")

    cmd = ["vgcreate", vgname]
    for device in devices:
        cmd.append(device)

    if force:
        cmd.append("--yes")
    else:
        cmd.append("-qq")

    valid = (
        "clustered",
        "maxlogicalvolumes",
        "maxphysicalvolumes",
        "vgmetadatacopies",
        "metadatacopies",
        "physicalextentsize",
    )
    for var in kwargs:
        if kwargs[var] and var in valid:
            cmd.append("--{0}".format(var))
            cmd.append(kwargs[var])
    out = __salt__["cmd.run"](cmd, python_shell=False).splitlines()
    vgdata = vgdisplay(vgname)
    vgdata["Output from vgcreate"] = out[0].strip()
    return vgdata

def vgextend(vgname, devices, force=False):
    """
    Add physical volumes to an LVM volume group

    CLI Examples:

    .. code-block:: bash

        salt mymachine lvm.vgextend my_vg /dev/sdb1,/dev/sdb2
        salt mymachine lvm.vgextend my_vg /dev/sdb1
    """
    if not vgname or not devices:
        return "Error: vgname and device(s) are both required"
    if isinstance(devices, six.string_types):
        devices = devices.split(",")

    cmd = ["vgextend", vgname]

    if force:
        cmd.append("--yes")
    else:
        cmd.append("-qq")

    for device in devices:
        cmd.append(device)
    out = __salt__["cmd.run"](cmd, python_shell=False).splitlines()
    vgdata = {"Output from vgextend": out[0].strip()}
    return vgdata

def lvcreate(
    lvname,
    vgname,
    size=None,
    extents=None,
    snapshot=None,
    pv=None,
    thinvolume=False,
    thinpool=False,
    force=False,
    **kwargs
):
    """
    Create a new logical volume, with option for which physical volume to be used

    CLI Examples:

    .. code-block:: bash

        salt '*' lvm.lvcreate new_volume_name     vg_name size=10G
        salt '*' lvm.lvcreate new_volume_name     vg_name extents=100 pv=/dev/sdb
        salt '*' lvm.lvcreate new_snapshot        vg_name snapshot=volume_name size=3G

    .. versionadded:: to_complete

    Support for thin pools and thin volumes

    CLI Examples:

    .. code-block:: bash

        salt '*' lvm.lvcreate new_thinpool_name   vg_name               size=20G thinpool=True
        salt '*' lvm.lvcreate new_thinvolume_name vg_name/thinpool_name size=10G thinvolume=True

    """
    if size and extents:
        return "Error: Please specify only one of size or extents"
    if thinvolume and thinpool:
        return "Error: Please set only one of thinvolume or thinpool to True"

    valid = (
        "activate",
        "chunksize",
        "contiguous",
        "discards",
        "stripes",
        "stripesize",
        "minor",
        "persistent",
        "mirrors",
        "noudevsync",
        "monitor",
        "ignoremonitoring",
        "permission",
        "poolmetadatasize",
        "readahead",
        "regionsize",
        "type",
        "virtualsize",
        "zero",
    )
    no_parameter = (
        "noudevsync",
        "ignoremonitoring",
        "thin",
    )

    extra_arguments = []
    if kwargs:
        for k, v in six.iteritems(kwargs):
            if k in no_parameter:
                extra_arguments.append("--{0}".format(k))
            elif k in valid:
                extra_arguments.extend(["--{0}".format(k), "{0}".format(v)])

    cmd = [salt.utils.path.which("lvcreate")]

    if thinvolume:
        cmd.extend(["--thin", "-n", lvname])
    elif thinpool:
        cmd.extend(["--thinpool", lvname])
    else:
        cmd.extend(["-n", lvname])

    if snapshot:
        cmd.extend(["-s", "{0}/{1}".format(vgname, snapshot)])
    else:
        cmd.append(vgname)

    if size and thinvolume:
        cmd.extend(["-V", "{0}".format(size)])
    elif extents and thinvolume:
        return "Error: Thin volume size cannot be specified as extents"
    elif size:
        cmd.extend(["-L", "{0}".format(size)])
    elif extents:
        cmd.extend(["-l", "{0}".format(extents)])
    else:
        return "Error: Either size or extents must be specified"

    if pv:
        cmd.append(pv)
    if extra_arguments:
        cmd.extend(extra_arguments)

    if force:
        cmd.append("--yes")
    else:
        cmd.append("-qq")

    out = __salt__["cmd.run"](cmd, python_shell=False).splitlines()
    lvdev = "/dev/{0}/{1}".format(vgname, lvname)
    lvdata = lvdisplay(lvdev)
    lvdata["Output from lvcreate"] = out[0].strip()
    return lvdata

def vgremove(vgname, force=True):
    """
    Remove an LVM volume group

    CLI Examples:

    .. code-block:: bash

        salt mymachine lvm.vgremove vgname
        salt mymachine lvm.vgremove vgname force=True
    """
    cmd = ["vgremove", vgname]

    if force:
        cmd.append("--yes")
    else:
        cmd.append("-qq")

    out = __salt__["cmd.run"](cmd, python_shell=False)
    return out.strip()

def lvremove(lvname, vgname, force=True):
    """
    Remove a given existing logical volume from a named existing volume group

    CLI Example:

    .. code-block:: bash

        salt '*' lvm.lvremove lvname vgname force=True
    """
    cmd = ["lvremove", "{0}/{1}".format(vgname, lvname)]

    if force:
        cmd.append("--yes")
    else:
        cmd.append("-qq")

    out = __salt__["cmd.run"](cmd, python_shell=False)
    return out.strip()

def lvresize(size=None, lvpath=None, extents=None, force=False, resizefs=False):
    """
    Return information about the logical volume(s)

    CLI Examples:

    .. code-block:: bash

        salt '*' lvm.lvresize +12M /dev/mapper/vg1-test
        salt '*' lvm.lvresize lvpath=/dev/mapper/vg1-test extents=+100%FREE

    """
    if size and extents:
        log.error("Error: Please specify only one of size or extents")
        return {}

    cmd = ["lvresize"]

    if force:
        cmd.append("--yes")
    else:
        cmd.append("-qq")

    if resizefs:
        cmd.append("--resizefs")

    if size:
        cmd.extend(["-L", "{0}".format(size)])
    elif extents:
        cmd.extend(["-l", "{0}".format(extents)])
    else:
        log.error("Error: Either size or extents must be specified")
        return {}

    cmd.append(lvpath)
    cmd_ret = __salt__["cmd.run"](cmd, python_shell=False).splitlines()
    return {"Output from lvresize": cmd_ret[0].strip()}
<commit_msg>Cleaning the exceptions trackback in linux_lvm.py<commit_after># -*- coding: utf-8 -*-
"""
Support for Linux LVM2
"""
from __future__ import absolute_import, print_function, unicode_literals

# Import python libs
import logging
import os.path

# Import salt libs
import salt.utils.path
from salt.ext import six

# Set up logger
log = logging.getLogger(__name__)

# Define the module's virtual name
__virtualname__ = "lvm"

def __virtual__():
    """
    Only load the module if lvm is installed
    """
    if salt.utils.path.which("lvm"):
        return __virtualname__
    return (
        False,
        "The linux_lvm execution module cannot be loaded: the lvm binary is not in the path.",
    )

def version():
    """
    Return LVM version from lvm version

    CLI Example:

    .. code-block:: bash

        salt '*' lvm.version
    """
    cmd = "lvm version"
    out = __salt__["cmd.run"](cmd).splitlines()
    ret = out[0].split(": ")
    return ret[1].strip()

def fullversion():
    """
    Return all version info from lvm version

    CLI Example:

    .. code-block:: bash

        salt '*' lvm.fullversion
    """
    ret = {}
    cmd = "lvm version"
    out = __salt__["cmd.run"](cmd).splitlines()
    for line in out:
        comps = line.split(":")
        ret[comps[0].strip()] = comps[1].strip()
    return ret

def pvdisplay(pvname="", real=False, quiet=False):
    """
    Return information about the physical volume(s)

    pvname
        physical device name

    real
        dereference any symlinks and report the real device

        .. versionadded:: 2015.8.7

    quiet
        if the physical volume is not present, do not show any error

    CLI Examples:

    .. code-block:: bash

        salt '*' lvm.pvdisplay
        salt '*' lvm.pvdisplay /dev/md0
    """
    ret = {}
    cmd = ["pvdisplay", "-c"]
    if pvname:
        cmd.append(pvname)
    cmd_ret = __salt__["cmd.run_all"](cmd, python_shell=False, ignore_retcode=quiet)

    if cmd_ret["retcode"] != 0:
        return {}

    out = cmd_ret["stdout"].splitlines()
    for line in out:
        if "is a new physical volume" not in line:
            comps = line.strip().split(":")
            if real:
                device = os.path.realpath(comps[0])
            else:
                device = comps[0]
            ret[device] = {
                "Physical Volume Device": comps[0],
                "Volume Group Name": comps[1],
                "Physical Volume Size (kB)": comps[2],
                "Internal Physical Volume Number": comps[3],
                "Physical Volume Status": comps[4],
                "Physical Volume (not) Allocatable": comps[5],
                "Current Logical Volumes Here": comps[6],
                "Physical Extent Size (kB)": comps[7],
                "Total Physical Extents": comps[8],
                "Free Physical Extents": comps[9],
                "Allocated Physical Extents": comps[10],
            }
            if real:
                ret[device]["Real Physical Volume Device"] = device
    return ret

def vgdisplay(vgname="", quiet=False):
    """
    Return information about the volume group(s)

    vgname
        volume group name

    quiet
        if the volume group is not present, do not show any error

    CLI Examples:

    .. code-block:: bash

        salt '*' lvm.vgdisplay
        salt '*' lvm.vgdisplay nova-volumes
    """
    ret = {}
    cmd = ["vgdisplay", "-c"]
    if vgname:
        cmd.append(vgname)
    cmd_ret = __salt__["cmd.run_all"](cmd, python_shell=False, ignore_retcode=quiet)

    if cmd_ret["retcode"] != 0:
        return {}

    out = cmd_ret["stdout"].splitlines()
    for line in out:
        comps = line.strip().split(":")
        ret[comps[0]] = {
            "Volume Group Name": comps[0],
            "Volume Group Access": comps[1],
            "Volume Group Status": comps[2],
            "Internal Volume Group Number": comps[3],
            "Maximum Logical Volumes": comps[4],
            "Current Logical Volumes": comps[5],
            "Open Logical Volumes": comps[6],
            "Maximum Logical Volume Size": comps[7],
            "Maximum Physical Volumes": comps[8],
            "Current Physical Volumes": comps[9],
            "Actual Physical Volumes": comps[10],
            "Volume Group Size (kB)": comps[11],
            "Physical Extent Size (kB)": comps[12],
            "Total Physical Extents": comps[13],
            "Allocated Physical Extents": comps[14],
            "Free Physical Extents": comps[15],
            "UUID": comps[16],
        }
    return ret

def lvdisplay(lvname="", quiet=False):
    """
    Return information about the logical volume(s)

    lvname
        logical device name

    quiet
        if the logical volume is not present, do not show any error

    CLI Examples:

    .. code-block:: bash

        salt '*' lvm.lvdisplay
        salt '*' lvm.lvdisplay /dev/vg_myserver/root
    """
    ret = {}
    cmd = ["lvdisplay", "-c"]
    if lvname:
        cmd.append(lvname)
    cmd_ret = __salt__["cmd.run_all"](cmd, python_shell=False, ignore_retcode=quiet)

    if cmd_ret["retcode"] != 0:
        return {}

    out = cmd_ret["stdout"].splitlines()
    for line in out:
        comps = line.strip().split(":")
        ret[comps[0]] = {
            "Logical Volume Name": comps[0],
            "Volume Group Name": comps[1],
            "Logical Volume Access": comps[2],
            "Logical Volume Status": comps[3],
            "Internal Logical Volume Number": comps[4],
            "Open Logical Volumes": comps[5],
            "Logical Volume Size": comps[6],
            "Current Logical Extents Associated": comps[7],
            "Allocated Logical Extents": comps[8],
            "Allocation Policy": comps[9],
            "Read Ahead Sectors": comps[10],
            "Major Device Number": comps[11],
            "Minor Device Number": comps[12],
        }
    return ret

def pvcreate(devices, override=True, force=True, **kwargs):
    """
    Set a physical device to be used as an LVM physical volume

    override
        Skip devices, if they are already LVM physical volumes

    CLI Examples:

    .. code-block:: bash

        salt mymachine lvm.pvcreate /dev/sdb1,/dev/sdb2
        salt mymachine lvm.pvcreate /dev/sdb1 dataalignmentoffset=7s
    """
    if not devices:
        return "Error: at least one device is required"
    if isinstance(devices, six.string_types):
        devices = devices.split(",")

    cmd = ["pvcreate"]

    if force:
        cmd.append("--yes")
    else:
        cmd.append("-qq")

    for device in devices:
        if not os.path.exists(device):
            return "{0} does not exist".format(device)
        if not pvdisplay(device, quiet=True):
            cmd.append(device)
        elif not override:
            return 'Device "{0}" is already an LVM physical volume.'.format(device)

    if not cmd[2:]:
        # All specified devices are already LVM volumes
        return True

    valid = (
        "metadatasize",
        "dataalignment",
        "dataalignmentoffset",
        "pvmetadatacopies",
        "metadatacopies",
        "metadataignore",
        "restorefile",
        "norestorefile",
        "labelsector",
        "setphysicalvolumesize",
    )
    no_parameter = "norestorefile"
    for var in kwargs:
        if kwargs[var] and var in valid:
            cmd.extend(["--{0}".format(var), kwargs[var]])
        elif kwargs[var] and var in no_parameter:
            cmd.append("--{0}".format(var))

    out = __salt__["cmd.run_all"](cmd, python_shell=False)
    if out.get("retcode"):
        return out.get("stderr")

    # Verify pvcreate was successful
    for device in devices:
        if not pvdisplay(device):
            return 'Device "{0}" was not affected.'.format(device)

    return True

def pvremove(devices, override=True, force=True):
    """
    Remove a physical device being used as an LVM physical volume

    override
        Skip devices, if they are already not used as LVM physical volumes

    CLI Examples:

    .. code-block:: bash

        salt mymachine lvm.pvremove /dev/sdb1,/dev/sdb2
    """
    if isinstance(devices, six.string_types):
        devices = devices.split(",")

    cmd = ["pvremove"]

    if force:
        cmd.append("--yes")
    else:
        cmd.append("-qq")

    for device in devices:
        if pvdisplay(device):
            cmd.append(device)
        elif not override:
            return "{0} is not a physical volume".format(device)

    if not cmd[2:]:
        # Nothing to do
        return True

    out = __salt__["cmd.run_all"](cmd, python_shell=False)
    if out.get("retcode"):
        return out.get("stderr")

    # Verify pvremove was successful
    for device in devices:
        if pvdisplay(device, quiet=True):
            return 'Device "{0}" was not affected.'.format(device)

    return True

def vgcreate(vgname, devices, force=False, **kwargs):
    """
    Create an LVM volume group

    CLI Examples:

    .. code-block:: bash

        salt mymachine lvm.vgcreate my_vg /dev/sdb1,/dev/sdb2
        salt mymachine lvm.vgcreate my_vg /dev/sdb1 clustered=y
    """
    if not vgname or not devices:
        return "Error: vgname and device(s) are both required"
    if isinstance(devices, six.string_types):
        devices = devices.split(",")

    cmd = ["vgcreate", vgname]
    for device in devices:
        cmd.append(device)

    if force:
        cmd.append("--yes")
    else:
        cmd.append("-qq")

    valid = (
        "clustered",
        "maxlogicalvolumes",
        "maxphysicalvolumes",
        "vgmetadatacopies",
        "metadatacopies",
        "physicalextentsize",
    )
    for var in kwargs:
        if kwargs[var] and var in valid:
            cmd.append("--{0}".format(var))
            cmd.append(kwargs[var])
    out = __salt__["cmd.run"](cmd, python_shell=False).splitlines()
    vgdata = vgdisplay(vgname)
    vgdata["Output from vgcreate"] = out[0].strip()
    return vgdata

def vgextend(vgname, devices, force=False):
    """
    Add physical volumes to an LVM volume group

    CLI Examples:

    .. code-block:: bash

        salt mymachine lvm.vgextend my_vg /dev/sdb1,/dev/sdb2
        salt mymachine lvm.vgextend my_vg /dev/sdb1
    """
    if not vgname or not devices:
        return "Error: vgname and device(s) are both required"
    if isinstance(devices, six.string_types):
        devices = devices.split(",")

    cmd = ["vgextend", vgname]

    if force:
        cmd.append("--yes")
    else:
        cmd.append("-qq")

    for device in devices:
        cmd.append(device)
    out = __salt__["cmd.run"](cmd, python_shell=False).splitlines()
    vgdata = {"Output from vgextend": out[0].strip()}
    return vgdata

def lvcreate(
    lvname,
    vgname,
    size=None,
    extents=None,
    snapshot=None,
    pv=None,
    thinvolume=False,
    thinpool=False,
    force=False,
    **kwargs
):
    """
    Create a new logical volume, with option for which physical volume to be used

    CLI Examples:

    .. code-block:: bash

        salt '*' lvm.lvcreate new_volume_name     vg_name size=10G
        salt '*' lvm.lvcreate new_volume_name     vg_name extents=100 pv=/dev/sdb
        salt '*' lvm.lvcreate new_snapshot        vg_name snapshot=volume_name size=3G

    .. versionadded:: to_complete

    Support for thin pools and thin volumes

    CLI Examples:

    .. code-block:: bash

        salt '*' lvm.lvcreate new_thinpool_name   vg_name               size=20G thinpool=True
        salt '*' lvm.lvcreate new_thinvolume_name vg_name/thinpool_name size=10G thinvolume=True

    """
    if size and extents:
        return "Error: Please specify only one of size or extents"
    if thinvolume and thinpool:
        return "Error: Please set only one of thinvolume or thinpool to True"

    valid = (
        "activate",
        "chunksize",
        "contiguous",
        "discards",
        "stripes",
        "stripesize",
        "minor",
        "persistent",
        "mirrors",
        "noudevsync",
        "monitor",
        "ignoremonitoring",
        "permission",
        "poolmetadatasize",
        "readahead",
        "regionsize",
        "type",
        "virtualsize",
        "zero",
    )
    no_parameter = (
        "noudevsync",
        "ignoremonitoring",
        "thin",
    )

    extra_arguments = []
    if kwargs:
        for k, v in six.iteritems(kwargs):
            if k in no_parameter:
                extra_arguments.append("--{0}".format(k))
            elif k in valid:
                extra_arguments.extend(["--{0}".format(k), "{0}".format(v)])

    cmd = [salt.utils.path.which("lvcreate")]

    if thinvolume:
        cmd.extend(["--thin", "-n", lvname])
    elif thinpool:
        cmd.extend(["--thinpool", lvname])
    else:
        cmd.extend(["-n", lvname])

    if snapshot:
        cmd.extend(["-s", "{0}/{1}".format(vgname, snapshot)])
    else:
        cmd.append(vgname)

    if size and thinvolume:
        cmd.extend(["-V", "{0}".format(size)])
    elif extents and thinvolume:
        return "Error: Thin volume size cannot be specified as extents"
    elif size:
        cmd.extend(["-L", "{0}".format(size)])
    elif extents:
        cmd.extend(["-l", "{0}".format(extents)])
    else:
        return "Error: Either size or extents must be specified"

    if pv:
        cmd.append(pv)
    if extra_arguments:
        cmd.extend(extra_arguments)

    if force:
        cmd.append("--yes")
    else:
        cmd.append("-qq")

    out = __salt__["cmd.run"](cmd, python_shell=False).splitlines()
    lvdev = "/dev/{0}/{1}".format(vgname, lvname)
    lvdata = lvdisplay(lvdev)
    lvdata["Output from lvcreate"] = out[0].strip()
    return lvdata

def vgremove(vgname, force=True):
    """
    Remove an LVM volume group

    CLI Examples:

    .. code-block:: bash

        salt mymachine lvm.vgremove vgname
        salt mymachine lvm.vgremove vgname force=True
    """
    cmd = ["vgremove", vgname]

    if force:
        cmd.append("--yes")
    else:
        cmd.append("-qq")

    out = __salt__["cmd.run"](cmd, python_shell=False)
    return out.strip()

def lvremove(lvname, vgname, force=True):
    """
    Remove a given existing logical volume from a named existing volume group

    CLI Example:

    .. code-block:: bash

        salt '*' lvm.lvremove lvname vgname force=True
    """
    cmd = ["lvremove", "{0}/{1}".format(vgname, lvname)]

    if force:
        cmd.append("--yes")
    else:
        cmd.append("-qq")

    out = __salt__["cmd.run"](cmd, python_shell=False)
    return out.strip()

def lvresize(size=None, lvpath=None, extents=None, force=False, resizefs=False):
    """
    Return information about the logical volume(s)

    CLI Examples:

    .. code-block:: bash

        salt '*' lvm.lvresize +12M /dev/mapper/vg1-test
        salt '*' lvm.lvresize lvpath=/dev/mapper/vg1-test extents=+100%FREE

    """
    if size and extents:
        log.error("Error: Please specify only one of size or extents")
        return {}

    cmd = ["lvresize"]

    if force:
        cmd.append("--yes")
    else:
        cmd.append("-qq")

    if resizefs:
        cmd.append("--resizefs")

    if size:
        cmd.extend(["-L", "{0}".format(size)])
    elif extents:
        cmd.extend(["-l", "{0}".format(extents)])
    else:
        log.error("Error: Either size or extents must be specified")
        return {}

    cmd.append(lvpath)
    cmd_ret = __salt__["cmd.run"](cmd, python_shell=False).splitlines()
    return {"Output from lvresize": cmd_ret[0].strip()}
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
'''
Module for managing locales on POSIX-like systems.
'''

# Import python libs
import logging
import re

# Import salt libs
import salt.utils

log = logging.getLogger(__name__)

# Define the module's virtual name
__virtualname__ = 'locale'

def __virtual__():
    '''
    Only work on POSIX-like systems
    '''
    if salt.utils.is_windows():
        return False
    return __virtualname__

def _parse_localectl():
    '''
    Get the 'System Locale' parameters from localectl
    '''
    ret = {}
    for line in __salt__['cmd.run']('localectl').splitlines():
        cols = [x.strip() for x in line.split(':', 1)]
        if len(cols) > 1:
            cur_param = cols.pop(0)
        if cur_param == 'System Locale':
            try:
                key, val = re.match('^([A-Z_]+)=(.*)$', cols[0]).groups()
            except AttributeError:
                log.error('Odd locale parameter "{0}" detected in localectl '
                          'output. This should not happen. localectl should '
                          'catch this. You should probably investigate what '
                          'caused this.'.format(cols[0]))
            else:
                ret[key] = val.replace('"', '')
    return ret

def _localectl_get():
    '''
    Use systemd's localectl command to get the current locale
    '''
    return _parse_localectl().get('LANG', '')

def _localectl_set(locale=''):
    '''
    Use systemd's localectl command to set the LANG locale parameter, making
    sure not to trample on other params that have been set.
    '''
    locale_params = _parse_localectl()
    locale_params['LANG'] = str(locale)
    args = ' '.join(['{0}="{1}"'.format(k, v)
                     for k, v in locale_params.iteritems()])
    cmd = 'localectl set-locale {0}'.format(args)
    return __salt__['cmd.retcode'](cmd) == 0

def list_avail():
    '''
    Lists available (compiled) locales

    CLI Example:

    .. code-block:: bash

        salt '*' locale.list_avail
    '''
    cmd = 'locale -a'
    out = __salt__['cmd.run'](cmd).split('\n')
    return out

def get_locale():
    '''
    Get the current system locale

    CLI Example:

    .. code-block:: bash

        salt '*' locale.get_locale
    '''
    cmd = ''
    if 'Arch' in __grains__['os_family']:
        return _localectl_get()
    elif 'RedHat' in __grains__['os_family']:
        cmd = 'grep "^LANG=" /etc/sysconfig/i18n'
    elif 'Debian' in __grains__['os_family']:
        cmd = 'grep "^LANG=" /etc/default/locale'
    elif 'Gentoo' in __grains__['os_family']:
        cmd = 'eselect --brief locale show'
        return __salt__['cmd.run'](cmd).strip()

    try:
        return __salt__['cmd.run'](cmd).split('=')[1].replace('"', '')
    except IndexError:
        return ''

def set_locale(locale):
    '''
    Sets the current system locale

    CLI Example:

    .. code-block:: bash

        salt '*' locale.set_locale 'en_US.UTF-8'
    '''
    if 'Arch' in __grains__['os_family']:
        return _localectl_set(locale)
    elif 'RedHat' in __grains__['os_family']:
        __salt__['file.sed'](
            '/etc/sysconfig/i18n', '^LANG=.*', 'LANG="{0}"'.format(locale)
        )
        __salt__['cmd.run'](
            'grep "^LANG=" /etc/sysconfig/i18n || echo "\nLANG={0}" '
            '>> /etc/sysconfig/i18n'.format(locale)
        )
    elif 'Debian' in __grains__['os_family']:
        __salt__['file.sed'](
            '/etc/default/locale', '^LANG=.*', 'LANG="{0}"'.format(locale)
        )
        __salt__['cmd.run'](
            'grep "^LANG=" /etc/default/locale || '
            'echo "\nLANG={0}" >> /etc/default/locale'.format(locale)
        )
    elif 'Gentoo' in __grains__['os_family']:
        cmd = 'eselect --brief locale set {0}'.format(locale)
        return __salt__['cmd.retcode'](cmd) == 0

    return True

def _normalize_locale(locale):
    lang_encoding = locale.split('.')
    lang_split = lang_encoding[0].split('_')
    if len(lang_split) > 1:
        lang_split[1] = lang_split[1].upper()
    lang_encoding[0] = '_'.join(lang_split)
    if len(lang_encoding) > 1:
        if len(lang_split) > 1:
           lang_encoding[1] = lang_encoding[1].lower().replace('-', '')
    return '.'.join(lang_encoding)

def avail(locale):
    '''
    Check if a locale is available

    CLI Example:

    .. code-block:: bash

        salt '*' locale.avail 'en_US.UTF-8'
    '''
    normalized_locale = _normalize_locale(locale)
    avail_locales = __salt__['locale.list_avail']()
    locale_exists = next((True for x in avail_locales if _normalize_locale(x.strip()) == normalized_locale), False)
    return locale_exists

def gen_locale(locale):
    '''
    Generate a locale

    CLI Example:

    .. code-block:: bash

        salt '*' locale.gen_locale 'en_US.UTF-8'
    '''

    __salt__['cmd.run'](
        'locale-gen {0}'.format(locale)
    )

    return True
<commit_msg>shorter line<commit_after># -*- coding: utf-8 -*-
'''
Module for managing locales on POSIX-like systems.
'''

# Import python libs
import logging
import re

# Import salt libs
import salt.utils

log = logging.getLogger(__name__)

# Define the module's virtual name
__virtualname__ = 'locale'

def __virtual__():
    '''
    Only work on POSIX-like systems
    '''
    if salt.utils.is_windows():
        return False
    return __virtualname__

def _parse_localectl():
    '''
    Get the 'System Locale' parameters from localectl
    '''
    ret = {}
    for line in __salt__['cmd.run']('localectl').splitlines():
        cols = [x.strip() for x in line.split(':', 1)]
        if len(cols) > 1:
            cur_param = cols.pop(0)
        if cur_param == 'System Locale':
            try:
                key, val = re.match('^([A-Z_]+)=(.*)$', cols[0]).groups()
            except AttributeError:
                log.error('Odd locale parameter "{0}" detected in localectl '
                          'output. This should not happen. localectl should '
                          'catch this. You should probably investigate what '
                          'caused this.'.format(cols[0]))
            else:
                ret[key] = val.replace('"', '')
    return ret

def _localectl_get():
    '''
    Use systemd's localectl command to get the current locale
    '''
    return _parse_localectl().get('LANG', '')

def _localectl_set(locale=''):
    '''
    Use systemd's localectl command to set the LANG locale parameter, making
    sure not to trample on other params that have been set.
    '''
    locale_params = _parse_localectl()
    locale_params['LANG'] = str(locale)
    args = ' '.join(['{0}="{1}"'.format(k, v)
                     for k, v in locale_params.iteritems()])
    cmd = 'localectl set-locale {0}'.format(args)
    return __salt__['cmd.retcode'](cmd) == 0

def list_avail():
    '''
    Lists available (compiled) locales

    CLI Example:

    .. code-block:: bash

        salt '*' locale.list_avail
    '''
    cmd = 'locale -a'
    out = __salt__['cmd.run'](cmd).split('\n')
    return out

def get_locale():
    '''
    Get the current system locale

    CLI Example:

    .. code-block:: bash

        salt '*' locale.get_locale
    '''
    cmd = ''
    if 'Arch' in __grains__['os_family']:
        return _localectl_get()
    elif 'RedHat' in __grains__['os_family']:
        cmd = 'grep "^LANG=" /etc/sysconfig/i18n'
    elif 'Debian' in __grains__['os_family']:
        cmd = 'grep "^LANG=" /etc/default/locale'
    elif 'Gentoo' in __grains__['os_family']:
        cmd = 'eselect --brief locale show'
        return __salt__['cmd.run'](cmd).strip()

    try:
        return __salt__['cmd.run'](cmd).split('=')[1].replace('"', '')
    except IndexError:
        return ''

def set_locale(locale):
    '''
    Sets the current system locale

    CLI Example:

    .. code-block:: bash

        salt '*' locale.set_locale 'en_US.UTF-8'
    '''
    if 'Arch' in __grains__['os_family']:
        return _localectl_set(locale)
    elif 'RedHat' in __grains__['os_family']:
        __salt__['file.sed'](
            '/etc/sysconfig/i18n', '^LANG=.*', 'LANG="{0}"'.format(locale)
        )
        __salt__['cmd.run'](
            'grep "^LANG=" /etc/sysconfig/i18n || echo "\nLANG={0}" '
            '>> /etc/sysconfig/i18n'.format(locale)
        )
    elif 'Debian' in __grains__['os_family']:
        __salt__['file.sed'](
            '/etc/default/locale', '^LANG=.*', 'LANG="{0}"'.format(locale)
        )
        __salt__['cmd.run'](
            'grep "^LANG=" /etc/default/locale || '
            'echo "\nLANG={0}" >> /etc/default/locale'.format(locale)
        )
    elif 'Gentoo' in __grains__['os_family']:
        cmd = 'eselect --brief locale set {0}'.format(locale)
        return __salt__['cmd.retcode'](cmd) == 0

    return True

def _normalize_locale(locale):
    lang_encoding = locale.split('.')
    lang_split = lang_encoding[0].split('_')
    if len(lang_split) > 1:
        lang_split[1] = lang_split[1].upper()
    lang_encoding[0] = '_'.join(lang_split)
    if len(lang_encoding) > 1:
        if len(lang_split) > 1:
           lang_encoding[1] = lang_encoding[1].lower().replace('-', '')
    return '.'.join(lang_encoding)

def avail(locale):
    '''
    Check if a locale is available

    CLI Example:

    .. code-block:: bash

        salt '*' locale.avail 'en_US.UTF-8'
    '''
    normalized_locale = _normalize_locale(locale)
    avail_locales = __salt__['locale.list_avail']()
    locale_exists = next((True for x in avail_locales
       if _normalize_locale(x.strip()) == normalized_locale), False)
    return locale_exists

def gen_locale(locale):
    '''
    Generate a locale

    CLI Example:

    .. code-block:: bash

        salt '*' locale.gen_locale 'en_US.UTF-8'
    '''

    __salt__['cmd.run'](
        'locale-gen {0}'.format(locale)
    )

    return True
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""
Neuroimaging tools for Python (NIPY).

The aim of NIPY is to produce a platform-independent Python environment for
the analysis of brain imaging data using an open development model.

The main website for NIPY is here:
http://nipy.sourceforge.net/

Nipype is the Neuroimaging in Python Pipelines and Interfaces package.
It's aim is to create Python Interfaces to other neuroimaging packages
and create an API for specifying a full analysis pipeline in Python.

Interfaces

    1. provide interface for using other packages through Python

        a. fsl (fsl 4.0 and above) http://www.fmrib.ox.ac.uk/fsl/

        b. spm (spm5, spm 8) http://www.fil.ion.ucl.ac.uk/spm/

        c. freesurfer

        d. afni

    2. pipeline functionality for batch processing data

        a. wrappers to provide common basic interface independent functionality
        (SkullStrip, Coregister, Realign, Warp,...)

        b. engine(s) to use other packages for controlling pipeline
        (networkx, ruffus, etc..)

        c. tools for interfacing databases, repositories

        d. tools for providence tracking, subject specific flags

Package Organization
====================
The nipy package contains the following subpackages and modules:

.. packagetree::
   :style: UML
"""

from version import version as __version__

__status__   = 'alpha'
__url__     = 'http://nipy.sourceforge.net/'

# We require numpy 1.2 for our test suite.  If Tester fails to import,
# check the version of numpy the user has and inform them they need to
# upgrade.
try:
    from numpy.testing import Tester

    class NipypeTester(Tester):
        def test(self, label='fast', verbose=1, extra_argv=None,
                 doctests=False, coverage=False):
            # setuptools does a chmod +x on ALL python modules when it
            # installs.  By default, as a security measure, nose refuses to
            # import executable files.  To forse nose to execute our tests, we
            # must supply the '--exe' flag.  List thread on this:
            # http://www.mail-archive.com/distutils-sig@python.org/msg05009.html
            if not extra_argv:
                extra_argv = ['--exe']
            else:
                extra_argv.append('--exe')
            super(NipypeTester, self).test(label, verbose, extra_argv,
                                           doctests, coverage)
        # Grab the docstring from numpy
        test.__doc__ = Tester.test.__doc__

    test = NipypeTester().test
    bench = NipypeTester().bench
except ImportError:
    # If the user has an older version of numpy which does not have
    # the nose test framework, fail gracefully and prompt them to
    # upgrade.
    import numpy as np
    npver = np.__version__.split('.')
    npver = '.'.join((npver[0], npver[1]))
    npver = float(npver)
    if npver < 1.2:
        raise ImportError('Nipy/nipype requires numpy version 1.2 or greater. '
                          '\n    You have numpy version %s installed.'
                          '\n    Please upgrade numpy:  '
                          'http://www.scipy.org/NumPy'
                          % np.__version__)

def _test_local_install():
    """ Warn the user that running with nipy being
        imported locally is a bad idea.
    """
    import os
    if os.getcwd() == os.sep.join(
                            os.path.abspath(__file__).split(os.sep)[:-2]):
        import warnings
        warnings.warn('Running the tests from the install directory may '
                     'trigger some failures')

_test_local_install()

# Cleanup namespace
del _test_local_install

# If this file is exec after being imported, the following lines will
# fail
try:
    del version
    del Tester
except:
    pass
<commit_msg>RF: relax numpy requirement to 1.1 to allow import of nipype even if tests can't be ran<commit_after># -*- coding: utf-8 -*-
"""
Neuroimaging tools for Python (NIPY).

The aim of NIPY is to produce a platform-independent Python environment for
the analysis of brain imaging data using an open development model.

The main website for NIPY is here:
http://nipy.sourceforge.net/

Nipype is the Neuroimaging in Python Pipelines and Interfaces package.
It's aim is to create Python Interfaces to other neuroimaging packages
and create an API for specifying a full analysis pipeline in Python.

Interfaces

    1. provide interface for using other packages through Python

        a. fsl (fsl 4.0 and above) http://www.fmrib.ox.ac.uk/fsl/

        b. spm (spm5, spm 8) http://www.fil.ion.ucl.ac.uk/spm/

        c. freesurfer

        d. afni

    2. pipeline functionality for batch processing data

        a. wrappers to provide common basic interface independent functionality
        (SkullStrip, Coregister, Realign, Warp,...)

        b. engine(s) to use other packages for controlling pipeline
        (networkx, ruffus, etc..)

        c. tools for interfacing databases, repositories

        d. tools for providence tracking, subject specific flags

Package Organization
====================
The nipy package contains the following subpackages and modules:

.. packagetree::
   :style: UML
"""

from version import version as __version__

__status__   = 'alpha'
__url__     = 'http://nipy.sourceforge.net/'

# We require numpy 1.2 for our test suite.  If Tester fails to import,
# check the version of numpy the user has and inform them they need to
# upgrade.
try:
    from numpy.testing import Tester

    class NipypeTester(Tester):
        def test(self, label='fast', verbose=1, extra_argv=None,
                 doctests=False, coverage=False):
            # setuptools does a chmod +x on ALL python modules when it
            # installs.  By default, as a security measure, nose refuses to
            # import executable files.  To forse nose to execute our tests, we
            # must supply the '--exe' flag.  List thread on this:
            # http://www.mail-archive.com/distutils-sig@python.org/msg05009.html
            if not extra_argv:
                extra_argv = ['--exe']
            else:
                extra_argv.append('--exe')
            super(NipypeTester, self).test(label, verbose, extra_argv,
                                           doctests, coverage)
        # Grab the docstring from numpy
        test.__doc__ = Tester.test.__doc__

    test = NipypeTester().test
    bench = NipypeTester().bench
except ImportError:
    # If the user has an older version of numpy which does not have
    # the nose test framework, verify that at least numpy 1.1 is available
    # and instruct to use nose directly for unittesting if test or bench
    # is called
    from nipype.utils.misc import package_check
    package_check('numpy', version='1.1')
    def test():
        raise NotImplementedError(
            'Since you are running numpy version prior 1.2, you '
            'would need to use nosetests directly, i.e no '
            'nipype.test(), nipype.bench() are provided.')
    # so "nosetests nipype" doesn't collect these poor buggers
    test.__test__ = False
    bench = test

def _test_local_install():
    """ Warn the user that running with nipy being
        imported locally is a bad idea.
    """
    import os
    if os.getcwd() == os.sep.join(
                            os.path.abspath(__file__).split(os.sep)[:-2]):
        import warnings
        warnings.warn('Running the tests from the install directory may '
                     'trigger some failures')

_test_local_install()

# Cleanup namespace
del _test_local_install

# If this file is exec after being imported, the following lines will
# fail
try:
    del version
    del Tester
except:
    pass
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
'''
Clone a remote git repository and use the filesystem as a Pillar source

This external Pillar source can be configured in the master config file like
so:

.. code-block:: yaml

    ext_pillar:
      - git: master git://gitserver/git-pillar.git root=subdirectory

The `root=` parameter is optional and used to set the subdirectory from where
to look for Pillar files (such as ``top.sls``).

.. versionchanged:: 2014.7.0
    The optional ``root`` parameter will be added.

.. versionchanged:: @TBD
    The special branch name '_' will be replace by the environment ({{env}})

Note that this is not the same thing as configuring pillar data using the
:conf_master:`pillar_roots` parameter. The branch referenced in the
:conf_master:`ext_pillar` entry above (``master``), would evaluate to the
``base`` environment, so this branch needs to contain a ``top.sls`` with a
``base`` section in it, like this:

.. code-block:: yaml

    base:
      '*':
        - foo

To use other environments from the same git repo as git_pillar sources, just
add additional lines, like so:

.. code-block:: yaml

    ext_pillar:
      - git: master git://gitserver/git-pillar.git
      - git: dev git://gitserver/git-pillar.git

In this case, the ``dev`` branch would need its own ``top.sls`` with a ``dev``
section in it, like this:

.. code-block:: yaml

    dev:
      '*':
        - bar

In a gitfs base setup with pillars from the same repository as the states,
the ``ext_pillar:`` configuration would be like:

.. code-block:: yaml

    ext_pillar:
      - git: _ git://gitserver/git-pillar.git root=pillar

The (optinal) root=pillar defines the directory that contains the pillar data.
The corresponding ``top.sls`` would be like:

.. code-block:: yaml

    {{env}}:
      '*':
        - bar
'''
from __future__ import absolute_import

# Import python libs
from copy import deepcopy
import logging
import hashlib
import os

# Import third party libs
HAS_GIT = False
try:
    import git
    HAS_GIT = True
except ImportError:
    pass

# Import salt libs
from salt.pillar import Pillar

# Set up logging
log = logging.getLogger(__name__)

# Define the module's virtual name
__virtualname__ = 'git'

def __virtual__():
    '''
    Only load if gitpython is available
    '''
    ext_pillar_sources = [x for x in __opts__.get('ext_pillar', [])]
    if not any(['git' in x for x in ext_pillar_sources]):
        return False
    if not HAS_GIT:
        log.error('Git-based ext_pillar is enabled in configuration but '
                  'could not be loaded, is GitPython installed?')
        return False
    if not git.__version__ > '0.3.0':
        return False
    return __virtualname__

class GitPillar(object):
    '''
    Deal with the remote git repository for Pillar
    '''

    def __init__(self, branch, repo_location, opts):
        '''
        Try to initialize the Git repo object
        '''
        self.branch = self.map_branch(branch, opts)
        self.rp_location = repo_location
        self.opts = opts
        self._envs = set()
        self.working_dir = ''
        self.repo = None

        hash_type = getattr(hashlib, opts.get('hash_type', 'md5'))
        hash_str = '{0} {1}'.format(self.branch, self.rp_location)
        repo_hash = hash_type(hash_str).hexdigest()
        rp_ = os.path.join(self.opts['cachedir'], 'pillar_gitfs', repo_hash)

        if not os.path.isdir(rp_):
            os.makedirs(rp_)

        try:
            self.repo = git.Repo.init(rp_)
        except (git.exc.NoSuchPathError,
                git.exc.InvalidGitRepositoryError) as exc:
            log.error('GitPython exception caught while '
                      'initializing the repo: {0}. Maybe '
                      'git is not available.'.format(exc))

        # Git directory we are working on
        # Should be the same as self.repo.working_dir
        self.working_dir = rp_

        if isinstance(self.repo, git.Repo):
            if not self.repo.remotes:
                try:
                    self.repo.create_remote('origin', self.rp_location)
                    # ignore git ssl verification if requested
                    if self.opts.get('pillar_gitfs_ssl_verify', True):
                        self.repo.git.config('http.sslVerify', 'true')
                    else:
                        self.repo.git.config('http.sslVerify', 'false')
                except os.error:
                    # This exception occurs when two processes are
                    # trying to write to the git config at once, go
                    # ahead and pass over it since this is the only
                    # write.
                    # This should place a lock down.
                    pass
            else:
                if self.repo.remotes.origin.url != self.rp_location:
                    self.repo.remotes.origin.config_writer.set('url', self.rp_location)

    def map_branch(self, branch, opts=None):
        opts = __opts__ if opts is None else opts
        if branch == '_':
            branch = opts['environment']
            if branch == 'base':
                branch = opts['gitfs_base']
        return branch

    def update(self):
        '''
        Ensure you are following the latest changes on the remote

        Return boolean whether it worked
        '''
        try:
            log.debug('Updating fileserver for git_pillar module')
            self.repo.git.fetch()
        except git.exc.GitCommandError as exc:
            log.error('Unable to fetch the latest changes from remote '
                      '{0}: {1}'.format(self.rp_location, exc))
            return False

        try:
            self.repo.git.checkout('origin/{0}'.format(self.branch))
        except git.exc.GitCommandError as exc:
            logging.error('Unable to checkout branch '
                          '{0}: {1}'.format(self.branch, exc))
            return False

        return True

    def envs(self):
        '''
        Return a list of refs that can be used as environments
        '''

        if isinstance(self.repo, git.Repo):
            remote = self.repo.remote()
            for ref in self.repo.refs:
                parted = ref.name.partition('/')
                short = parted[2] if parted[2] else parted[0]
                if isinstance(ref, git.Head):
                    if short == 'master':
                        short = 'base'
                    if ref not in remote.stale_refs:
                        self._envs.add(short)
                elif isinstance(ref, git.Tag):
                    self._envs.add(short)

        return list(self._envs)

def update(branch, repo_location):
    '''
    Ensure you are following the latest changes on the remote

    return boolean whether it worked
    '''
    gitpil = GitPillar(branch, repo_location, __opts__)

    return gitpil.update()

def envs(branch, repo_location):
    '''
    Return a list of refs that can be used as environments
    '''
    gitpil = GitPillar(branch, repo_location, __opts__)

    return gitpil.envs()

def _extract_key_val(kv, delimiter='='):
    '''Extract key and value from key=val string.

    Example:
    >>> _extract_key_val('foo=bar')
    ('foo', 'bar')
    '''
    pieces = kv.split(delimiter)
    key = pieces[0]
    val = delimiter.join(pieces[1:])
    return key, val

def ext_pillar(minion_id,
               repo_string,
               pillar_dirs):
    '''
    Execute a command and read the output as YAML
    '''
    if pillar_dirs is None:
        return
    # split the branch, repo name and optional extra (key=val) parameters.
    options = repo_string.strip().split()
    branch = options[0]
    repo_location = options[1]
    root = ''

    for extraopt in options[2:]:
        # Support multiple key=val attributes as custom parameters.
        DELIM = '='
        if DELIM not in extraopt:
            log.error('Incorrectly formatted extra parameter. '
                      'Missing {0!r}: {1}'.format(DELIM, extraopt))
        key, val = _extract_key_val(extraopt, DELIM)
        if key == 'root':
            root = val
        else:
            log.warning('Unrecognized extra parameter: {0}'.format(key))

    gitpil = GitPillar(branch, repo_location, __opts__)
    branch = gitpil.branch

    # environment is "different" from the branch
    branch = (branch == 'master' and 'base' or branch)

    # normpath is needed to remove appended '/' if root is empty string.
    pillar_dir = os.path.normpath(os.path.join(gitpil.working_dir, root))

    pillar_dirs.setdefault(pillar_dir, {})

    if pillar_dirs[pillar_dir].get(branch, False):
        return {}  # we've already seen this combo

    pillar_dirs[pillar_dir].setdefault(branch, True)

    # Don't recurse forever-- the Pillar object will re-call the ext_pillar
    # function
    if __opts__['pillar_roots'].get(branch, []) == [pillar_dir]:
        return {}

    gitpil.update()

    opts = deepcopy(__opts__)

    opts['pillar_roots'][branch] = [pillar_dir]

    pil = Pillar(opts, __grains__, minion_id, branch)

    return pil.compile_pillar()
<commit_msg>Renamed special branch from '_' to '__env__'<commit_after># -*- coding: utf-8 -*-
'''
Clone a remote git repository and use the filesystem as a Pillar source

This external Pillar source can be configured in the master config file like
so:

.. code-block:: yaml

    ext_pillar:
      - git: master git://gitserver/git-pillar.git root=subdirectory

The `root=` parameter is optional and used to set the subdirectory from where
to look for Pillar files (such as ``top.sls``).

.. versionchanged:: 2014.7.0
    The optional ``root`` parameter will be added.

.. versionchanged:: @TBD
    The special branch name '__env__' will be replace by the environment ({{env}})

Note that this is not the same thing as configuring pillar data using the
:conf_master:`pillar_roots` parameter. The branch referenced in the
:conf_master:`ext_pillar` entry above (``master``), would evaluate to the
``base`` environment, so this branch needs to contain a ``top.sls`` with a
``base`` section in it, like this:

.. code-block:: yaml

    base:
      '*':
        - foo

To use other environments from the same git repo as git_pillar sources, just
add additional lines, like so:

.. code-block:: yaml

    ext_pillar:
      - git: master git://gitserver/git-pillar.git
      - git: dev git://gitserver/git-pillar.git

In this case, the ``dev`` branch would need its own ``top.sls`` with a ``dev``
section in it, like this:

.. code-block:: yaml

    dev:
      '*':
        - bar

In a gitfs base setup with pillars from the same repository as the states,
the ``ext_pillar:`` configuration would be like:

.. code-block:: yaml

    ext_pillar:
      - git: _ git://gitserver/git-pillar.git root=pillar

The (optinal) root=pillar defines the directory that contains the pillar data.
The corresponding ``top.sls`` would be like:

.. code-block:: yaml

    {{env}}:
      '*':
        - bar
'''
from __future__ import absolute_import

# Import python libs
from copy import deepcopy
import logging
import hashlib
import os

# Import third party libs
HAS_GIT = False
try:
    import git
    HAS_GIT = True
except ImportError:
    pass

# Import salt libs
from salt.pillar import Pillar

# Set up logging
log = logging.getLogger(__name__)

# Define the module's virtual name
__virtualname__ = 'git'

def __virtual__():
    '''
    Only load if gitpython is available
    '''
    ext_pillar_sources = [x for x in __opts__.get('ext_pillar', [])]
    if not any(['git' in x for x in ext_pillar_sources]):
        return False
    if not HAS_GIT:
        log.error('Git-based ext_pillar is enabled in configuration but '
                  'could not be loaded, is GitPython installed?')
        return False
    if not git.__version__ > '0.3.0':
        return False
    return __virtualname__

class GitPillar(object):
    '''
    Deal with the remote git repository for Pillar
    '''

    def __init__(self, branch, repo_location, opts):
        '''
        Try to initialize the Git repo object
        '''
        self.branch = self.map_branch(branch, opts)
        self.rp_location = repo_location
        self.opts = opts
        self._envs = set()
        self.working_dir = ''
        self.repo = None

        hash_type = getattr(hashlib, opts.get('hash_type', 'md5'))
        hash_str = '{0} {1}'.format(self.branch, self.rp_location)
        repo_hash = hash_type(hash_str).hexdigest()
        rp_ = os.path.join(self.opts['cachedir'], 'pillar_gitfs', repo_hash)

        if not os.path.isdir(rp_):
            os.makedirs(rp_)

        try:
            self.repo = git.Repo.init(rp_)
        except (git.exc.NoSuchPathError,
                git.exc.InvalidGitRepositoryError) as exc:
            log.error('GitPython exception caught while '
                      'initializing the repo: {0}. Maybe '
                      'git is not available.'.format(exc))

        # Git directory we are working on
        # Should be the same as self.repo.working_dir
        self.working_dir = rp_

        if isinstance(self.repo, git.Repo):
            if not self.repo.remotes:
                try:
                    self.repo.create_remote('origin', self.rp_location)
                    # ignore git ssl verification if requested
                    if self.opts.get('pillar_gitfs_ssl_verify', True):
                        self.repo.git.config('http.sslVerify', 'true')
                    else:
                        self.repo.git.config('http.sslVerify', 'false')
                except os.error:
                    # This exception occurs when two processes are
                    # trying to write to the git config at once, go
                    # ahead and pass over it since this is the only
                    # write.
                    # This should place a lock down.
                    pass
            else:
                if self.repo.remotes.origin.url != self.rp_location:
                    self.repo.remotes.origin.config_writer.set('url', self.rp_location)

    def map_branch(self, branch, opts=None):
        opts = __opts__ if opts is None else opts
        if branch == '__env__':
            branch = opts['environment']
            if branch == 'base':
                branch = opts['gitfs_base']
        return branch

    def update(self):
        '''
        Ensure you are following the latest changes on the remote

        Return boolean whether it worked
        '''
        try:
            log.debug('Updating fileserver for git_pillar module')
            self.repo.git.fetch()
        except git.exc.GitCommandError as exc:
            log.error('Unable to fetch the latest changes from remote '
                      '{0}: {1}'.format(self.rp_location, exc))
            return False

        try:
            self.repo.git.checkout('origin/{0}'.format(self.branch))
        except git.exc.GitCommandError as exc:
            logging.error('Unable to checkout branch '
                          '{0}: {1}'.format(self.branch, exc))
            return False

        return True

    def envs(self):
        '''
        Return a list of refs that can be used as environments
        '''

        if isinstance(self.repo, git.Repo):
            remote = self.repo.remote()
            for ref in self.repo.refs:
                parted = ref.name.partition('/')
                short = parted[2] if parted[2] else parted[0]
                if isinstance(ref, git.Head):
                    if short == 'master':
                        short = 'base'
                    if ref not in remote.stale_refs:
                        self._envs.add(short)
                elif isinstance(ref, git.Tag):
                    self._envs.add(short)

        return list(self._envs)

def update(branch, repo_location):
    '''
    Ensure you are following the latest changes on the remote

    return boolean whether it worked
    '''
    gitpil = GitPillar(branch, repo_location, __opts__)

    return gitpil.update()

def envs(branch, repo_location):
    '''
    Return a list of refs that can be used as environments
    '''
    gitpil = GitPillar(branch, repo_location, __opts__)

    return gitpil.envs()

def _extract_key_val(kv, delimiter='='):
    '''Extract key and value from key=val string.

    Example:
    >>> _extract_key_val('foo=bar')
    ('foo', 'bar')
    '''
    pieces = kv.split(delimiter)
    key = pieces[0]
    val = delimiter.join(pieces[1:])
    return key, val

def ext_pillar(minion_id,
               repo_string,
               pillar_dirs):
    '''
    Execute a command and read the output as YAML
    '''
    if pillar_dirs is None:
        return
    # split the branch, repo name and optional extra (key=val) parameters.
    options = repo_string.strip().split()
    branch = options[0]
    repo_location = options[1]
    root = ''

    for extraopt in options[2:]:
        # Support multiple key=val attributes as custom parameters.
        DELIM = '='
        if DELIM not in extraopt:
            log.error('Incorrectly formatted extra parameter. '
                      'Missing {0!r}: {1}'.format(DELIM, extraopt))
        key, val = _extract_key_val(extraopt, DELIM)
        if key == 'root':
            root = val
        else:
            log.warning('Unrecognized extra parameter: {0}'.format(key))

    gitpil = GitPillar(branch, repo_location, __opts__)
    branch = gitpil.branch

    # environment is "different" from the branch
    branch = (branch == 'master' and 'base' or branch)

    # normpath is needed to remove appended '/' if root is empty string.
    pillar_dir = os.path.normpath(os.path.join(gitpil.working_dir, root))

    pillar_dirs.setdefault(pillar_dir, {})

    if pillar_dirs[pillar_dir].get(branch, False):
        return {}  # we've already seen this combo

    pillar_dirs[pillar_dir].setdefault(branch, True)

    # Don't recurse forever-- the Pillar object will re-call the ext_pillar
    # function
    if __opts__['pillar_roots'].get(branch, []) == [pillar_dir]:
        return {}

    gitpil.update()

    opts = deepcopy(__opts__)

    opts['pillar_roots'][branch] = [pillar_dir]

    pil = Pillar(opts, __grains__, minion_id, branch)

    return pil.compile_pillar()
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (C) 2007 Christopher Lenz
# All rights reserved.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution.

"""Implementation of a view server for functions written in Python."""

import os
import simplejson as json
import sys
import traceback
from types import FunctionType

__all__ = ['main', 'run']
__docformat__ = 'restructuredtext en'

def run(input=sys.stdin, output=sys.stdout):
    r"""CouchDB view function handler implementation for Python.

    >>> from StringIO import StringIO

    >>> output = StringIO()
    >>> run(input=StringIO('["reset"]\n'), output=output)
    >>> print output.getvalue()
    true
    <BLANKLINE>

    >>> output = StringIO()
    >>> run(input=StringIO('["add_fun", "def fun(doc): yield None, doc"]\n'),
    ...     output=output)
    >>> print output.getvalue()
    true
    <BLANKLINE>

    >>> output = StringIO()
    >>> run(input=StringIO('["add_fun", "def fun(doc): yield None, doc"]\n'
    ...                    '["map_doc", {"foo": "bar"}]\n'),
    ...     output=output)
    >>> print output.getvalue()
    true
    [[[null, {"foo": "bar"}]]]
    <BLANKLINE>

    :param input: the readable file-like object to read input from
    :param output: the writable file-like object to write output to
    """
    functions = []

    def reset():
        del functions[:]
        return True

    def add_fun(string):
        string = '\xef\xbb\xbf' + string.encode('utf-8')
        globals_ = {}
        try:
            exec string in {}, globals_
        except Exception, e:
            return {'error': {'id': 'map_compilation_error', 'reason': e.args[0]}}
        err = {'error': {
            'id': 'map_compilation_error',
            'reason': 'string must eval to a function (ex: "def(doc): return 1")'
        }}
        if len(globals_) != 1:
            return err
        function = globals_.values()[0]
        if type(function) is not FunctionType:
            return err
        functions.append(function)
        return True

    def map_doc(doc):
        results = []
        for function in functions:
            try:
                results.append([[key, value] for key, value in function(doc)])
            except Exception, e:
                results.append([])
                output.write(json.dumps({'log': e.args[0]}))
        return results

    handlers = {'reset': reset, 'add_fun': add_fun, 'map_doc': map_doc}

    try:
        while True:
            line = input.readline()
            if not line:
                break
            try:
                cmd = json.loads(line)
            except ValueError, e:
                sys.stderr.write('error: %s\n' % e)
                sys.stderr.flush()
                exit(1)
            else:
                retval = handlers[cmd[0]](*cmd[1:])
                output.write(json.dumps(retval))
                output.write('\n')
                output.flush()
    except KeyboardInterrupt:
        exit(0)

_VERSION = """%(name)s - CouchDB Python %(version)s

Copyright (C) 2007 Christopher Lenz <cmlenz@gmx.de>.
"""
_HELP = """Usage: %(name)s [OPTION]

The %(name)s command runs the CouchDB Python view server.

The exit status is 0 for success or 1 for failure.

Options:

  --version          display version information and exit
  -h, --help         display a short help message and exit

Report bugs via the web at <http://code.google.com/p/couchdb-python>.
"""

def main():
    """Command-line entry point for running the view server."""
    import getopt
    from couchdb import __version__ as VERSION
    try:
        option_list, argument_list = getopt.gnu_getopt(
            sys.argv[1:], 'h', ['version', 'help'])
        message = None
        for option, value in option_list:
            if option in ('--version'):
                message = _VERSION % dict(name=os.path.basename(sys.argv[0]),
                                      version=VERSION)
            elif option in ('-h', '--help'):
                message = _HELP % dict(name=os.path.basename(sys.argv[0]))
        if message:
            sys.stdout.write(message)
            sys.stdout.flush()
            exit(0)
    except getopt.GetoptError, error:
        message = '%s\n\nTry `%s --help` for more information.\n' % (
            str(error), os.path.basename(sys.argv[0])
        )
        sys.stderr.write(message)
        sys.stderr.flush()
        exit(1)
    run()

if __name__ == '__main__':
    main()
<commit_msg>Fix use of unqualified exit() function in view server (issue #7). Thanks to Noah Slater for the patch.<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (C) 2007 Christopher Lenz
# All rights reserved.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution.

"""Implementation of a view server for functions written in Python."""

import os
import simplejson as json
import sys
import traceback
from types import FunctionType

__all__ = ['main', 'run']
__docformat__ = 'restructuredtext en'

def run(input=sys.stdin, output=sys.stdout):
    r"""CouchDB view function handler implementation for Python.

    >>> from StringIO import StringIO

    >>> output = StringIO()
    >>> run(input=StringIO('["reset"]\n'), output=output)
    >>> print output.getvalue()
    true
    <BLANKLINE>

    >>> output = StringIO()
    >>> run(input=StringIO('["add_fun", "def fun(doc): yield None, doc"]\n'),
    ...     output=output)
    >>> print output.getvalue()
    true
    <BLANKLINE>

    >>> output = StringIO()
    >>> run(input=StringIO('["add_fun", "def fun(doc): yield None, doc"]\n'
    ...                    '["map_doc", {"foo": "bar"}]\n'),
    ...     output=output)
    >>> print output.getvalue()
    true
    [[[null, {"foo": "bar"}]]]
    <BLANKLINE>

    :param input: the readable file-like object to read input from
    :param output: the writable file-like object to write output to
    """
    functions = []

    def reset():
        del functions[:]
        return True

    def add_fun(string):
        string = '\xef\xbb\xbf' + string.encode('utf-8')
        globals_ = {}
        try:
            exec string in {}, globals_
        except Exception, e:
            return {'error': {'id': 'map_compilation_error', 'reason': e.args[0]}}
        err = {'error': {
            'id': 'map_compilation_error',
            'reason': 'string must eval to a function (ex: "def(doc): return 1")'
        }}
        if len(globals_) != 1:
            return err
        function = globals_.values()[0]
        if type(function) is not FunctionType:
            return err
        functions.append(function)
        return True

    def map_doc(doc):
        results = []
        for function in functions:
            try:
                results.append([[key, value] for key, value in function(doc)])
            except Exception, e:
                results.append([])
                output.write(json.dumps({'log': e.args[0]}))
        return results

    handlers = {'reset': reset, 'add_fun': add_fun, 'map_doc': map_doc}

    try:
        while True:
            line = input.readline()
            if not line:
                break
            try:
                cmd = json.loads(line)
            except ValueError, e:
                sys.stderr.write('error: %s\n' % e)
                sys.stderr.flush()
                return 1
            else:
                retval = handlers[cmd[0]](*cmd[1:])
                output.write(json.dumps(retval))
                output.write('\n')
                output.flush()
    except KeyboardInterrupt:
        return 0

_VERSION = """%(name)s - CouchDB Python %(version)s

Copyright (C) 2007 Christopher Lenz <cmlenz@gmx.de>.
"""
_HELP = """Usage: %(name)s [OPTION]

The %(name)s command runs the CouchDB Python view server.

The exit status is 0 for success or 1 for failure.

Options:

  --version          display version information and exit
  -h, --help         display a short help message and exit

Report bugs via the web at <http://code.google.com/p/couchdb-python>.
"""

def main():
    """Command-line entry point for running the view server."""
    import getopt
    from couchdb import __version__ as VERSION
    try:
        option_list, argument_list = getopt.gnu_getopt(
            sys.argv[1:], 'h', ['version', 'help'])
        message = None
        for option, value in option_list:
            if option in ('--version'):
                message = _VERSION % dict(name=os.path.basename(sys.argv[0]),
                                      version=VERSION)
            elif option in ('-h', '--help'):
                message = _HELP % dict(name=os.path.basename(sys.argv[0]))
        if message:
            sys.stdout.write(message)
            sys.stdout.flush()
            sys.exit(0)
    except getopt.GetoptError, error:
        message = '%s\n\nTry `%s --help` for more information.\n' % (
            str(error), os.path.basename(sys.argv[0])
        )
        sys.stderr.write(message)
        sys.stderr.flush()
        sys.exit(1)
    sys.exit(run())

if __name__ == '__main__':
    main()
<|endoftext|>