Package plugins :: Package core :: Package shell :: Module main
[hide private]
[frames] | no frames]

Source Code for Module plugins.core.shell.main

  1  #-*- coding: utf8 -* 
  2  # 
  3  # Max E. Kuznecov <syhpoon@syhpoon.name> 2009 
  4  # 
  5   
  6  import sys 
  7  import errno 
  8  import os 
  9  import signal 
 10   
 11  import libxyz.core as core 
 12   
 13  from libxyz.core.utils import bstring 
 14  from libxyz.core.plugins import BasePlugin 
 15   
16 -class XYZPlugin(BasePlugin):
17 "Plugin shell" 18 19 NAME = u"shell" 20 AUTHOR = u"Max E. Kuznecov <syhpoon@syhpoon.name>" 21 VERSION = u"0.1" 22 BRIEF_DESCRIPTION = u"Shell wrapper" 23 FULL_DESCRIPTION = u"Execute commands in external shell" 24 NAMESPACE = u"core" 25 MIN_XYZ_VERSION = None 26 DOC = None 27 HOMEPAGE = "http://xyzcmd.syhpoon.name" 28 29 shell_args = {"sh": ["-c"], 30 "bash": ["-c"], 31 "zsh": ["-c"] 32 } 33
34 - def __init__(self, xyz):
35 self.status = 0 36 super(XYZPlugin, self).__init__(xyz) 37 38 self.export(self.execute)
39 40 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 41
42 - def prepare(self):
43 # Determine shell 44 45 shell = os.getenv("SHELL") 46 47 if not shell: 48 shell = "/bin/sh" 49 50 _shell = os.path.basename(shell) 51 52 if _shell not in self.shell_args: 53 shell, _shell = "/bin/sh", "sh" 54 55 self.shell = [shell] + self.shell_args[_shell]
56 57 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 58
59 - def execute(self, cmd):
60 """ 61 Execute command in shell 62 """ 63 64 cmd = bstring(cmd) 65 self.xyz.screen.clear() 66 stdout = sys.stdout 67 self.xyz.screen.stop() 68 69 _current_term = None 70 71 # Restore original terminal settings 72 if self.xyz.term is not None: 73 _current_term = core.utils.term_settings()[-1] 74 core.utils.restore_term(self.xyz.term) 75 76 # Clear the screen 77 #TODO: make it more portable! 78 stdout.write("\x1b[H\x1b[2J") 79 80 stdout.write("%s%s\n" % 81 (bstring( 82 self.xyz.conf[u"plugins"][":sys:cmd"][u"prompt"]), 83 cmd)) 84 stdout.flush() 85 86 def _sigwinch(sig, frame): 87 self.xyz.screen.resized = True
88 89 signal.signal(signal.SIGWINCH, _sigwinch) 90 91 pid = os.fork() 92 93 # Child - Exec passed cmd 94 if pid == 0: 95 os.execvp(self.shell[0], self.shell + [cmd]) 96 # WTF? 97 sys.exit() 98 # Parent 99 else: 100 while True: 101 try: 102 self.status = os.waitpid(pid, 0) 103 except KeyboardInterrupt: 104 pass 105 except OSError, e: 106 if e.errno != errno.EINTR: 107 break 108 109 if _current_term is not None: 110 core.utils.restore_term(_current_term) 111 112 self._press_key(_(u"Press ENTER to continue..."), "\n") 113 114 self.xyz.screen.start() 115 116 return self.status
117 118 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 119
120 - def _press_key(self, msg, key):
121 """ 122 Print prompt and wait for the key to be pressed 123 """ 124 125 sys.stdout.write(msg) 126 sys.stdout.flush() 127 128 while True: 129 try: 130 m = os.read(sys.stdin.fileno(), 1024) 131 if key in m: 132 break 133 except OSError, e: 134 if e.errno != errno.EINTR: 135 break
136