| OLD | NEW |
| (Empty) |
| 1 # -*- Python -*- | |
| 2 # Copyright (c) 2001-2004 Twisted Matrix Laboratories. | |
| 3 # See LICENSE for details. | |
| 4 | |
| 5 | |
| 6 # TODO: | |
| 7 # * send script | |
| 8 # * replace method | |
| 9 # * save readline history | |
| 10 # * save-history-as-python | |
| 11 # * save transcript | |
| 12 # * identifier completion | |
| 13 | |
| 14 import code, string, sys, traceback, types | |
| 15 import gtk | |
| 16 | |
| 17 from twisted.python import rebuild, util | |
| 18 from twisted.spread.ui import gtkutil | |
| 19 from twisted.spread import pb | |
| 20 from twisted.manhole import explorer | |
| 21 | |
| 22 True = gtk.TRUE | |
| 23 False = gtk.FALSE | |
| 24 | |
| 25 try: | |
| 26 import spelunk_gnome | |
| 27 except ImportError: | |
| 28 _GNOME_POWER = False | |
| 29 else: | |
| 30 _GNOME_POWER = True | |
| 31 | |
| 32 | |
| 33 ## def findBeginningOfLineWithPoint(entry): | |
| 34 ## pos = entry.get_point() | |
| 35 ## while pos: | |
| 36 ## pos = pos - 1 | |
| 37 ## c = entry.get_chars(pos, pos+1) | |
| 38 ## if c == '\n': | |
| 39 ## return pos+1 | |
| 40 ## return 0 | |
| 41 | |
| 42 import pywidgets | |
| 43 | |
| 44 class Interaction(pywidgets.Interaction, pb.Referenceable): | |
| 45 loginWindow = None | |
| 46 | |
| 47 capabilities = { | |
| 48 "Explorer": 'Set', | |
| 49 } | |
| 50 | |
| 51 def __init__(self): | |
| 52 pywidgets.Interaction.__init__(self) | |
| 53 self.signal_connect('destroy', gtk.mainquit, None) | |
| 54 | |
| 55 if _GNOME_POWER: | |
| 56 self.display = BrowserDisplay() | |
| 57 dWindow = gtk.GtkWindow(title="Spelunking") | |
| 58 dWindow.add(self.display) | |
| 59 dWindow.show_all() | |
| 60 self.display.makeDefaultCanvas() | |
| 61 else: | |
| 62 self.display = BrowserDisplay(self) | |
| 63 | |
| 64 # The referencable attached to the Perspective | |
| 65 self.client = self | |
| 66 | |
| 67 def remote_console(self, message): | |
| 68 self.output.console(message) | |
| 69 | |
| 70 def remote_receiveExplorer(self, xplorer): | |
| 71 if _GNOME_POWER: | |
| 72 self.display.receiveExplorer(xplorer) | |
| 73 else: | |
| 74 XXX # text display? | |
| 75 | |
| 76 def remote_listCapabilities(self): | |
| 77 return self.capabilities | |
| 78 | |
| 79 def connected(self, perspective): | |
| 80 self.loginWindow.hide() | |
| 81 self.name = self.loginWindow.username.get_text() | |
| 82 self.hostname = self.loginWindow.hostname.get_text() | |
| 83 perspective.broker.notifyOnDisconnect(self.connectionLost) | |
| 84 self.perspective = perspective | |
| 85 self.show_all() | |
| 86 self.set_title("Manhole: %s@%s" % (self.name, self.hostname)) | |
| 87 | |
| 88 def connectionLost(self, reason=None): | |
| 89 if not reason: | |
| 90 reason = "Connection Lost" | |
| 91 self.loginWindow.loginReport(reason) | |
| 92 self.hide() | |
| 93 self.loginWindow.show() | |
| 94 | |
| 95 def codeInput(self, text): | |
| 96 methodName = 'do' | |
| 97 if text[0] == '/': | |
| 98 split = string.split(text[1:],' ',1) | |
| 99 statement = split[0] | |
| 100 if len(split) == 2: | |
| 101 remainder = split[1] | |
| 102 if statement in ('browse', 'explore'): | |
| 103 methodName = 'explore' | |
| 104 text = remainder | |
| 105 elif statement == 'watch': | |
| 106 methodName = 'watch' | |
| 107 text = remainder | |
| 108 elif statement == 'self_rebuild': | |
| 109 rebuild.rebuild(explorer) | |
| 110 if _GNOME_POWER: | |
| 111 rebuild.rebuild(spelunk_gnome) | |
| 112 rebuild.rebuild(sys.modules[__name__]) | |
| 113 return | |
| 114 try: | |
| 115 self.perspective.callRemote(methodName, text) | |
| 116 except pb.ProtocolError: | |
| 117 # ASSUMPTION: pb.ProtocolError means we lost our connection. | |
| 118 (eType, eVal, tb) = sys.exc_info() | |
| 119 del tb | |
| 120 s = string.join(traceback.format_exception_only(eType, eVal), | |
| 121 '') | |
| 122 self.connectionLost(s) | |
| 123 except: | |
| 124 traceback.print_exc() | |
| 125 gtk.mainquit() | |
| 126 | |
| 127 | |
| 128 class LineOrientedBrowserDisplay: | |
| 129 def __init__(self, toplevel=None): | |
| 130 if toplevel: | |
| 131 self.toplevel = toplevel | |
| 132 | |
| 133 def receiveBrowserObject(self, obj): | |
| 134 """Display a browser ObjectLink. | |
| 135 """ | |
| 136 # This is a stop-gap implementation. Ideally, everything | |
| 137 # would be nicely formatted with pretty colours and you could | |
| 138 # select referenced objects to browse them with | |
| 139 # browse(selectedLink.identifier) | |
| 140 | |
| 141 if obj.type in map(explorer.typeString, [types.FunctionType, | |
| 142 types.MethodType]): | |
| 143 arglist = [] | |
| 144 for arg in obj.value['signature']: | |
| 145 if arg.has_key('default'): | |
| 146 a = "%s=%s" % (arg['name'], arg['default']) | |
| 147 elif arg.has_key('list'): | |
| 148 a = "*%s" % (arg['name'],) | |
| 149 elif arg.has_key('keywords'): | |
| 150 a = "**%s" % (arg['name'],) | |
| 151 else: | |
| 152 a = arg['name'] | |
| 153 arglist.append(a) | |
| 154 | |
| 155 things = '' | |
| 156 if obj.value.has_key('class'): | |
| 157 things = "Class: %s\n" % (obj.value['class'],) | |
| 158 if obj.value.has_key('self'): | |
| 159 things = things + "Self: %s\n" % (obj.value['self'],) | |
| 160 | |
| 161 s = "%(name)s(%(arglist)s)\n%(things)s\n%(doc)s\n" % { | |
| 162 'name': obj.value['name'], | |
| 163 'doc': obj.value['doc'], | |
| 164 'things': things, | |
| 165 'arglist': string.join(arglist,", "), | |
| 166 } | |
| 167 else: | |
| 168 s = str(obj) + '\n' | |
| 169 | |
| 170 self.toplevel.output.console([('stdout',s)]) | |
| 171 | |
| 172 | |
| 173 if _GNOME_POWER: | |
| 174 BrowserDisplay = spelunk_gnome.SpelunkDisplay | |
| 175 else: | |
| 176 BrowserDisplay = LineOrientedBrowserDisplay | |
| 177 | |
| 178 class Signature(pb.RemoteCopy, explorer.Signature): | |
| 179 def __init__(self): | |
| 180 pass | |
| 181 | |
| 182 __str__ = explorer.Signature.__str__ | |
| 183 | |
| 184 pb.setCopierForClass('twisted.manhole.explorer.Signature', Signature) | |
| OLD | NEW |