Tools for GNS3 GUI
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

0003-tools-add-option-run-in-terminal.patch 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. From e5e28f31c0b72986dd83eb165de2be45a41e6711 Mon Sep 17 00:00:00 2001
  2. From: Bernhard Ehlers <be@bernhard-ehlers.de>
  3. Date: Fri, 29 Dec 2017 14:26:31 +0100
  4. Subject: [PATCH 3/7] tools: add option "run in terminal"
  5. ---
  6. gns3/tool.py | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
  7. 1 file changed, 78 insertions(+), 1 deletion(-)
  8. diff --git a/gns3/tool.py b/gns3/tool.py
  9. index f2df147..fca4e8c 100644
  10. --- a/gns3/tool.py
  11. +++ b/gns3/tool.py
  12. @@ -19,8 +19,11 @@ Manage Tools
  13. """
  14. import os
  15. +import sys
  16. import json
  17. import logging
  18. +import re
  19. +import shutil
  20. import subprocess
  21. from enum import Enum
  22. @@ -32,6 +35,21 @@ from .items.drawing_item import DrawingItem
  23. log = logging.getLogger(__name__)
  24. +# sh_quote inspired by compat_shlex_quote in youtube-dl:youtube_dl/compat.py
  25. +if sys.platform.startswith("win"):
  26. + def sh_quote(arg):
  27. + """ quote argument for safe use in windows CMD """
  28. + if not re.match(r'^[-._\w]+$', arg):
  29. + arg = '"' + arg.replace('"', '\\"') + '"'
  30. + arg = re.sub(r'([()%!^"<>&|])', r'^\1', arg)
  31. + return arg
  32. +else:
  33. + def sh_quote(arg):
  34. + """ quote argument for safe use in sh """
  35. + if not re.match(r'^[-_\w./]+$', arg):
  36. + arg = "'" + arg.replace("'", "'\"'\"'") + "'"
  37. + return arg
  38. +
  39. class ContextState(Enum):
  40. """ enum for context option """
  41. @@ -43,6 +61,8 @@ class ContextState(Enum):
  42. class Tool:
  43. """ tool class """
  44. + _terminal_app = None
  45. +
  46. def __init__(self, name, path, options):
  47. self._name = name
  48. self._path = path
  49. @@ -59,11 +79,65 @@ class Tool:
  50. log.warning("Tool %s: unknown context option '%s'", name, context)
  51. context = ContextState.enable
  52. self.context = context
  53. + self.terminal = options.get('terminal', False)
  54. def name(self):
  55. """ tool name """
  56. return self._name
  57. + def run_in_terminal(self, argv):
  58. + """ run command in terminal window """
  59. +
  60. + if sys.platform.startswith("win"):
  61. + cmd_exe = os.environ.get('ComSpec', "cmd.exe")
  62. + cmd_string = " ".join(sh_quote(arg) for arg in argv)
  63. + subprocess.Popen("{} /c {} & pause".format(cmd_exe, cmd_string),
  64. + env=os.environ)
  65. + elif sys.platform.startswith("darwin"):
  66. + osascript = r"""
  67. +on run (args)
  68. + set cmd to " echo -n -e '\\033]0;" & first item of args & "\\007\\033[H\\033[2J\\033[3J'; " & second item of args & "; exit"
  69. + if application "Terminal" is running then
  70. + tell application "Terminal"
  71. + activate
  72. + do script cmd
  73. + end tell
  74. + else
  75. + tell application "Terminal"
  76. + activate
  77. + repeat while not exists (window 1)
  78. + delay 0.2
  79. + activate
  80. + end repeat
  81. + do script cmd in window 1
  82. + end tell
  83. + end if
  84. + return
  85. +end run
  86. +"""
  87. + cmd = "PATH=" + sh_quote(os.environ['PATH']) + "; " + \
  88. + "cd " + sh_quote(os.getcwd()) + "; " + \
  89. + " ".join(sh_quote(arg) for arg in argv) + \
  90. + "; echo; read -p Close... var"
  91. + prog = os.path.splitext(os.path.basename(argv[0]))[0]
  92. + subprocess.Popen(["osascript", "-e", osascript, "--", prog, cmd],
  93. + env=os.environ)
  94. + else:
  95. + if Tool._terminal_app is None:
  96. + for app in ("gnome-terminal", "mate-terminal", "konsole",
  97. + "xfce4-terminal", "urxvt", "xterm"):
  98. + if shutil.which(app):
  99. + Tool._terminal_app = app
  100. + break
  101. + else:
  102. + log.error("Tool %s: No terminal emulator found", self._name)
  103. + return
  104. + cmd = " ".join(sh_quote(arg) for arg in argv) + \
  105. + "; echo; read -p Close... var"
  106. + cmd = "sh -c " + sh_quote(cmd)
  107. + subprocess.Popen([Tool._terminal_app, "-e", cmd],
  108. + env=os.environ)
  109. +
  110. def run(self, project, item_list):
  111. """ run tool """
  112. @@ -81,7 +155,10 @@ class Tool:
  113. args.append("drawings/" + item.drawing_id())
  114. try:
  115. - subprocess.Popen(args, env=os.environ)
  116. + if self.terminal:
  117. + self.run_in_terminal(args)
  118. + else:
  119. + subprocess.Popen(args, env=os.environ)
  120. except (OSError, ValueError, subprocess.SubprocessError) as err:
  121. log.error('Could not start tool %s: %s', self._name, err)
  122. --
  123. 2.10.1 (Apple Git-78)