diff options
| -rw-r--r-- | youtube_dl/YoutubeDL.py | 2 | ||||
| -rw-r--r-- | youtube_dl/utils.py | 60 | 
2 files changed, 61 insertions, 1 deletions
diff --git a/youtube_dl/YoutubeDL.py b/youtube_dl/YoutubeDL.py index d011ddeb5..bd7497f85 100644 --- a/youtube_dl/YoutubeDL.py +++ b/youtube_dl/YoutubeDL.py @@ -287,7 +287,7 @@ class YoutubeDL(object):          return self.to_stdout(message, skip_eol, check_quiet=True)      def _write_string(self, s, out=None): -        write_string(s, out=out, encoding=self.get_encoding()) +        write_string(s, out=out, encoding=self.params.get('encoding'))      def to_stdout(self, message, skip_eol=False, check_quiet=False):          """Print message to stdout if not in quiet mode.""" diff --git a/youtube_dl/utils.py b/youtube_dl/utils.py index 68424aeb6..b57fd7a33 100644 --- a/youtube_dl/utils.py +++ b/youtube_dl/utils.py @@ -910,11 +910,71 @@ def platform_name():      return res +def _windows_write_string(s, out): +    """ Returns True if the string was written using special methods, +    False if it has yet to be written out.""" +    # Adapted from http://stackoverflow.com/a/3259271/35070 + +    import ctypes +    import ctypes.wintypes + +    WIN_OUTPUT_IDS = { +        1: -11, +        2: -12, +    } + +    fileno = out.fileno() +    if fileno not in WIN_OUTPUT_IDS: +        return False + +    GetStdHandle = ctypes.WINFUNCTYPE( +        ctypes.wintypes.HANDLE, ctypes.wintypes.DWORD)( +        ("GetStdHandle", ctypes.windll.kernel32)) +    h = GetStdHandle(WIN_OUTPUT_IDS[fileno]) + +    WriteConsoleW = ctypes.WINFUNCTYPE( +        ctypes.wintypes.BOOL, ctypes.wintypes.HANDLE, ctypes.wintypes.LPWSTR, +        ctypes.wintypes.DWORD, ctypes.POINTER(ctypes.wintypes.DWORD), +        ctypes.wintypes.LPVOID)(("WriteConsoleW", ctypes.windll.kernel32)) +    written = ctypes.wintypes.DWORD(0) + +    GetFileType = ctypes.WINFUNCTYPE(ctypes.wintypes.DWORD, ctypes.wintypes.DWORD)(("GetFileType", ctypes.windll.kernel32)) +    FILE_TYPE_CHAR = 0x0002 +    FILE_TYPE_REMOTE = 0x8000 +    GetConsoleMode = ctypes.WINFUNCTYPE( +        ctypes.wintypes.BOOL, ctypes.wintypes.HANDLE, +        ctypes.POINTER(ctypes.wintypes.DWORD))( +        ("GetConsoleMode", ctypes.windll.kernel32)) +    INVALID_HANDLE_VALUE = ctypes.wintypes.DWORD(-1).value + +    def not_a_console(handle): +        if handle == INVALID_HANDLE_VALUE or handle is None: +            return True +        return ((GetFileType(handle) & ~FILE_TYPE_REMOTE) != FILE_TYPE_CHAR +                or GetConsoleMode(handle, ctypes.byref(ctypes.wintypes.DWORD())) == 0) + +    if not_a_console(h): +        return False + +    remaining = len(s) +    while remaining > 0: +        ret = WriteConsoleW( +            h, s, min(len(s), 1024), ctypes.byref(written), None) +        if ret == 0: +            raise OSError('Failed to write string') +        remaining -= written.value +    return True + +  def write_string(s, out=None, encoding=None):      if out is None:          out = sys.stderr      assert type(s) == compat_str +    if sys.platform == 'win32' and encoding is None and hasattr(out, 'fileno'): +        if _windows_write_string(s, out): +            return +      if ('b' in getattr(out, 'mode', '') or              sys.version_info[0] < 3):  # Python 2 lies about mode of sys.stderr          byt = s.encode(encoding or preferredencoding(), 'ignore')  | 
