[update] Self-restart after update

This commit is contained in:
pukkandan 2022-06-21 16:48:32 +05:30
parent 57e0f077a6
commit 8372be7469
No known key found for this signature in database
GPG key ID: 7EEE9E1E817D0A39
2 changed files with 34 additions and 16 deletions

View file

@ -26,7 +26,7 @@ from .postprocessor import (
MetadataFromFieldPP, MetadataFromFieldPP,
MetadataParserPP, MetadataParserPP,
) )
from .update import run_update from .update import Updater
from .utils import ( from .utils import (
NO_DEFAULT, NO_DEFAULT,
POSTPROCESS_WHEN, POSTPROCESS_WHEN,
@ -879,17 +879,23 @@ def _real_main(argv=None):
return return
with YoutubeDL(ydl_opts) as ydl: with YoutubeDL(ydl_opts) as ydl:
pre_process = opts.update_self or opts.rm_cachedir
actual_use = all_urls or opts.load_info_filename actual_use = all_urls or opts.load_info_filename
if opts.rm_cachedir: if opts.rm_cachedir:
ydl.cache.remove() ydl.cache.remove()
if opts.update_self and run_update(ydl) and actual_use: updater = Updater(ydl)
# If updater returns True, exit. Required for windows if opts.update_self and updater.update() and actual_use:
return 100, 'ERROR: The program must exit for the update to complete' if updater.cmd:
return updater.restart()
# This code is reachable only for zip variant in py < 3.10
# It makes sense to exit here, but the old behavior is to continue
ydl.report_warning('Restart yt-dlp to use the updated version')
# return 100, 'ERROR: The program must exit for the update to complete'
if not actual_use: if not actual_use:
if opts.update_self or opts.rm_cachedir: if pre_process:
return ydl._download_retcode return ydl._download_retcode
ydl.warn_if_short_id(sys.argv[1:] if argv is None else argv) ydl.warn_if_short_id(sys.argv[1:] if argv is None else argv)

View file

@ -1,3 +1,4 @@
import atexit
import hashlib import hashlib
import json import json
import os import os
@ -8,7 +9,7 @@ from zipimport import zipimporter
from .compat import functools # isort: split from .compat import functools # isort: split
from .compat import compat_realpath from .compat import compat_realpath
from .utils import Popen, traverse_obj, version_tuple from .utils import Popen, shell_quote, traverse_obj, version_tuple
from .version import __version__ from .version import __version__
REPOSITORY = 'yt-dlp/yt-dlp' REPOSITORY = 'yt-dlp/yt-dlp'
@ -206,17 +207,28 @@ class Updater:
if detect_variant() not in ('win32_exe', 'py2exe'): if detect_variant() not in ('win32_exe', 'py2exe'):
if old_filename: if old_filename:
os.remove(old_filename) os.remove(old_filename)
self.ydl.to_screen(f'Updated yt-dlp to version {self.new_version}; Restart yt-dlp to use the new version') else:
return atexit.register(Popen, f'ping 127.0.0.1 -n 5 -w 1000 & del /F "{old_filename}"',
try:
# Continues to run in the background
Popen(f'ping 127.0.0.1 -n 5 -w 1000 & del /F "{old_filename}"',
shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
self.ydl.to_screen(f'Updated yt-dlp to version {self.new_version}') self.ydl.to_screen(f'Updated yt-dlp to version {self.new_version}')
return True # Exit app return True
except OSError:
self._report_unable('delete the old version') @functools.cached_property
def cmd(self):
"""The command-line to run the executable, if known"""
# There is no sys.orig_argv in py < 3.10. Also, it can be [] when frozen
if getattr(sys, 'orig_argv', None):
return sys.orig_argv
elif hasattr(sys, 'frozen'):
return sys.argv
def restart(self):
"""Restart the executable"""
assert self.cmd, 'Must be frozen or Py >= 3.10'
self.ydl.write_debug(f'Restarting: {shell_quote(self.cmd)}')
_, _, returncode = Popen.run(self.cmd)
return returncode
def run_update(ydl): def run_update(ydl):