# coding=utf-8
"""
A terminal command executor module
"""
__author__ = 'Alisue <lambdalisue@hashnote.net>'
import sys
import subprocess
from notify.compat import StringIO

if sys.version_info >= (3, 0):
    # i'm not sure the encoding should be utf-8 or not
    force_unicode = lambda x: str(x, 'utf-8')
else:
    force_unicode = unicode

def call(args):
    """
    Call terminal command and return exit_code and stdout

    Parameters
    ----------
    args : list
        A command and arguments list

    Returns
    -------
    list : [exit_code, stdout]
        exit_code indicate the exit code of the command and stdout indicate the
        output of the command
    """
    b = StringIO()
    p = subprocess.Popen(args,
                        stdout=subprocess.PIPE,
                        stderr=subprocess.STDOUT)
    # old python has bug in p.stdout, so the following little
    # hack is required.
    for stdout in iter(p.stdout.readline, ''):
        if len(stdout) == 0:
            break
        stdout = force_unicode(stdout)
        b.write(stdout)
        sys.stdout.write(stdout)
        sys.stdout.flush()
    buf = b.getvalue()
    p.stdout.close()
    return p.returncode or 0, buf

def get_command_str(args):
    """
    Get terminal command string from list of command and arguments

    Parameters
    ----------
    args : list
        A command and arguments list

    Returns
    -------
    str
        A string indicate terminal command
    """
    single_quote = "'"
    double_quote = '"'
    for i, value in enumerate(args):
        if " " in value and double_quote not in value:
            args[i] = '"%s"' % value
        elif " " in value and single_quote not in value:
            args[i] = "'%s'" % value
    return " ".join(args)

@@ -303,24 +303,28 @@
 )%0Aelse:%0A    
+def 
 force_unicod
@@ -328,18 +328,2382 @@
 code
- = unicode
+(s, encoding='utf-8', strings_only=False, errors='strict'):%0A        %22%22%22%0A        Similar to smart_unicode, except that lazy instances are resolved to%0A        strings, rather than kept as lazy objects.%0A%0A        If strings_only is True, don't convert (some) non-string-like objects.%0A        %22%22%22%0A        # Handle the common case first, saves 30-40%25 in performance when s%0A        # is an instance of unicode. This function gets called often in that%0A        # setting.%0A        if isinstance(s, unicode):%0A            return s%0A        try:%0A            if not isinstance(s, basestring,):%0A                if hasattr(s, '__unicode__'):%0A                    s = unicode(s)%0A                else:%0A                    try:%0A                        s = unicode(str(s), encoding, errors)%0A                    except UnicodeEncodeError:%0A                        if not isinstance(s, Exception):%0A                            raise%0A                        # If we get to here, the caller has passed in an Exception%0A                        # subclass populated with non-ASCII data without special%0A                        # handling to display as a string. We need to handle this%0A                        # without raising a further exception. We do an%0A                        # approximation to what the Exception's standard str()%0A                        # output should be.%0A                        s = ' '.join(%5Bforce_unicode(arg, encoding, strings_only,%0A                                errors) for arg in s%5D)%0A            elif not isinstance(s, unicode):%0A                # Note: We use .decode() here, instead of unicode(s, encoding,%0A                # errors), so that if s is a SafeString, it ends up being a%0A                # SafeUnicode at the end.%0A                s = s.decode(encoding, errors)%0A        except UnicodeDecodeError, e:%0A            if not isinstance(s, Exception):%0A                raise %0A            else:%0A                # If we get to here, the caller has passed in an Exception%0A                # subclass populated with non-ASCII bytestring data without a%0A                # working unicode method. Try to handle this without raising a%0A                # further exception by individually forcing the exception args%0A                # to unicode.%0A                s = ' '.join(%5Bforce_unicode(arg, encoding, strings_only,%0A                        errors) for arg in s%5D)%0A        return s
 %0A%0Ade

Add django force_unicode method