from argparse import Namespace
from contextlib import contextmanager
from pkg_resources import get_distribution, DistributionNotFound
import errno
import logging
import os
from random import SystemRandom
import string

import yaml

from ._compat import which


import_module = __import__

logger = logging.getLogger('passpie')
handler = logging.StreamHandler()
formatter = logging.Formatter(
    '%(name)s::%(levelname)s::%(module)s::%(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)


def genpass(length=32, special="_-#|+="):
    """generates a password with random chararcters
    """
    chars = special + string.ascii_letters + string.digits + " "
    return "".join(SystemRandom().choice(chars) for _ in range(length))


@contextmanager
def mkdir_open(path, mode="r"):
    try:
        dir_path = os.path.dirname(path)
        os.makedirs(dir_path)
    except OSError as exc:
        if exc.errno == errno.EEXIST and os.path.isdir(dir_path):
            pass
        else:
            raise
    with open(path, mode) as fd:
        yield fd


def get_version():
    try:
        _dist = get_distribution('passpie')
        dist_loc = os.path.normcase(_dist.location)
        here = os.path.normcase(__file__)
        if not here.startswith(os.path.join(dist_loc, 'passpie')):
            raise DistributionNotFound
    except DistributionNotFound:
        return 'Please install this project with setup.py or pip'
    else:
        return _dist.version


def load_config(default_config, user_config_path):
    try:
        with open(user_config_path) as config_file:
            config_content = config_file.read()
    except IOError as e:
        logging.debug('Not a valid path for config {}'.format(e))
        return Namespace(**default_config)

    try:
        user_config = yaml.load(config_content)
        default_config.update(user_config)
    except yaml.scanner.ScannerError as e:
        logging.debug('Malformed user configuration file {}'.format(e))
        return Namespace(**default_config)

    config = Namespace(**default_config)
    return config


def ensure_dependencies():
    try:
        assert which('gpg') or which('gpg2')
    except AssertionError:
        raise RuntimeError('GnuPG not installed. https://www.gnupg.org/')


def reverse_enumerate(seq):
    return [e for e in zip(reversed(range(len(list(seq)))), list(seq))]

@@ -62,16 +62,44 @@
 manager%0A
+from functools import wraps%0A
 from pkg
@@ -155,16 +155,48 @@
 otFound%0A
+from random import SystemRandom%0A
 import e
@@ -229,53 +229,51 @@
  os%0A
-from random import SystemRandom%0Aimport string
+import shutil%0Aimport string%0Aimport tempfile
 %0A%0Aim
@@ -2434,8 +2434,399 @@
 (seq))%5D%0A
+%0A%0A@contextmanager%0Adef tempdir():%0A    path = tempfile.mkdtemp()%0A    yield path%0A    if os.path.exists(path):%0A        shutil.rmtree(path)%0A%0A%0Adef logged(func):%0A    @wraps(func)%0A    def wrapper(*args, **kwargs):%0A        text = '%7B%7D called with args: %7B%7D, kwargs: %7B%7D'.format(%0A            func.__name__, args, kwargs)%0A        logger.debug(text)%0A        return func(*args, **kwargs)%0A    return wrapper%0A

Add tempdir context manager to utils