]> jfr.im git - yt-dlp.git/commitdiff
[update] Self-restart after update
authorpukkandan <redacted>
Tue, 21 Jun 2022 11:18:32 +0000 (16:48 +0530)
committerpukkandan <redacted>
Tue, 21 Jun 2022 11:32:57 +0000 (17:02 +0530)
yt_dlp/__init__.py
yt_dlp/update.py

index 1cd14a44d5ce837934d1fe1e4e30364bf4a2ec13..db77ee39be2f5be70914133f5f7ae44915bc51d0 100644 (file)
@@ -26,7 +26,7 @@
     MetadataFromFieldPP,
     MetadataParserPP,
 )
-from .update import run_update
+from .update import Updater
 from .utils import (
     NO_DEFAULT,
     POSTPROCESS_WHEN,
@@ -879,17 +879,23 @@ def _real_main(argv=None):
         return
 
     with YoutubeDL(ydl_opts) as ydl:
+        pre_process = opts.update_self or opts.rm_cachedir
         actual_use = all_urls or opts.load_info_filename
 
         if opts.rm_cachedir:
             ydl.cache.remove()
 
-        if opts.update_self and run_update(ydl) and actual_use:
-            # If updater returns True, exit. Required for windows
-            return 100, 'ERROR: The program must exit for the update to complete'
+        updater = Updater(ydl)
+        if opts.update_self and updater.update() and actual_use:
+            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 opts.update_self or opts.rm_cachedir:
+            if pre_process:
                 return ydl._download_retcode
 
             ydl.warn_if_short_id(sys.argv[1:] if argv is None else argv)
index 68418ce981738f72002281edbb08dde59afbc411..f4ce4f9587f491e2787c5efdb07c76ec273c280f 100644 (file)
@@ -1,3 +1,4 @@
+import atexit
 import hashlib
 import json
 import os
@@ -8,7 +9,7 @@
 
 from .compat import functools  # isort: split
 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__
 
 REPOSITORY = 'yt-dlp/yt-dlp'
@@ -206,17 +207,28 @@ def update(self):
         if detect_variant() not in ('win32_exe', 'py2exe'):
             if 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')
-            return
+        else:
+            atexit.register(Popen, f'ping 127.0.0.1 -n 5 -w 1000 & del /F "{old_filename}"',
+                            shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
 
-        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)
-            self.ydl.to_screen(f'Updated yt-dlp to version {self.new_version}')
-            return True  # Exit app
-        except OSError:
-            self._report_unable('delete the old version')
+        self.ydl.to_screen(f'Updated yt-dlp to version {self.new_version}')
+        return True
+
+    @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):