Browse Source

Use basic restart for Windows binaries

Python 3.9 changed the output of Py_GetArgcArgv on Windows, causing the restart of the binaries to fail.
pull/1763/head
Safihre 4 years ago
parent
commit
ae30f89a2d
  1. 27
      SABnzbd.py
  2. 13
      sabnzbd/misc.py
  3. 11
      sabnzbd/newsunpack.py
  4. 16
      tests/test_misc.py
  5. 16
      tests/test_newsunpack.py

27
SABnzbd.py

@ -1555,31 +1555,34 @@ def main():
# Or special restart cases like Mac and WindowsService
if sabnzbd.TRIGGER_RESTART:
logging.info("Performing triggered restart")
# Shutdown
sabnzbd.shutdown_program()
# Add arguments and make sure we are in the right directory
if sabnzbd.Downloader.paused:
sabnzbd.RESTART_ARGS.append("-p")
if autorestarted:
sabnzbd.RESTART_ARGS.append("--autorestarted")
sys.argv = sabnzbd.RESTART_ARGS
os.chdir(org_dir)
# If macOS frozen restart of app instead of embedded python
if hasattr(sys, "frozen") and sabnzbd.DARWIN:
# [[NSProcessInfo processInfo] processIdentifier]]
# logging.info("%s" % (NSProcessInfo.processInfo().processIdentifier()))
my_pid = os.getpid()
my_name = sabnzbd.MY_FULLNAME.replace("/Contents/MacOS/SABnzbd", "")
my_args = " ".join(sys.argv[1:])
cmd = 'kill -9 %s && open "%s" --args %s' % (my_pid, my_name, my_args)
logging.info("Launching: %s", cmd)
os.system(cmd)
# Binaries require special restart
if hasattr(sys, "frozen"):
if sabnzbd.DARWIN:
# On macOS restart of app instead of embedded python
my_name = sabnzbd.MY_FULLNAME.replace("/Contents/MacOS/SABnzbd", "")
my_args = " ".join(sys.argv[1:])
cmd = 'kill -9 %s && open "%s" --args %s' % (os.getpid(), my_name, my_args)
logging.info("Launching: %s", cmd)
os.system(cmd)
elif sabnzbd.WIN32:
# Just a simple restart of the exe
os.execv(sys.executable, ['"%s"' % arg for arg in sys.argv])
elif sabnzbd.WIN_SERVICE:
# Use external service handler to do the restart
# Wait 5 seconds to clean up
subprocess.Popen("timeout 5 & sc start SABnzbd", shell=True)
else:
# CherryPy has special logic to include interpreter options such as "-OO"
cherrypy.engine._do_execv()
# Send our final goodbyes!

13
sabnzbd/misc.py

@ -963,6 +963,17 @@ def nntp_to_msg(text: Union[List[AnyStr], str]) -> str:
return ubtou(lines[0])
def list2cmdline(lst: List[str]) -> str:
""" convert list to a cmd.exe-compatible command string """
nlst = []
for arg in lst:
if not arg:
nlst.append('""')
else:
nlst.append('"%s"' % arg)
return " ".join(nlst)
def build_and_run_command(command: List[str], flatten_command=False, **kwargs):
"""Builds and then runs command with nessecary flags and optional
IONice and Nice commands. Optional Popen arguments can be supplied.
@ -1000,7 +1011,7 @@ def build_and_run_command(command: List[str], flatten_command=False, **kwargs):
if command[0].endswith(".py"):
command.insert(0, "python.exe")
if flatten_command:
command = sabnzbd.newsunpack.list2cmdline(command)
command = list2cmdline(command)
# On some Windows platforms we need to supress a quick pop-up of the command window
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags = win32process.STARTF_USESHOWWINDOW

11
sabnzbd/newsunpack.py

@ -2367,17 +2367,6 @@ def pre_queue(nzo: NzbObject, pp, cat):
return values
def list2cmdline(lst):
""" convert list to a cmd.exe-compatible command string """
nlst = []
for arg in lst:
if not arg:
nlst.append('""')
else:
nlst.append('"%s"' % arg)
return " ".join(nlst)
def is_sevenfile(path):
""" Return True if path has proper extension and 7Zip is installed """
return SEVEN_COMMAND and os.path.splitext(path)[1].lower() == ".7z"

16
tests/test_misc.py

@ -214,6 +214,22 @@ class TestMisc:
os.unlink("test.cert")
os.unlink("test.key")
@pytest.mark.parametrize(
"test_input, expected_output",
[
(["cmd1", 9, "cmd3"], '"cmd1" "9" "cmd3"'), # sending all commands as valid string
(["", "cmd1", "5"], '"" "cmd1" "5"'), # sending blank string
(["cmd1", None, "cmd3", "tail -f"], '"cmd1" "" "cmd3" "tail -f"'), # sending None in command
(["cmd1", 0, "ps ux"], '"cmd1" "" "ps ux"'), # sending 0
],
)
def test_list_to_cmd(self, test_input, expected_output):
""" Test to convert list to a cmd.exe-compatible command string """
res = misc.list2cmdline(test_input)
# Make sure the output is cmd.exe-compatible
assert res == expected_output
class TestBuildAndRunCommand:
# Path should exist

16
tests/test_newsunpack.py

@ -25,22 +25,6 @@ from sabnzbd.newsunpack import *
class TestNewsUnpack:
@pytest.mark.parametrize(
"test_input, expected_output",
[
(["cmd1", 9, "cmd3"], '"cmd1" "9" "cmd3"'), # sending all commands as valid string
(["", "cmd1", "5"], '"" "cmd1" "5"'), # sending blank string
(["cmd1", None, "cmd3", "tail -f"], '"cmd1" "" "cmd3" "tail -f"'), # sending None in command
(["cmd1", 0, "ps ux"], '"cmd1" "" "ps ux"'), # sending 0
],
)
def test_list_to_cmd(self, test_input, expected_output):
""" Test to convert list to a cmd.exe-compatible command string """
res = list2cmdline(test_input)
# Make sure the output is cmd.exe-compatible
assert res == expected_output
def test_is_sfv_file(self):
assert is_sfv_file("tests/data/good_sfv_unicode.sfv")
assert is_sfv_file("tests/data/one_line.sfv")

Loading…
Cancel
Save