From 5d673555433988dace4cce49b3ab2ee4e43374eb Mon Sep 17 00:00:00 2001 From: kikuyan Date: Mon, 28 Jun 2021 11:39:31 +0900 Subject: [PATCH 1/4] [YoutubeDL] restore macos terminal window title for --console-title --- youtube_dl/YoutubeDL.py | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/youtube_dl/YoutubeDL.py b/youtube_dl/YoutubeDL.py index fe30758ef..cf15c47ea 100755 --- a/youtube_dl/YoutubeDL.py +++ b/youtube_dl/YoutubeDL.py @@ -32,6 +32,7 @@ from .compat import ( compat_basestring, compat_cookiejar, compat_get_terminal_size, + compat_getenv, compat_http_client, compat_kwargs, compat_numeric_types, @@ -53,6 +54,7 @@ from .utils import ( determine_protocol, DownloadError, encode_compat_str, + encodeArgument, encodeFilename, error_to_compat_str, expand_path, @@ -355,6 +357,7 @@ class YoutubeDL(object): self._num_downloads = 0 self._screen_file = [sys.stdout, sys.stderr][params.get('logtostderr', False)] self._err_file = sys.stderr + self._apple_terminal = None self.params = { # Default parameters 'nocheckcertificate': False, @@ -546,8 +549,29 @@ class YoutubeDL(object): if self.params.get('simulate', False): return if compat_os_name != 'nt' and 'TERM' in os.environ: - # Save the title on stack - self._write_string('\033[22;0t', self._screen_file) + if not (sys.platform == 'darwin' and compat_getenv('TERM_PROGRAM') == 'Apple_Terminal'): + # Save the title on stack + self._write_string('\033[22;0t', self._screen_file) + else: + # macOS Terminal app + window_title = None + try: + ttyname = os.ttyname(self._screen_file.fileno()) + opts = ['-e', 'tell app "Terminal" to get custom title of item 1 of (every window whose tty is "%s")' % ttyname] + cmd = ([encodeFilename('osascript', True)] + + [encodeArgument(o) for o in opts]) + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = p.communicate() + if p.returncode == 0: + window_title = stdout.decode('utf-8').strip() + except EnvironmentError: + pass + if window_title is None or window_title and preferredencoding() != 'UTF-8': + self.report_warning('Window title may not be restored correctly') + if window_title is None: + self._apple_terminal = '' # reset on restore anyway + else: + self._apple_terminal = window_title def restore_console_title(self): if not self.params.get('consoletitle', False): @@ -555,8 +579,11 @@ class YoutubeDL(object): if self.params.get('simulate', False): return if compat_os_name != 'nt' and 'TERM' in os.environ: - # Restore the title from stack - self._write_string('\033[23;0t', self._screen_file) + if self._apple_terminal is None: + # Restore the title from stack + self._write_string('\033[23;0t', self._screen_file) + else: + self._write_string('\033]0;%s\007' % self._apple_terminal, self._screen_file) def __enter__(self): self.save_console_title() From 43eef1dcd89b5e2c54d2a0f5eac905bc597cddeb Mon Sep 17 00:00:00 2001 From: kikuyan Date: Wed, 30 Jun 2021 15:18:44 +0900 Subject: [PATCH 2/4] avoid phantom windows in osascript --- youtube_dl/YoutubeDL.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/youtube_dl/YoutubeDL.py b/youtube_dl/YoutubeDL.py index cf15c47ea..7184f89e3 100755 --- a/youtube_dl/YoutubeDL.py +++ b/youtube_dl/YoutubeDL.py @@ -557,7 +557,18 @@ class YoutubeDL(object): window_title = None try: ttyname = os.ttyname(self._screen_file.fileno()) - opts = ['-e', 'tell app "Terminal" to get custom title of item 1 of (every window whose tty is "%s")' % ttyname] + scpt = [ + 'tell app "Terminal"', + 'repeat with win in (every window)', + 'if tty of win is "%s" then' % ttyname, + 'return custom title of win', + 'end if', + 'end repeat', + 'end tell' + ] + opts = [] + for s in scpt: + opts += ['-e', s] cmd = ([encodeFilename('osascript', True)] + [encodeArgument(o) for o in opts]) p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) From a3da97129e7565727c34fa7111837c478d6cf9c4 Mon Sep 17 00:00:00 2001 From: kikuyan Date: Wed, 30 Jun 2021 16:58:25 +0900 Subject: [PATCH 3/4] [YoutubeDL] improve --console-title output to go to tty --- youtube_dl/YoutubeDL.py | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/youtube_dl/YoutubeDL.py b/youtube_dl/YoutubeDL.py index 7184f89e3..c09af2cec 100755 --- a/youtube_dl/YoutubeDL.py +++ b/youtube_dl/YoutubeDL.py @@ -357,6 +357,7 @@ class YoutubeDL(object): self._num_downloads = 0 self._screen_file = [sys.stdout, sys.stderr][params.get('logtostderr', False)] self._err_file = sys.stderr + self._tty_file = None # for --console-title self._apple_terminal = None self.params = { # Default parameters @@ -422,6 +423,17 @@ class YoutubeDL(object): 'Parameter outtmpl is bytes, but should be a unicode string. ' 'Put from __future__ import unicode_literals at the top of your code file or consider switching to Python 3.x.') + if (self.params.get('consoletitle', False) + and not self.params.get('simulate', False) + and compat_os_name != 'nt' and 'TERM' in os.environ): + if self._screen_file.isatty(): + self._tty_file = self._screen_file + elif self._err_file != self._screen_file and self._err_file.isatty(): + self._tty_file = self._err_file + else: + self.report_warning('Could not find a tty for output, ignoring --console-title. Either stdout or stderr must be a tty.') + self.params['consoletitle'] = False + self._setup_opener() if auto_init: @@ -541,7 +553,7 @@ class YoutubeDL(object): # already of type unicode() ctypes.windll.kernel32.SetConsoleTitleW(ctypes.c_wchar_p(message)) elif 'TERM' in os.environ: - self._write_string('\033]0;%s\007' % message, self._screen_file) + self._write_string('\033]0;%s\007' % message, self._tty_file) def save_console_title(self): if not self.params.get('consoletitle', False): @@ -551,12 +563,12 @@ class YoutubeDL(object): if compat_os_name != 'nt' and 'TERM' in os.environ: if not (sys.platform == 'darwin' and compat_getenv('TERM_PROGRAM') == 'Apple_Terminal'): # Save the title on stack - self._write_string('\033[22;0t', self._screen_file) + self._write_string('\033[22;0t', self._tty_file) else: # macOS Terminal app window_title = None try: - ttyname = os.ttyname(self._screen_file.fileno()) + ttyname = os.ttyname(self._tty_file.fileno()) scpt = [ 'tell app "Terminal"', 'repeat with win in (every window)', @@ -592,9 +604,9 @@ class YoutubeDL(object): if compat_os_name != 'nt' and 'TERM' in os.environ: if self._apple_terminal is None: # Restore the title from stack - self._write_string('\033[23;0t', self._screen_file) + self._write_string('\033[23;0t', self._tty_file) else: - self._write_string('\033]0;%s\007' % self._apple_terminal, self._screen_file) + self._write_string('\033]0;%s\007' % self._apple_terminal, self._tty_file) def __enter__(self): self.save_console_title() From f95c9ddad1ae5b2f0bc2e07dc768b2c6a97d525f Mon Sep 17 00:00:00 2001 From: kikuyan Date: Thu, 1 Jul 2021 08:20:33 +0900 Subject: [PATCH 4/4] feed script to osascript from stdin --- youtube_dl/YoutubeDL.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/youtube_dl/YoutubeDL.py b/youtube_dl/YoutubeDL.py index c09af2cec..8867a3ada 100755 --- a/youtube_dl/YoutubeDL.py +++ b/youtube_dl/YoutubeDL.py @@ -578,13 +578,10 @@ class YoutubeDL(object): 'end repeat', 'end tell' ] - opts = [] - for s in scpt: - opts += ['-e', s] - cmd = ([encodeFilename('osascript', True)] - + [encodeArgument(o) for o in opts]) - p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - stdout, stderr = p.communicate() + scpt = '\n'.join(scpt).encode('utf-8') + cmd = [encodeFilename('osascript', True), encodeArgument('-')] + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) + stdout, stderr = p.communicate(input=scpt) if p.returncode == 0: window_title = stdout.decode('utf-8').strip() except EnvironmentError: