import types
import fcntl
import os

class PidFile(object):
    """Context manager that locks a pid file."""
    def __init__(self, path):
        self.path = path
        self.pidfile = None

    def close(self):
        pidfile = self.pidfile
        self.pidfile = None
        pidfile.close()

    def __enter__(self):
        self.pidfile = open(self.path, "a+")
        fcntl.flock(self.pidfile.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
        self.pidfile.seek(0)
        self.pidfile.truncate()
        self.pidfile.write(str(os.getpid()))
        self.pidfile.flush()
        self.pidfile.seek(0)
        return self.pidfile

    def __exit__(self, exc_type=None, exc_value=None, exc_tb=None):
        if self.pidfile:
            self.pidfile.close()
            os.remove(self.path)

# compatibility later for swifclient < 2.7.0
def smart_unicode(s, encoding='utf-8'):
    if isinstance(s, unicode):
        return s
    else:
        return unicode(s, encoding)

#from django.utils
def smart_str(s, encoding='utf-8', strings_only=False, errors='strict'):
    if strings_only and isinstance(s, (types.NoneType, int)):
        return s
    elif not isinstance(s, basestring):
        try:
            return str(s)
        except UnicodeEncodeError:
            if isinstance(s, Exception):
                return ' '.join([smart_str(arg, encoding, strings_only,
                        errors) for arg in s])
            return unicode(s).encode(encoding, errors)
    elif isinstance(s, unicode):
        return s.encode(encoding, errors)
    elif s and encoding != 'utf-8':
        return s.decode('utf-8', errors).encode(encoding, errors)
    else:
        return s

