mirror of
				https://gitlab.com/ytdl-org/youtube-dl.git
				synced 2025-11-03 23:07:07 -05:00 
			
		
		
		
	[utils] Completely rewrite Windows output (Fixes #2672)
This commit is contained in:
		@@ -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."""
 | 
			
		||||
 
 | 
			
		||||
@@ -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')
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user