Exemplo n.º 1
0
class Console:
    PROMPT = sys.ps1
    PROCESS = sys.ps2
    BANNER = ["Jython Completion Shell", InteractiveConsole.getDefaultBanner()]
  
    include_single_underscore_methods = False
    include_double_underscore_methods = False

    def __init__(self, namespace=None):
        """
            Create a Jython Console.
            namespace is an optional and should be a dictionary or Map
        """
        self.history = History(self)

        if namespace != None:
            self.locals = namespace
        else:
            self.locals = {}

        self.buffer = [] # buffer for multi-line commands                    

        self.interp = Interpreter(self, self.locals)
        sys.stdout = StdOutRedirector(self)

        self.text_pane = JTextPane(keyTyped = self.keyTyped, keyPressed = self.keyPressed)
        self.__initKeyMap()

        self.doc = self.text_pane.document
        self.__propertiesChanged()
        self.__inittext()
        self.initialLocation = self.doc.createPosition(self.doc.length-1)

        # Don't pass frame to popups. JWindows with null owners are not focusable
        # this fixes the focus problem on Win32, but make the mouse problem worse
        self.popup = Popup(None, self.text_pane)
        self.tip = Tip(None)

        # get fontmetrics info so we can position the popup
        metrics = self.text_pane.getFontMetrics(self.text_pane.getFont())
        self.dotWidth = metrics.charWidth('.')
        self.textHeight = metrics.getHeight()

        # add some handles to our objects
        self.locals['console'] = self

    def insertText(self, text):
        """insert text at the current caret position"""
        # seems like there should be a better way to do this....
        # might be better as a method on the text component?
        caretPosition = self.text_pane.getCaretPosition()
        self.text_pane.select(caretPosition, caretPosition)
        self.text_pane.replaceSelection(text)
        self.text_pane.setCaretPosition(caretPosition + len(text))

    def getText(self):
        """get text from last line of console"""
        offsets = self.__lastLine()
        text = self.doc.getText(offsets[0], offsets[1]-offsets[0])
        return text.rstrip()

    def getDisplayPoint(self):
        """Get the point where the popup window should be displayed"""
        screenPoint = self.text_pane.getLocationOnScreen()
        caretPoint = self.text_pane.caret.getMagicCaretPosition()

        # BUG: sometimes caretPoint is None
        # To duplicate type "java.aw" and hit '.' to complete selection while popup is visible

        x = screenPoint.getX() + caretPoint.getX() + self.dotWidth
        y = screenPoint.getY() + caretPoint.getY() + self.textHeight
        return Point(int(x),int(y))

    def hide(self, event=None):
        """Hide the popup or tip window if visible"""
        if self.popup.visible:
            self.popup.hide()
        if self.tip.visible:
            self.tip.hide()

    def hideTip(self, event=None):
        self.tip.hide()
        self.insertText(')')

    def showTip(self, event=None):
        # get the display point before writing text
        # otherwise magicCaretPosition is None
        displayPoint = self.getDisplayPoint()

        if self.popup.visible:
            self.popup.hide()
        
        line = self.getText()

        self.insertText('(')
        
        (name, argspec, tip) = jintrospect.getCallTipJava(line, self.locals)

        if tip:
            self.tip.showTip(tip, displayPoint)
            
    def showPopup(self, event=None):
        """show code completion popup"""

        try:
            line = self.getText()
            list = jintrospect.getAutoCompleteList(line, self.locals, includeSingle=self.include_single_underscore_methods, includeDouble=self.include_double_underscore_methods)
            if len(list) > 0:
                self.popup.showMethodCompletionList(list, self.getDisplayPoint())

        except Exception, e:
            print >> sys.stderr, "Error getting completion list: ", e
Exemplo n.º 2
0
class Console:
    PROMPT = sys.ps1
    PROCESS = sys.ps2
    BANNER = ["Jython Completion Shell", InteractiveConsole.getDefaultBanner()]

    include_single_underscore_methods = False
    include_double_underscore_methods = False

    def __init__(self, namespace=None):
        """
            Create a Jython Console.
            namespace is an optional and should be a dictionary or Map
        """
        self.history = History(self)

        if namespace != None:
            self.locals = namespace
        else:
            self.locals = {}

        self.buffer = []  # buffer for multi-line commands

        self.interp = Interpreter(self, self.locals)
        sys.stdout = StdOutRedirector(self)

        self.text_pane = JTextPane(keyTyped=self.keyTyped,
                                   keyPressed=self.keyPressed)
        self.__initKeyMap()

        self.doc = self.text_pane.document
        self.__propertiesChanged()
        self.__inittext()
        self.initialLocation = self.doc.createPosition(self.doc.length - 1)

        # Don't pass frame to popups. JWindows with null owners are not focusable
        # this fixes the focus problem on Win32, but make the mouse problem worse
        self.popup = Popup(None, self.text_pane)
        self.tip = Tip(None)

        # get fontmetrics info so we can position the popup
        metrics = self.text_pane.getFontMetrics(self.text_pane.getFont())
        self.dotWidth = metrics.charWidth('.')
        self.textHeight = metrics.getHeight()

        # add some handles to our objects
        self.locals['console'] = self

    def insertText(self, text):
        """insert text at the current caret position"""
        # seems like there should be a better way to do this....
        # might be better as a method on the text component?
        caretPosition = self.text_pane.getCaretPosition()
        self.text_pane.select(caretPosition, caretPosition)
        self.text_pane.replaceSelection(text)
        self.text_pane.setCaretPosition(caretPosition + len(text))

    def getText(self):
        """get text from last line of console"""
        offsets = self.__lastLine()
        text = self.doc.getText(offsets[0], offsets[1] - offsets[0])
        return text.rstrip()

    def getDisplayPoint(self):
        """Get the point where the popup window should be displayed"""
        screenPoint = self.text_pane.getLocationOnScreen()
        caretPoint = self.text_pane.caret.getMagicCaretPosition()

        # BUG: sometimes caretPoint is None
        # To duplicate type "java.aw" and hit '.' to complete selection while popup is visible

        x = screenPoint.getX() + caretPoint.getX() + self.dotWidth
        y = screenPoint.getY() + caretPoint.getY() + self.textHeight
        return Point(int(x), int(y))

    def hide(self, event=None):
        """Hide the popup or tip window if visible"""
        if self.popup.visible:
            self.popup.hide()
        if self.tip.visible:
            self.tip.hide()

    def hideTip(self, event=None):
        self.tip.hide()
        self.insertText(')')

    def showTip(self, event=None):
        # get the display point before writing text
        # otherwise magicCaretPosition is None
        displayPoint = self.getDisplayPoint()

        if self.popup.visible:
            self.popup.hide()

        line = self.getText()

        self.insertText('(')

        (name, argspec, tip) = jintrospect.getCallTipJava(line, self.locals)

        if tip:
            self.tip.showTip(tip, displayPoint)

    def showPopup(self, event=None):
        """show code completion popup"""

        try:
            line = self.getText()
            list = jintrospect.getAutoCompleteList(
                line,
                self.locals,
                includeSingle=self.include_single_underscore_methods,
                includeDouble=self.include_double_underscore_methods)
            if len(list) > 0:
                self.popup.showMethodCompletionList(list,
                                                    self.getDisplayPoint())

        except Exception, e:
            print >> sys.stderr, "Error getting completion list: ", e
Exemplo n.º 3
0
class Console(object):
    PS1 = sys.ps1
    PS2 = sys.ps2

    def __init__(self, burp, namespace=None):
        self.burp = burp
        self.log = burp.log
        self._locals = dict(Burp=burp)
        self._buffer = []
        self.history = History(self)

        if namespace is not None:
            self._locals.update(namespace)

        self.interp = JythonInterpreter(self, self._locals)

        self.textpane = JTextPane(keyTyped=self.keyTyped,
                                  keyPressed=self.keyPressed)

        self.textpane.setFont(Font('Monospaced', Font.PLAIN, 11))
        self.burp.customizeUiComponent(self.textpane)

        self.initKeyMap()

        self.document.remove(0, self.document.getLength())
        self.write('Burp Extender Jython Shell', prefix='')
        self.write(self.PS1)

        self.textpane.requestFocus()
        burp.log.info('Interactive interpreter ready...')

    @property
    def document(self):
        return self.textpane.document

    def resetbuffer(self):
        self._buffer = []

    def keyTyped(self, event=None):
        if not self.inLastLine():
            event.consume()

    def keyPressed(self, event):
        if event.keyCode in (KeyEvent.VK_BACK_SPACE, KeyEvent.VK_LEFT):
            self.backspaceListener(event)

    def getText(self):
        start, end = self.__getLastLineOffsets()
        text = self.document.getText(start, end - start)
        return text.rstrip()

    def insertText(self, data):
        position = self.textpane.getCaretPosition()
        self.textpane.select(position, position)
        self.textpane.replaceSelection(data)
        self.textpane.setCaretPosition(position + len(data))

    def replaceText(self, data):
        start, end = self.__getLastLineOffsets()
        self.textpane.select(start, end)
        self.textpane.replaceSelection(data)
        self.textpane.setCaretPosition(start + len(data))

    def write(self, data, color=Color.black, prefix='\n'):
        style = SimpleAttributeSet()

        if color is not None:
            style.addAttribute(StyleConstants.Foreground, color)

        self.document.insertString(self.document.getLength(), prefix + data, style)
        self.textpane.caretPosition = self.document.getLength()

    def enterAction(self, event=None):
        text = self.getText()
        self._buffer.append(text)
        source = '\n'.join(self._buffer)
        more = self.interp.runsource(source)

        if more:
            self.write(self.PS2, color=Color.black)
        else:
            self.resetbuffer()
            self.write(self.PS1)

        self.history.append(text)

    def deleteAction(self, event=None):
        if self.inLastLine():
            if self.textpane.getSelectedText():
                self.document.remove(self.textpane.getSelectionStart(),
                     self.textpane.getSelectionEnd() - self.textpane.getSelectionStart())

            elif self.textpane.getCaretPosition() < self.document.getLength():
                self.document.remove(self.textpane.getCaretPosition(), 1)

    def deleteEndLineAction(self, event=None):
        if self.inLastLine():
            position = self.textpane.getCaretPosition()
            self.textpane.setSelectionStart(position)
            _, end = self.__getLastLineOffsets()
            self.textpane.setSelectionEnd(end - 1)
            self.textpane.cut()

    def homeAction(self, event=None):
        if self.inLastLine():
            start, end = self.__getLastLineOffsets()
            self.textpane.caretPosition = start

    def endAction(self, event=None):
        if self.inLastLine():
            start, end = self.__getLastLineOffsets()
            self.textpane.caretPosition = end - 1

    def pasteAction(self, event=None):
        if self.inLastLine():
            clipboard = Toolkit.getDefaultToolkit().getSystemClipboard()
            clipboard.getContents(self.textpane)
            contents = clipboard.getData(DataFlavor.stringFlavor)

            lines = contents.splitlines()
            for i, line in enumerate(lines):
                self.insertText(line)
                if i < len(lines) - 1:
                    self.enterAction()

    def keyboardInterruptAction(self, event=None):
        self.interp.runsource('raise KeyboardInterrupt\n')
        self.resetbuffer()
        self.write(self.PS1)

    def backspaceListener(self, event=None):
        start, end = self.__getLastLineOffsets()

        if self.textpane.getCaretPosition() <= start and \
            not self.textpane.getSelectedText():
                event.consume()

    def initKeyMap(self):
        import platform
        os_name = platform.java_ver()[-1][0]

        if os_name.startswith('Win'):
            exit_key = KeyEvent.VK_Z
            interrupt_key = KeyEvent.VK_PAUSE
        else:
            exit_key = KeyEvent.VK_D
            interrupt_key = KeyEvent.VK_C

        bindings = [
            (KeyEvent.VK_ENTER, 0, 'jython.enter', self.enterAction),
            (KeyEvent.VK_DELETE, 0, 'jython.delete', self.deleteAction),

            (KeyEvent.VK_HOME, 0, 'jython.home', self.homeAction),
            (KeyEvent.VK_LEFT, InputEvent.META_DOWN_MASK, 'jython.home', self.homeAction),
            (KeyEvent.VK_END, 0, 'jython.end', self.endAction),
            (KeyEvent.VK_RIGHT, InputEvent.META_DOWN_MASK, 'jython.end', self.endAction),

            (KeyEvent.VK_UP, 0, 'jython.up', self.history.historyUp),
            (KeyEvent.VK_DOWN, 0, 'jython.down', self.history.historyDown),

            (KeyEvent.VK_V, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(), 'jython.paste', self.pasteAction),

            (KeyEvent.VK_A, InputEvent.CTRL_MASK, 'jython.home', self.homeAction),
            (KeyEvent.VK_E, InputEvent.CTRL_MASK, 'jython.end', self.endAction),
            (KeyEvent.VK_K, InputEvent.CTRL_MASK, 'jython.deleteEndLine', self.deleteEndLineAction),
            (KeyEvent.VK_Y, InputEvent.CTRL_MASK, 'jython.paste', self.pasteAction),

            #(interrupt_key, InputEvent.CTRL_MASK, 'jython.keyboardInterrupt', self.keyboardInterruptAction),
            ]

        keymap = JTextComponent.addKeymap('jython', self.textpane.getKeymap())

        for key, modifier, name, function in bindings:
            keymap.addActionForKeyStroke(
                    KeyStroke.getKeyStroke(key, modifier),
                    ActionDelegator(name, function))

        self.textpane.keymap = keymap

    def inLastLine(self, include=True):
        start, end = self.__getLastLineOffsets()

        if self.textpane.getSelectedText():
            position = self.textpane.getSelectionStart()
        else:
            position = self.textpane.getCaretPosition()

        if include is True:
            return start <= position <= end

        return start < position <= end

    def __getLastLineOffsets(self):
        firstElement = self.document.getRootElements()[0]
        lines = firstElement.getElementCount()

        start = firstElement.getElement(lines - 1).getStartOffset()
        end = firstElement.getElement(lines - 1).getEndOffset()

        line = self.document.getText(start, end - start)

        if len(line) >= 4 and (line[0:4] == self.PS1 or line[0:4] == self.PS2):
            return start + 4, end

        return start, end