mirror of
https://github.com/rwinkhart/sshyp.git
synced 2026-09-06 09:07:13 -04:00
Fixed many instances where the curses menus could break the terminal session
Former-commit-id: df73403b4a8bc3ffb238486516d0f1e5a1f601c6 Former-commit-id: 649503907f391ff318fc0d3247b965ed3b2aacba
This commit is contained in:
+1
-1
@@ -2,7 +2,7 @@ from os import listdir, remove, walk
|
|||||||
from os.path import expanduser, isdir, isfile, getmtime, join
|
from os.path import expanduser, isdir, isfile, getmtime, join
|
||||||
from subprocess import CalledProcessError, PIPE, run
|
from subprocess import CalledProcessError, PIPE, run
|
||||||
from sys import exit as s_exit
|
from sys import exit as s_exit
|
||||||
home = expanduser("~")
|
home = expanduser('~')
|
||||||
|
|
||||||
|
|
||||||
# PORT START SSHYNC-REMOTE
|
# PORT START SSHYNC-REMOTE
|
||||||
|
|||||||
+7
-7
@@ -10,7 +10,7 @@ from sys import argv, exit as s_exit
|
|||||||
# PORT START UNAME-IMPORT-SSHYP
|
# PORT START UNAME-IMPORT-SSHYP
|
||||||
from os import uname
|
from os import uname
|
||||||
# PORT END UNAME-IMPORT-SSHYP
|
# PORT END UNAME-IMPORT-SSHYP
|
||||||
home = expanduser("~")
|
home = expanduser('~')
|
||||||
|
|
||||||
|
|
||||||
# UTILITY FUNCTIONS
|
# UTILITY FUNCTIONS
|
||||||
@@ -652,8 +652,8 @@ if __name__ == "__main__":
|
|||||||
print(f"{73*'!'}\n")
|
print(f"{73*'!'}\n")
|
||||||
s_exit(1)
|
s_exit(1)
|
||||||
else:
|
else:
|
||||||
from stweak import initial_setup
|
from stweak import wrapped_entry
|
||||||
initial_setup()
|
wrapped_entry(False)
|
||||||
s_exit()
|
s_exit()
|
||||||
|
|
||||||
# run function based on arguments
|
# run function based on arguments
|
||||||
@@ -702,8 +702,8 @@ if __name__ == "__main__":
|
|||||||
read_shortcut()
|
read_shortcut()
|
||||||
elif arguments[0] == 'tweak':
|
elif arguments[0] == 'tweak':
|
||||||
success_flag = True
|
success_flag = True
|
||||||
from stweak import global_menu
|
from stweak import wrapped_entry
|
||||||
global_menu('client', 'configuration options:')
|
wrapped_entry(device_type)
|
||||||
|
|
||||||
# PORT START ARGS-SERVER
|
# PORT START ARGS-SERVER
|
||||||
# server arguments
|
# server arguments
|
||||||
@@ -713,8 +713,8 @@ if __name__ == "__main__":
|
|||||||
print_info()
|
print_info()
|
||||||
elif arg_count == 1 and arguments[0] == 'tweak':
|
elif arg_count == 1 and arguments[0] == 'tweak':
|
||||||
success_flag = True
|
success_flag = True
|
||||||
from stweak import global_menu
|
from stweak import wrapped_entry
|
||||||
global_menu('server', 'configuration options:')
|
wrapped_entry(device_type)
|
||||||
# PORT END ARGS-SERVER
|
# PORT END ARGS-SERVER
|
||||||
|
|
||||||
if arg_count > 0 and success_flag == 0 and arguments[0] != 'sync':
|
if arg_count > 0 and success_flag == 0 and arguments[0] != 'sync':
|
||||||
|
|||||||
+146
-161
@@ -10,7 +10,7 @@ from subprocess import PIPE, run
|
|||||||
# PORT START UNAME-IMPORT-STWEAK
|
# PORT START UNAME-IMPORT-STWEAK
|
||||||
from os import uname
|
from os import uname
|
||||||
# PORT END UNAME-IMPORT-STWEAK
|
# PORT END UNAME-IMPORT-STWEAK
|
||||||
home, stdscr, sshyp_data = expanduser("~"), initscr(), ConfigParser()
|
home, sshyp_data, stdscr, term_messages = expanduser('~'), ConfigParser(), None, []
|
||||||
if isfile(f"{home}/.config/sshyp/sshyp.ini"):
|
if isfile(f"{home}/.config/sshyp/sshyp.ini"):
|
||||||
_exists_flag = True
|
_exists_flag = True
|
||||||
sshyp_data.read(f"{home}/.config/sshyp/sshyp.ini")
|
sshyp_data.read(f"{home}/.config/sshyp/sshyp.ini")
|
||||||
@@ -66,15 +66,6 @@ def curses_text(_pretext):
|
|||||||
return _box.gather().strip()
|
return _box.gather().strip()
|
||||||
|
|
||||||
|
|
||||||
# cleanly exit curses and optionally prints an exit message
|
|
||||||
def curses_terminate(_term_message):
|
|
||||||
nocbreak()
|
|
||||||
echo()
|
|
||||||
endwin()
|
|
||||||
if _term_message:
|
|
||||||
print(_term_message)
|
|
||||||
|
|
||||||
|
|
||||||
# device+sync type selection
|
# device+sync type selection
|
||||||
def install_type():
|
def install_type():
|
||||||
_offline_mode = 'false'
|
_offline_mode = 'false'
|
||||||
@@ -86,7 +77,7 @@ def install_type():
|
|||||||
_dev_type = 'server'
|
_dev_type = 'server'
|
||||||
Path(f"{home}/.config/sshyp/deleted").mkdir(mode=0o700, exist_ok=True)
|
Path(f"{home}/.config/sshyp/deleted").mkdir(mode=0o700, exist_ok=True)
|
||||||
Path(f"{home}/.config/sshyp/whitelist").mkdir(mode=0o700, exist_ok=True)
|
Path(f"{home}/.config/sshyp/whitelist").mkdir(mode=0o700, exist_ok=True)
|
||||||
curses_terminate('\nmake sure the ssh service is running and properly configured\n')
|
term_messages.append('make sure the ssh service is running and properly configured')
|
||||||
else:
|
else:
|
||||||
_dev_type = 'client'
|
_dev_type = 'client'
|
||||||
if _install_type == 1:
|
if _install_type == 1:
|
||||||
@@ -260,7 +251,6 @@ def refresh_encryption():
|
|||||||
|
|
||||||
# decrypt, optimize, and re-encrypt each entry with the newly selected key
|
# decrypt, optimize, and re-encrypt each entry with the newly selected key
|
||||||
if isdir(_directory):
|
if isdir(_directory):
|
||||||
curses_terminate('\noptimizing and re-encrypting entries... please wait - do not terminate this process')
|
|
||||||
_gpg_id = sshyp_data.get('CLIENT-GENERAL', 'gpg_id')
|
_gpg_id = sshyp_data.get('CLIENT-GENERAL', 'gpg_id')
|
||||||
for _root, _dirs, _files in sorted(walk(_directory, topdown=True)):
|
for _root, _dirs, _files in sorted(walk(_directory, topdown=True)):
|
||||||
for _filename in _files:
|
for _filename in _files:
|
||||||
@@ -369,7 +359,7 @@ def extension_downloader():
|
|||||||
_extensions.append('CANCEL')
|
_extensions.append('CANCEL')
|
||||||
_choice = curses_radio(_extensions, 'select an extension for more info')
|
_choice = curses_radio(_extensions, 'select an extension for more info')
|
||||||
if _choice == len(_extensions)-1:
|
if _choice == len(_extensions)-1:
|
||||||
return False, False
|
return False
|
||||||
_selected = _extensions[_choice]
|
_selected = _extensions[_choice]
|
||||||
_choice = curses_radio(('no', 'yes'), f"install {_selected}?\n\n\n\n\ndescription: "
|
_choice = curses_radio(('no', 'yes'), f"install {_selected}?\n\n\n\n\ndescription: "
|
||||||
f"{_pointer.get(_selected, 'desc')}\n\nusage: "
|
f"{_pointer.get(_selected, 'desc')}\n\nusage: "
|
||||||
@@ -383,8 +373,8 @@ def extension_downloader():
|
|||||||
# set permissions under active user
|
# set permissions under active user
|
||||||
chmod(_exe_dir, 0o755)
|
chmod(_exe_dir, 0o755)
|
||||||
chmod(_ini_dir, 0o644)
|
chmod(_ini_dir, 0o644)
|
||||||
return False, _selected
|
return _selected
|
||||||
return False, False
|
return False
|
||||||
|
|
||||||
|
|
||||||
# uninstalls/deletes selected extensions
|
# uninstalls/deletes selected extensions
|
||||||
@@ -395,16 +385,16 @@ def extension_remover():
|
|||||||
_installed.append('CANCEL')
|
_installed.append('CANCEL')
|
||||||
_choice = curses_radio(_installed, 'select an extension to uninstall')
|
_choice = curses_radio(_installed, 'select an extension to uninstall')
|
||||||
if _choice == len(_installed)-1:
|
if _choice == len(_installed)-1:
|
||||||
return False, False
|
return False
|
||||||
_sure = curses_radio(('no', 'yes'), f"are you sure you want to remove {_installed[_choice]}?")
|
_sure = curses_radio(('no', 'yes'), f"are you sure you want to remove {_installed[_choice]}?")
|
||||||
if _sure == 0:
|
if _sure == 0:
|
||||||
return False, False
|
return False
|
||||||
return False, _installed[_choice]
|
return _installed[_choice]
|
||||||
|
|
||||||
|
|
||||||
# provides options for managing extensions
|
# provides options for managing extensions
|
||||||
def extension_menu():
|
def extension_menu():
|
||||||
_term_message, _ext_name, _action = False, False, False
|
_ext_name, _action = False, False
|
||||||
# determine which of the supported privilege escalation utilities is installed
|
# determine which of the supported privilege escalation utilities is installed
|
||||||
if which('doas') is not None:
|
if which('doas') is not None:
|
||||||
_escalator = 'doas'
|
_escalator = 'doas'
|
||||||
@@ -417,126 +407,124 @@ def extension_menu():
|
|||||||
while True:
|
while True:
|
||||||
_choice = curses_radio(('download/update extensions', 'remove extensions', 'BACK'), 'extension management')
|
_choice = curses_radio(('download/update extensions', 'remove extensions', 'BACK'), 'extension management')
|
||||||
if _choice == 0:
|
if _choice == 0:
|
||||||
_term_message, _ext_name = extension_downloader()
|
_ext_name = extension_downloader()
|
||||||
if _ext_name:
|
if _ext_name:
|
||||||
# True represents installation
|
# True represents installation
|
||||||
_action = True
|
_action = True
|
||||||
break
|
break
|
||||||
elif _choice == 1:
|
elif _choice == 1:
|
||||||
_term_message, _ext_name = extension_remover()
|
_ext_name = extension_remover()
|
||||||
if _ext_name:
|
if _ext_name:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
return _term_message, _ext_name, _escalator, _action
|
return _ext_name, _escalator, _action
|
||||||
|
|
||||||
|
|
||||||
# runs secondary configuration menu
|
# runs secondary configuration menu
|
||||||
def global_menu(_device_type, _top_message):
|
def global_menu(_scr, _device_type, _top_message):
|
||||||
|
global stdscr
|
||||||
|
# only set global stdscr if running as entry point
|
||||||
|
if not isinstance(_scr, bool):
|
||||||
|
stdscr = _scr
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
# curses initialization
|
_options, _choice, _exit_signal = ['change device/synchronization types'], 0, False
|
||||||
noecho()
|
if _device_type == 'client':
|
||||||
cbreak()
|
_options.extend(['change gpg key', 're-configure ssh(ync)', 'change device name',
|
||||||
stdscr.keypad(True)
|
'[OPTIONAL, RECOMMENDED] set custom text editor',
|
||||||
|
'[OPTIONAL] enable/disable quick-unlock',
|
||||||
|
'[OPTIONAL] re-encrypt/optimize entries',
|
||||||
|
'[OPTIONAL] extension management'])
|
||||||
|
else:
|
||||||
|
_options.extend(['manage quick-unlock/whitelist'])
|
||||||
|
_options.extend(['EXIT/DONE'])
|
||||||
|
_choice += curses_radio(_options, _top_message)
|
||||||
|
|
||||||
_options, _choice, _term_message, _exit_signal = ['change device/synchronization types'], 0, False, False
|
if _choice == 0:
|
||||||
try:
|
_dev_sync_types = install_type()
|
||||||
if _device_type == 'client':
|
# if switching to client mode...
|
||||||
_options.extend(['change gpg key', 're-configure ssh(ync)', 'change device name',
|
if _dev_sync_types[0] == 'client':
|
||||||
'[OPTIONAL, RECOMMENDED] set custom text editor',
|
# ...and gpg settings are missing
|
||||||
'[OPTIONAL] enable/disable quick-unlock',
|
if not sshyp_data.has_option('CLIENT-GENERAL', 'gpg_id'):
|
||||||
'[OPTIONAL] re-encrypt/optimize entries',
|
|
||||||
'[OPTIONAL] extension management'])
|
|
||||||
else:
|
|
||||||
_options.extend(['manage quick-unlock/whitelist'])
|
|
||||||
_options.extend(['EXIT/DONE'])
|
|
||||||
_choice += curses_radio(_options, _top_message)
|
|
||||||
|
|
||||||
if _choice == 0:
|
|
||||||
_dev_sync_types = install_type()
|
|
||||||
# if switching to client mode...
|
|
||||||
if _dev_sync_types[0] == 'client':
|
|
||||||
# ...and gpg settings are missing
|
|
||||||
if not sshyp_data.has_option('CLIENT-GENERAL', 'gpg_id'):
|
|
||||||
gpg_config()
|
|
||||||
# ...and text editor settings are missing
|
|
||||||
if not sshyp_data.has_option('CLIENT-GENERAL', 'text_editor'):
|
|
||||||
editor_config(True)
|
|
||||||
# ...and online (synced) mode is enabled...
|
|
||||||
if _dev_sync_types[1] == 'false':
|
|
||||||
# ...and quick-unlock settings are missing
|
|
||||||
if not sshyp_data.has_option('CLIENT-ONLINE', 'quick_unlock_enabled'):
|
|
||||||
quick_unlock_config(True)
|
|
||||||
# ...and there is no sshync config present
|
|
||||||
if not sshyp_data.has_section('SSHYNC'):
|
|
||||||
_ip, _username_ssh, _port = ssh_config()
|
|
||||||
# ...and there is no device ID present
|
|
||||||
if not listdir(f"{home}/.config/sshyp/devices"):
|
|
||||||
dev_id_config(_ip, _username_ssh, _port)
|
|
||||||
# ...or ssh_error is missing
|
|
||||||
elif not sshyp_data.has_option('CLIENT-ONLINE', 'ssh_error'):
|
|
||||||
sshyp_data.set('CLIENT-ONLINE', 'ssh_error', '1')
|
|
||||||
write_config()
|
|
||||||
_device_type = _dev_sync_types[0]
|
|
||||||
elif _choice == 1:
|
|
||||||
if _device_type == 'client':
|
|
||||||
gpg_config()
|
gpg_config()
|
||||||
else:
|
# ...and text editor settings are missing
|
||||||
whitelist_menu()
|
if not sshyp_data.has_option('CLIENT-GENERAL', 'text_editor'):
|
||||||
elif _choice == 2:
|
editor_config(True)
|
||||||
if _device_type == 'client':
|
# ...and online (synced) mode is enabled...
|
||||||
ssh_config()
|
if _dev_sync_types[1] == 'false':
|
||||||
else:
|
# ...and quick-unlock settings are missing
|
||||||
_exit_signal = True
|
if not sshyp_data.has_option('CLIENT-ONLINE', 'quick_unlock_enabled'):
|
||||||
elif _choice == 3:
|
quick_unlock_config(True)
|
||||||
if not sshyp_data.has_section('SSHYNC'):
|
# ...and there is no sshync config present
|
||||||
ssh_config()
|
if not sshyp_data.has_section('SSHYNC'):
|
||||||
dev_id_config(sshyp_data.get('SSHYNC', 'ip'), sshyp_data.get('SSHYNC', 'user'),
|
_ip, _username_ssh, _port = ssh_config()
|
||||||
sshyp_data.get('SSHYNC', 'port'))
|
# ...and there is no device ID present
|
||||||
elif _choice == 4:
|
if not listdir(f"{home}/.config/sshyp/devices"):
|
||||||
editor_config(False)
|
dev_id_config(_ip, _username_ssh, _port)
|
||||||
elif _choice == 5:
|
# ...or ssh_error is missing
|
||||||
_enabled = quick_unlock_config(False)
|
elif not sshyp_data.has_option('CLIENT-ONLINE', 'ssh_error'):
|
||||||
if _enabled == 'true':
|
sshyp_data.set('CLIENT-ONLINE', 'ssh_error', '1')
|
||||||
_term_message = ('\nquick-unlock has been enabled client-side - in order for this feature to '
|
write_config()
|
||||||
'function,\nyou must first log in to the sshyp server and run:\n\nsshyp tweak\n\n'
|
_device_type = _dev_sync_types[0]
|
||||||
'from there you can create a quick-unlock pin and add this device to the '
|
elif _choice == 1:
|
||||||
'whitelist\n')
|
if _device_type == 'client':
|
||||||
elif _choice == 6:
|
gpg_config()
|
||||||
_success = refresh_encryption()
|
else:
|
||||||
if _success == 1:
|
whitelist_menu()
|
||||||
_term_message = "\na backup of your previous entry directory has been created:\n\n" \
|
elif _choice == 2:
|
||||||
f"{home}/.local/share/sshyp.old\n"
|
if _device_type == 'client':
|
||||||
elif _success == 2:
|
ssh_config()
|
||||||
_term_message = '\n\u001b[38;5;9merror: re-encryption failed: ' \
|
|
||||||
'entry directory not found\u001b[0m\n'
|
|
||||||
elif _choice == 7:
|
|
||||||
_term_message, _ext_name, _escalator, _action = extension_menu()
|
|
||||||
else:
|
else:
|
||||||
_exit_signal = True
|
_exit_signal = True
|
||||||
curses_terminate(_term_message)
|
elif _choice == 3:
|
||||||
# if root is needed for extension management...
|
if not sshyp_data.has_section('SSHYNC'):
|
||||||
if _choice == 7 and _ext_name:
|
ssh_config()
|
||||||
if _action:
|
dev_id_config(sshyp_data.get('SSHYNC', 'ip'), sshyp_data.get('SSHYNC', 'user'),
|
||||||
# install with privilege escalation (outside of curses)
|
sshyp_data.get('SSHYNC', 'port'))
|
||||||
from tempfile import gettempdir
|
elif _choice == 4:
|
||||||
_exe_dir, _ini_dir = f"{gettempdir()}/sshyp_exe", f"{gettempdir()}/sshyp_ini"
|
editor_config(False)
|
||||||
run((_escalator, 'chown', 'root:root', _exe_dir, _ini_dir))
|
elif _choice == 5:
|
||||||
run((_escalator, 'mv', _exe_dir, f"/usr/lib/sshyp/{_ext_name}"))
|
_enabled = quick_unlock_config(False)
|
||||||
run((_escalator, 'mv', _ini_dir, f"/usr/lib/sshyp/extensions/{_ext_name}.ini"))
|
if _enabled == 'true':
|
||||||
else:
|
term_messages.append('quick-unlock has been enabled client-side - in order for this feature to '
|
||||||
# uninstall with privilege escalation (outside of curses)
|
'function,\nyou must first log in to the sshyp server and run:\n\nsshyp tweak\n\n'
|
||||||
run((_escalator, 'rm', '-I', f"/usr/lib/sshyp/{_ext_name}", f"/usr/lib/sshyp/extensions/{_ext_name}.ini"))
|
'from there you can create a quick-unlock pin and add this device to the '
|
||||||
break
|
'whitelist')
|
||||||
except KeyboardInterrupt:
|
elif _choice == 6:
|
||||||
curses_terminate(False)
|
_success = refresh_encryption()
|
||||||
|
if _success == 1:
|
||||||
|
term_messages.append("a backup of your previous entry directory has been created:\n\n"
|
||||||
|
f"{home}/.local/share/sshyp.old")
|
||||||
|
elif _success == 2:
|
||||||
|
term_messages.append('\u001b[38;5;9merror: re-encryption failed: '
|
||||||
|
'entry directory not found\u001b[0m')
|
||||||
|
elif _choice == 7:
|
||||||
|
_ext_name, _escalator, _action = extension_menu()
|
||||||
|
else:
|
||||||
_exit_signal = True
|
_exit_signal = True
|
||||||
|
# if root is needed for extension management...
|
||||||
|
if _choice == 7 and _ext_name:
|
||||||
|
if _action:
|
||||||
|
# install with privilege escalation (outside of curses)
|
||||||
|
from tempfile import gettempdir
|
||||||
|
_exe_dir, _ini_dir = f"{gettempdir()}/sshyp_exe", f"{gettempdir()}/sshyp_ini"
|
||||||
|
run((_escalator, 'chown', 'root:root', _exe_dir, _ini_dir))
|
||||||
|
run((_escalator, 'mv', _exe_dir, f"/usr/lib/sshyp/{_ext_name}"))
|
||||||
|
run((_escalator, 'mv', _ini_dir, f"/usr/lib/sshyp/extensions/{_ext_name}.ini"))
|
||||||
|
else:
|
||||||
|
# uninstall with privilege escalation (outside of curses)
|
||||||
|
run((_escalator, 'rm', '-I', f"/usr/lib/sshyp/{_ext_name}", f"/usr/lib/sshyp/extensions/{_ext_name}.ini"))
|
||||||
|
break
|
||||||
if _exit_signal:
|
if _exit_signal:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
# runs initial configuration wizard
|
# runs initial configuration wizard
|
||||||
def initial_setup():
|
def initial_setup(_scr):
|
||||||
|
global stdscr
|
||||||
|
stdscr = _scr
|
||||||
|
|
||||||
# required directory creation
|
# required directory creation
|
||||||
Path(f"{home}/.config/sshyp/devices").mkdir(mode=0o700, parents=True, exist_ok=True)
|
Path(f"{home}/.config/sshyp/devices").mkdir(mode=0o700, parents=True, exist_ok=True)
|
||||||
Path(f"{home}/.local/share/sshyp").mkdir(mode=0o700, parents=True, exist_ok=True)
|
Path(f"{home}/.local/share/sshyp").mkdir(mode=0o700, parents=True, exist_ok=True)
|
||||||
@@ -545,60 +533,57 @@ def initial_setup():
|
|||||||
if _exists_flag:
|
if _exists_flag:
|
||||||
sshyp_data.clear()
|
sshyp_data.clear()
|
||||||
|
|
||||||
# curses initialization
|
|
||||||
noecho()
|
|
||||||
cbreak()
|
|
||||||
stdscr.keypad(True)
|
|
||||||
|
|
||||||
# curses menu tree
|
# curses menu tree
|
||||||
try:
|
# device+sync type selection
|
||||||
# device+sync type selection
|
_dev_sync_types = install_type()
|
||||||
_dev_sync_types = install_type()
|
|
||||||
|
|
||||||
if _dev_sync_types[0] == 'client':
|
if _dev_sync_types[0] == 'client':
|
||||||
|
|
||||||
# gpg configuration
|
# gpg configuration
|
||||||
gpg_config()
|
gpg_config()
|
||||||
|
|
||||||
# text editor configuration (automated)
|
# text editor configuration (automated)
|
||||||
editor_config(True)
|
editor_config(True)
|
||||||
|
|
||||||
# quick-unlock configuration (disabled by default)
|
# quick-unlock configuration (disabled by default)
|
||||||
quick_unlock_config(True)
|
quick_unlock_config(True)
|
||||||
|
|
||||||
# online (synchronized mode) configuration
|
# online (synchronized mode) configuration
|
||||||
if _dev_sync_types[1] != 'true':
|
if _dev_sync_types[1] != 'true':
|
||||||
|
|
||||||
# ssh+sshync configuration
|
# ssh+sshync configuration
|
||||||
_ip, _username_ssh, _port = ssh_config()
|
_ip, _username_ssh, _port = ssh_config()
|
||||||
|
|
||||||
# device id configuration
|
# device id configuration
|
||||||
dev_id_config(_ip, _username_ssh, _port)
|
dev_id_config(_ip, _username_ssh, _port)
|
||||||
|
|
||||||
# cleanly exit curses
|
# PORT START CLIPTOOL TODO fix printing with new curses wrapper
|
||||||
curses_terminate(False)
|
# check for clipboard tool and display warning if missing
|
||||||
|
if uname()[0] in ('Linux', 'FreeBSD') and 'WSL_DISTRO_NAME' not in environ \
|
||||||
|
and not exists("/data/data/com.termux"):
|
||||||
|
_display_server, _clipboard_tool, _clipboard_package = None, None, None
|
||||||
|
if 'WAYLAND_DISPLAY' in environ:
|
||||||
|
_display_server, _clipboard_tool, _clipboard_package = 'Wayland', 'wl-copy', 'wl-clipboard'
|
||||||
|
elif 'DISPLAY' in environ:
|
||||||
|
_display_server, _clipboard_tool, _clipboard_package = 'X11', 'xclip', 'xclip'
|
||||||
|
if _display_server is not None and which(_clipboard_tool) is None:
|
||||||
|
print(f'\n\u001b[38;5;9mwarning: you are using {_display_server} and "{_clipboard_tool}" is not '
|
||||||
|
f'present - \ncopying entry fields will not function until '
|
||||||
|
f'"{_clipboard_package}" is installed\u001b[0m')
|
||||||
|
# PORT END CLIPTOOL
|
||||||
|
|
||||||
else:
|
# run optional configuration menu
|
||||||
# cleanly exit curses
|
wrapped_entry(_dev_sync_types[0], 'additional configuration options:')
|
||||||
curses_terminate(False)
|
|
||||||
|
|
||||||
# PORT START CLIPTOOL
|
|
||||||
# check for clipboard tool and display warning if missing
|
|
||||||
if uname()[0] in ('Linux', 'FreeBSD') and 'WSL_DISTRO_NAME' not in environ \
|
|
||||||
and not exists("/data/data/com.termux"):
|
|
||||||
_display_server, _clipboard_tool, _clipboard_package = None, None, None
|
|
||||||
if 'WAYLAND_DISPLAY' in environ:
|
|
||||||
_display_server, _clipboard_tool, _clipboard_package = 'Wayland', 'wl-copy', 'wl-clipboard'
|
|
||||||
elif 'DISPLAY' in environ:
|
|
||||||
_display_server, _clipboard_tool, _clipboard_package = 'X11', 'xclip', 'xclip'
|
|
||||||
if _display_server is not None and which(_clipboard_tool) is None:
|
|
||||||
print(f'\n\u001b[38;5;9mwarning: you are using {_display_server} and "{_clipboard_tool}" is not '
|
|
||||||
f'present - \ncopying entry fields will not function until '
|
|
||||||
f'"{_clipboard_package}" is installed\u001b[0m')
|
|
||||||
# PORT END CLIPTOOL
|
|
||||||
|
|
||||||
global_menu(_dev_sync_types[0], 'additional configuration options:')
|
# runs the specified entry function (menu start point) within a curses wrapper
|
||||||
|
def wrapped_entry(_gm_device_type, _gm_top_message='configuration options:'):
|
||||||
except KeyboardInterrupt:
|
from curses import wrapper, use_default_colors
|
||||||
# cleanly exit curses
|
# a boolean value represents init
|
||||||
curses_terminate(False)
|
if isinstance(_gm_device_type, bool):
|
||||||
|
wrapper(lambda _wrap_stdscr: (use_default_colors(), initial_setup(_wrap_stdscr)))
|
||||||
|
# any other vlaue will be provided as the global menu device type
|
||||||
|
else:
|
||||||
|
wrapper(lambda _wrap_stdscr: (use_default_colors(), global_menu(_wrap_stdscr, _gm_device_type, _gm_top_message)))
|
||||||
|
for _message in term_messages:
|
||||||
|
print(f"\n{_message}\n")
|
||||||
|
|||||||
Reference in New Issue
Block a user