Build Windows client console exe (#450) (#631)

* Add Utils support for Windows console

* Avoid GraphicalUI if Windows Console

* Don't show GuiConfig for EXE console

* Add enter-to-exit prompt when EXE console is missing args

* Build syncplayConsole EXE

* Fix isWindowsConsole() check

* Limit stderr->blackhole code to Windows client console EXEs
This commit is contained in:
Etoh 2023-10-11 22:12:38 +01:00 committed by GitHub
parent 7456a940fa
commit 20846ca78c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 36 additions and 10 deletions

View File

@ -673,9 +673,7 @@ info = dict(
"icon_resources": [(1, "syncplay\\resources\\icon.ico")], "icon_resources": [(1, "syncplay\\resources\\icon.ico")],
'dest_base': "Syncplay"}, 'dest_base': "Syncplay"},
], ],
console=['syncplayServer.py'], console=['syncplayServer.py', {"script":"syncplayClient.py", "icon_resources":[(1, "syncplay\\resources\\icon.ico")], 'dest_base': "SyncplayConsole"}],
# *** If you wish to make the Syncplay client use console mode (for --no-gui to work) then comment out the above two lines and uncomment the following line:
# console=['syncplayServer.py', {"script":"syncplayClient.py", "icon_resources":[(1, "resources\\icon.ico")], 'dest_base': "Syncplay"}],
options={ options={
'py2exe': { 'py2exe': {

View File

@ -408,10 +408,12 @@ class ConfigurationGetter(object):
sys.exit() sys.exit()
def _promptForMissingArguments(self, error=None): def _promptForMissingArguments(self, error=None):
if self._config['noGui']: if self._config['noGui'] or utils.isWindowsConsole():
if error: if error:
print("{}!".format(error)) print("{}!".format(error))
print(getMessage("missing-arguments-error")) print(getMessage("missing-arguments-error"))
if utils.isWindowsConsole():
input(getMessage("enter-to-exit-prompt"))
sys.exit() sys.exit()
else: else:
from syncplay.ui.GuiConfiguration import GuiConfiguration from syncplay.ui.GuiConfiguration import GuiConfiguration
@ -550,7 +552,7 @@ class ConfigurationGetter(object):
# Arguments not validated yet - booleans are still text values # Arguments not validated yet - booleans are still text values
if self._config['language']: if self._config['language']:
setLanguage(self._config['language']) setLanguage(self._config['language'])
if (self._config['forceGuiPrompt'] == "True" or not self._config['file']) and not self._config['noGui']: if (self._config['forceGuiPrompt'] == "True" or not self._config['file']) and not self._config['noGui'] and not utils.isWindowsConsole():
self._forceGuiPrompt() self._forceGuiPrompt()
self._checkConfig() self._checkConfig()
self._saveConfig(iniPath) self._saveConfig(iniPath)

View File

@ -1,10 +1,12 @@
import os import os
from syncplay.utils import isWindowsConsole
if "QT_PREFERRED_BINDING" not in os.environ: if "QT_PREFERRED_BINDING" not in os.environ:
os.environ["QT_PREFERRED_BINDING"] = os.pathsep.join( os.environ["QT_PREFERRED_BINDING"] = os.pathsep.join(
["PySide6", "PySide2", "PySide", "PyQt5", "PyQt4"] ["PySide6", "PySide2", "PySide", "PyQt5", "PyQt4"]
) )
if not isWindowsConsole():
try: try:
from syncplay.ui.gui import MainWindow as GraphicalUI from syncplay.ui.gui import MainWindow as GraphicalUI
except ImportError: except ImportError:
@ -13,7 +15,7 @@ from syncplay.ui.consoleUI import ConsoleUI
def getUi(graphical=True, passedBar=None): def getUi(graphical=True, passedBar=None):
if graphical: if graphical and not isWindowsConsole():
ui = GraphicalUI(passedBar=passedBar) ui = GraphicalUI(passedBar=passedBar)
else: else:
ui = ConsoleUI() ui = ConsoleUI()

View File

@ -37,6 +37,8 @@ def isMacOS():
def isBSD(): def isBSD():
return constants.OS_BSD in sys.platform or sys.platform.startswith(constants.OS_DRAGONFLY) return constants.OS_BSD in sys.platform or sys.platform.startswith(constants.OS_DRAGONFLY)
def isWindowsConsole():
return os.path.basename(sys.executable) == "SyncplayConsole.exe"
def retry(ExceptionToCheck, tries=4, delay=3, backoff=2, logger=None): def retry(ExceptionToCheck, tries=4, delay=3, backoff=2, logger=None):
"""Retry calling the decorated function using an exponential backoff. """Retry calling the decorated function using an exponential backoff.
@ -225,6 +227,28 @@ def blackholeStdoutForFrozenWindow():
sys.stdout = Blackhole() sys.stdout = Blackhole()
del Blackhole del Blackhole
elif isWindowsConsole():
class Blackhole(object):
softspace = 0
def write(self, text):
pass
def flush(self):
pass
class Stderr(object):
softspace = 0
_file = None
_error = None
def flush(self):
if self._file is not None:
self._file.flush()
sys.stderr = Blackhole()
del Blackhole
def truncateText(unicodeText, maxLength): def truncateText(unicodeText, maxLength):
try: try: