Пример #1
0
    def handleKey(self, key):
        self.valsLock.acquire()

        isKeystrokeConsumed = True
        if uiTools.isScrollKey(key):
            pageHeight = self.getPreferredSize()[0] - 1
            if self._showDetails: pageHeight -= (DETAILS_HEIGHT + 1)
            isChanged = self._scroller.handleKey(key, self._entryLines,
                                                 pageHeight)
            if isChanged: self.redraw(True)
        elif uiTools.isSelectionKey(key):
            self._showDetails = not self._showDetails
            self.redraw(True)
        elif key == ord('s') or key == ord('S'):
            self.showSortDialog()
        elif key == ord('u') or key == ord('U'):
            # provides a menu to pick the connection resolver
            title = "Resolver Util:"
            options = ["auto"] + list(connections.Resolver)
            connResolver = connections.getResolver("tor")

            currentOverwrite = connResolver.overwriteResolver
            if currentOverwrite == None: oldSelection = 0
            else: oldSelection = options.index(currentOverwrite)

            selection = cli.popups.showMenu(title, options, oldSelection)

            # applies new setting
            if selection != -1:
                selectedOption = options[selection] if selection != 0 else None
                connResolver.overwriteResolver = selectedOption
        elif key == ord('l') or key == ord('L'):
            # provides a menu to pick the primary information we list connections by
            title = "List By:"
            options = list(entries.ListingType)

            # dropping the HOSTNAME listing type until we support displaying that content
            options.remove(cli.connections.entries.ListingType.HOSTNAME)

            oldSelection = options.index(self.getListingType())
            selection = cli.popups.showMenu(title, options, oldSelection)

            # applies new setting
            if selection != -1: self.setListingType(options[selection])
        elif key == ord('d') or key == ord('D'):
            # presents popup for raw consensus data
            descriptorPopup.showDescriptorPopup(self)
        elif (key == ord('c') or key == ord('C')) and self.isClientsAllowed():
            countPopup.showCountDialog(countPopup.CountType.CLIENT_LOCALE,
                                       self._clientLocaleUsage)
        elif (key == ord('e') or key == ord('E')) and self.isExitsAllowed():
            countPopup.showCountDialog(countPopup.CountType.EXIT_PORT,
                                       self._exitPortUsage)
        else:
            isKeystrokeConsumed = False

        self.valsLock.release()
        return isKeystrokeConsumed
Пример #2
0
 def handleKey(self, key):
   self.valsLock.acquire()
   
   isKeystrokeConsumed = True
   if uiTools.isScrollKey(key):
     pageHeight = self.getPreferredSize()[0] - 1
     if self._showDetails: pageHeight -= (DETAILS_HEIGHT + 1)
     isChanged = self._scroller.handleKey(key, self._entryLines, pageHeight)
     if isChanged: self.redraw(True)
   elif uiTools.isSelectionKey(key):
     self._showDetails = not self._showDetails
     self.redraw(True)
   elif key == ord('s') or key == ord('S'):
     self.showSortDialog()
   elif key == ord('u') or key == ord('U'):
     # provides a menu to pick the connection resolver
     title = "Resolver Util:"
     options = ["auto"] + connections.Resolver.values()
     connResolver = connections.getResolver("tor")
     
     currentOverwrite = connResolver.overwriteResolver
     if currentOverwrite == None: oldSelection = 0
     else: oldSelection = options.index(currentOverwrite)
     
     selection = cli.popups.showMenu(title, options, oldSelection)
     
     # applies new setting
     if selection != -1:
       selectedOption = options[selection] if selection != 0 else None
       connResolver.overwriteResolver = selectedOption
   elif key == ord('l') or key == ord('L'):
     # provides a menu to pick the primary information we list connections by
     title = "List By:"
     options = entries.ListingType.values()
     
     # dropping the HOSTNAME listing type until we support displaying that content
     options.remove(cli.connections.entries.ListingType.HOSTNAME)
     
     oldSelection = options.index(self._listingType)
     selection = cli.popups.showMenu(title, options, oldSelection)
     
     # applies new setting
     if selection != -1: self.setListingType(options[selection])
   elif key == ord('d') or key == ord('D'):
     # presents popup for raw consensus data
     descriptorPopup.showDescriptorPopup(self)
   elif (key == ord('c') or key == ord('C')) and self.isClientsAllowed():
     countPopup.showCountDialog(countPopup.CountType.CLIENT_LOCALE, self._clientLocaleUsage)
   elif (key == ord('e') or key == ord('E')) and self.isExitsAllowed():
     countPopup.showCountDialog(countPopup.CountType.EXIT_PORT, self._exitPortUsage)
   else: isKeystrokeConsumed = False
   
   self.valsLock.release()
   return isKeystrokeConsumed
Пример #3
0
 def handleKey(self, key):
   self.valsLock.acquire()
   if uiTools.isScrollKey(key):
     pageHeight = self.getPreferredSize()[0] - 1
     detailPanelHeight = self._config["features.config.selectionDetails.height"]
     if detailPanelHeight > 0 and detailPanelHeight + 2 <= pageHeight:
       pageHeight -= (detailPanelHeight + 1)
     
     isChanged = self.scroller.handleKey(key, self.confContents, pageHeight)
     if isChanged: self.redraw(True)
   self.valsLock.release()
Пример #4
0
    def handleKey(self, key):
        self.valsLock.acquire()
        if uiTools.isScrollKey(key):
            pageHeight = self.getPreferredSize()[0] - 1
            detailPanelHeight = self._config[
                "features.config.selectionDetails.height"]
            if detailPanelHeight > 0 and detailPanelHeight + 2 <= pageHeight:
                pageHeight -= (detailPanelHeight + 1)

            isChanged = self.scroller.handleKey(key, self.confContents,
                                                pageHeight)
            if isChanged: self.redraw(True)
        self.valsLock.release()
Пример #5
0
 def handleKey(self, key):
   isKeystrokeConsumed = True
   if uiTools.isScrollKey(key):
     pageHeight = self.getPreferredSize()[0] - 1
     newScroll = uiTools.getScrollPosition(key, self.scroll, pageHeight, self.lastContentHeight)
     
     if self.scroll != newScroll:
       self.valsLock.acquire()
       self.scroll = newScroll
       self.redraw(True)
       self.valsLock.release()
   elif key in (ord('u'), ord('U')):
     self.valsLock.acquire()
     self.showDuplicates = not self.showDuplicates
     self.redraw(True)
     self.valsLock.release()
   elif key == ord('c') or key == ord('C'):
     msg = "This will clear the log. Are you sure (c again to confirm)?"
     keyPress = popups.showMsg(msg, attr = curses.A_BOLD)
     if keyPress in (ord('c'), ord('C')): self.clear()
   elif key == ord('f') or key == ord('F'):
     # Provides menu to pick regular expression filters or adding new ones:
     # for syntax see: http://docs.python.org/library/re.html#regular-expression-syntax
     options = ["None"] + self.filterOptions + ["New..."]
     oldSelection = 0 if not self.regexFilter else 1
     
     # does all activity under a curses lock to prevent redraws when adding
     # new filters
     panel.CURSES_LOCK.acquire()
     try:
       selection = popups.showMenu("Log Filter:", options, oldSelection)
       
       # applies new setting
       if selection == 0:
         self.setFilter(None)
       elif selection == len(options) - 1:
         # selected 'New...' option - prompt user to input regular expression
         self.showFilterPrompt()
       elif selection != -1:
         self.makeFilterSelection(self.filterOptions[selection - 1])
     finally:
       panel.CURSES_LOCK.release()
     
     if len(self.filterOptions) > MAX_REGEX_FILTERS: del self.filterOptions[MAX_REGEX_FILTERS:]
   elif key == ord('e') or key == ord('E'):
     self.showEventSelectionPrompt()
   elif key == ord('a') or key == ord('A'):
     self.showSnapshotPrompt()
   else: isKeystrokeConsumed = False
   
   return isKeystrokeConsumed
 def handleKey(self, key):
   isKeystrokeConsumed = True
   if uiTools.isSelectionKey(key):
     self.prompt()
   elif uiTools.isScrollKey(key) and not self.isInputMode:
     pageHeight = self.getPreferredSize()[0] - 1
     displayLength = len(self.interpretor.getDisplayContents(PROMPT_LINE))
     newScroll = uiTools.getScrollPosition(key, self.scroll, pageHeight, displayLength)
     
     if self.scroll != newScroll:
       self.scroll = newScroll
       self.redraw(True)
   else: isKeystrokeConsumed = False
   
   return isKeystrokeConsumed
Пример #7
0
 def handleKey(self, key):
   if uiTools.isScrollKey(key):
     pageHeight = self.getPreferredSize()[0] - 1
     newScroll = uiTools.getScrollPosition(key, self.scroll, pageHeight, self.lastContentHeight)
     
     if self.scroll != newScroll:
       self.valsLock.acquire()
       self.scroll = newScroll
       self.redraw(True)
       self.valsLock.release()
   elif key in (ord('u'), ord('U')):
     self.valsLock.acquire()
     self.showDuplicates = not self.showDuplicates
     self.redraw(True)
     self.valsLock.release()
Пример #8
0
    def handleKey(self, key):
        if uiTools.isScrollKey(key):
            pageHeight = self.getPreferredSize()[0] - 1
            newScroll = uiTools.getScrollPosition(key, self.scroll, pageHeight,
                                                  self.lastContentHeight)

            if self.scroll != newScroll:
                self.valsLock.acquire()
                self.scroll = newScroll
                self.redraw(True)
                self.valsLock.release()
        elif key in (ord('u'), ord('U')):
            self.valsLock.acquire()
            self.showDuplicates = not self.showDuplicates
            self.redraw(True)
            self.valsLock.release()
Пример #9
0
 def handleKey(self, key):
   self.valsLock.acquire()
   if uiTools.isScrollKey(key):
     pageHeight = self.getPreferredSize()[0] - 1
     newScroll = uiTools.getScrollPosition(key, self.scroll, pageHeight, self._lastContentHeight)
     
     if self.scroll != newScroll:
       self.scroll = newScroll
       self.redraw(True)
   elif key == ord('n') or key == ord('N'):
     self.showLineNum = not self.showLineNum
     self._lastContentHeightArgs = None
     self.redraw(True)
   elif key == ord('s') or key == ord('S'):
     self.stripComments = not self.stripComments
     self._lastContentHeightArgs = None
     self.redraw(True)
   
   self.valsLock.release()
Пример #10
0
    def handleKey(self, key):
        self.valsLock.acquire()
        if uiTools.isScrollKey(key):
            pageHeight = self.getPreferredSize()[0] - 1
            newScroll = uiTools.getScrollPosition(key, self.scroll, pageHeight,
                                                  self._lastContentHeight)

            if self.scroll != newScroll:
                self.scroll = newScroll
                self.redraw(True)
        elif key == ord('n') or key == ord('N'):
            self.showLineNum = not self.showLineNum
            self._lastContentHeightArgs = None
            self.redraw(True)
        elif key == ord('s') or key == ord('S'):
            self.stripComments = not self.stripComments
            self._lastContentHeightArgs = None
            self.redraw(True)

        self.valsLock.release()
Пример #11
0
 def handleKey(self, key):
   # cursor or scroll movement
   
   #if key in (curses.KEY_UP, curses.KEY_DOWN, curses.KEY_PPAGE, curses.KEY_NPAGE):
   if uiTools.isScrollKey(key):
     pageHeight = self.getPreferredSize()[0] - 1
     if self.showingDetails: pageHeight -= 8
     
     self.connectionsLock.acquire()
     try:
       # determines location parameter to use
       if self.isCursorEnabled:
         try: currentLoc = self.connections.index(self.cursorSelection)
         except ValueError: currentLoc = self.cursorLoc # fall back to nearby entry
       else: currentLoc = self.scroll
       
       # location offset
       if key == curses.KEY_UP: shift = -1
       elif key == curses.KEY_DOWN: shift = 1
       elif key == curses.KEY_PPAGE: shift = -pageHeight + 1 if self.isCursorEnabled else -pageHeight
       elif key == curses.KEY_NPAGE: shift = pageHeight - 1 if self.isCursorEnabled else pageHeight
       elif key == curses.KEY_HOME: shift = -currentLoc
       elif key == curses.KEY_END: shift = len(self.connections) # always below the lower bound
       newLoc = currentLoc + shift
       
       # restricts to valid bounds
       maxLoc = len(self.connections) - 1 if self.isCursorEnabled else len(self.connections) - pageHeight
       newLoc = max(0, min(newLoc, maxLoc))
       
       # applies to proper parameter
       if self.isCursorEnabled and self.connections:
         self.cursorSelection, self.cursorLoc = self.connections[newLoc], newLoc
       else: self.scroll = newLoc
     finally:
       self.connectionsLock.release()
   elif key == ord('r') or key == ord('R'):
     self.allowDNS = not self.allowDNS
     if not self.allowDNS: hostnames.setPaused(True)
     elif self.listingType == LIST_HOSTNAME: hostnames.setPaused(False)
   else: return # skip following redraw
   self.redraw(True)
Пример #12
0
    def handleKey(self, key):
        self.valsLock.acquire()
        isKeystrokeConsumed = True
        if uiTools.isScrollKey(key):
            pageHeight = self.getPreferredSize()[0] - 1
            newScroll = uiTools.getScrollPosition(key, self.scroll, pageHeight, self._lastContentHeight)

            if self.scroll != newScroll:
                self.scroll = newScroll
                self.redraw(True)
        elif key == ord("n") or key == ord("N"):
            self.setLineNumberVisible(not self.showLineNum)
        elif key == ord("s") or key == ord("S"):
            self.setCommentsVisible(self.stripComments)
        elif key == ord("r") or key == ord("R"):
            self.reloadTorrc()
        else:
            isKeystrokeConsumed = False

        self.valsLock.release()
        return isKeystrokeConsumed
Пример #13
0
    def handleKey(self, key):
        self.valsLock.acquire()
        isKeystrokeConsumed = True
        if uiTools.isScrollKey(key):
            pageHeight = self.getPreferredSize()[0] - 1
            newScroll = uiTools.getScrollPosition(key, self.scroll, pageHeight,
                                                  self._lastContentHeight)

            if self.scroll != newScroll:
                self.scroll = newScroll
                self.redraw(True)
        elif key == ord('n') or key == ord('N'):
            self.setLineNumberVisible(not self.showLineNum)
        elif key == ord('s') or key == ord('S'):
            self.setCommentsVisible(self.stripComments)
        elif key == ord('r') or key == ord('R'):
            self.reloadTorrc()
        else:
            isKeystrokeConsumed = False

        self.valsLock.release()
        return isKeystrokeConsumed
Пример #14
0
 def handleKey(self, key):
   self.valsLock.acquire()
   isKeystrokeConsumed = True
   if uiTools.isScrollKey(key):
     pageHeight = self.getPreferredSize()[0] - 1
     detailPanelHeight = self._config["features.config.selectionDetails.height"]
     if detailPanelHeight > 0 and detailPanelHeight + 2 <= pageHeight:
       pageHeight -= (detailPanelHeight + 1)
     
     isChanged = self.scroller.handleKey(key, self._getConfigOptions(), pageHeight)
     if isChanged: self.redraw(True)
   elif uiTools.isSelectionKey(key) and self._getConfigOptions():
     # Prompts the user to edit the selected configuration value. The
     # interface is locked to prevent updates between setting the value
     # and showing any errors.
     
     panel.CURSES_LOCK.acquire()
     try:
       selection = self.getSelection()
       configOption = selection.get(Field.OPTION)
       if selection.isUnset(): initialValue = ""
       else: initialValue = selection.get(Field.VALUE)
       
       promptMsg = "%s Value (esc to cancel): " % configOption
       isPrepopulated = self._config["features.config.prepopulateEditValues"]
       newValue = popups.inputPrompt(promptMsg, initialValue if isPrepopulated else "")
       
       if newValue != None and newValue != initialValue:
         try:
           if selection.get(Field.TYPE) == "Boolean":
             # if the value's a boolean then allow for 'true' and 'false' inputs
             if newValue.lower() == "true": newValue = "1"
             elif newValue.lower() == "false": newValue = "0"
           elif selection.get(Field.TYPE) == "LineList":
             # setOption accepts list inputs when there's multiple values
             newValue = newValue.split(",")
           
           torTools.getConn().setOption(configOption, newValue)
           
           # forces the label to be remade with the new value
           selection.labelCache = None
           
           # resets the isDefault flag
           customOptions = torConfig.getCustomOptions()
           selection.fields[Field.IS_DEFAULT] = not configOption in customOptions
           
           self.redraw(True)
         except Exception, exc:
           popups.showMsg("%s (press any key)" % exc)
     finally:
       panel.CURSES_LOCK.release()
   elif key == ord('a') or key == ord('A'):
     self.showAll = not self.showAll
     self.redraw(True)
   elif key == ord('s') or key == ord('S'):
     self.showSortDialog()
   elif key == ord('v') or key == ord('V'):
     self.showWriteDialog()
   else: isKeystrokeConsumed = False
   
   self.valsLock.release()
   return isKeystrokeConsumed
Пример #15
0
def showConfirmationDialog(torrcContents, torrcLocation):
    """
  Shows a confirmation dialog with the given torrc contents, returning CANCEL,
  NEXT, or BACK based on the selection.
  
  Arguments:
    torrcContents - lines of torrc contents to be presented
    torrcLocation - path where the torrc will be placed
  """

    torrcLines = torrcContents.split("\n")
    options = ["Cancel", "Back to Setup", "Start Tor"]

    control = cli.controller.getController()
    screenHeight = control.getScreen().getmaxyx()[0]
    stickyHeight = sum(
        [stickyPanel.getHeight() for stickyPanel in control.getStickyPanels()])
    isScrollbarVisible = len(torrcLines) + stickyHeight + 5 > screenHeight

    xOffset = 3 if isScrollbarVisible else 0
    popup, width, height = cli.popups.init(len(torrcLines) + 5, 84 + xOffset)
    if not popup: return False

    try:
        scroll, selection = 0, 2
        curses.cbreak()

        while True:
            popup.win.erase()
            popup.win.box()

            # renders the scrollbar
            if isScrollbarVisible:
                popup.addScrollBar(scroll, scroll + height - 5,
                                   len(torrcLines), 1, height - 4, 1)

            # shows the path where the torrc will be placed
            titleMsg = "The following will be placed at '%s':" % torrcLocation
            popup.addstr(0, 0, titleMsg, curses.A_STANDOUT)

            # renders the torrc contents
            for i in range(scroll, min(len(torrcLines), height - 5 + scroll)):
                # parses the argument and comment from options
                option, arg, comment = uiTools.cropStr(torrcLines[i], width -
                                                       4 - xOffset), "", ""

                div = option.find("#")
                if div != -1: option, comment = option[:div], option[div:]

                div = option.strip().find(" ")
                if div != -1: option, arg = option[:div], option[div:]

                drawX = 2 + xOffset
                popup.addstr(i + 1 - scroll, drawX, option,
                             curses.A_BOLD | uiTools.getColor("green"))
                drawX += len(option)
                popup.addstr(i + 1 - scroll, drawX, arg,
                             curses.A_BOLD | uiTools.getColor("cyan"))
                drawX += len(arg)
                popup.addstr(i + 1 - scroll, drawX, comment,
                             uiTools.getColor("white"))

            # divider between the torrc and the options
            popup.addch(height - 4, 0, curses.ACS_LTEE)
            popup.addch(height - 4, width, curses.ACS_RTEE)
            popup.hline(height - 4, 1, width - 1)
            if isScrollbarVisible: popup.addch(height - 4, 2, curses.ACS_BTEE)

            # renders the selection options
            confirmationMsg = "Run tor with the above configuration?"
            popup.addstr(height - 3, width - len(confirmationMsg) - 1,
                         confirmationMsg,
                         uiTools.getColor("green") | curses.A_BOLD)

            drawX = width - 1
            for i in range(len(options) - 1, -1, -1):
                optionLabel = " %s " % options[i]
                drawX -= (len(optionLabel) + 4)

                selectionFormat = curses.A_STANDOUT if i == selection else curses.A_NORMAL
                popup.addstr(height - 2, drawX, "[", uiTools.getColor("green"))
                popup.addstr(
                    height - 2, drawX + 1, optionLabel,
                    uiTools.getColor("green") | selectionFormat
                    | curses.A_BOLD)
                popup.addstr(height - 2, drawX + len(optionLabel) + 1, "]",
                             uiTools.getColor("green"))

                drawX -= 1  # space gap between the options

            popup.win.refresh()
            key = cli.controller.getController().getScreen().getch()

            if key == curses.KEY_LEFT:
                selection = (selection - 1) % len(options)
            elif key == curses.KEY_RIGHT:
                selection = (selection + 1) % len(options)
            elif uiTools.isScrollKey(key):
                scroll = uiTools.getScrollPosition(key, scroll, height - 5,
                                                   len(torrcLines))
            elif uiTools.isSelectionKey(key):
                if selection == 0: return CANCEL
                elif selection == 1: return BACK
                else: return NEXT
            elif key in (27, ord('q'), ord('Q')): return CANCEL
    finally:
        cli.popups.finalize()
Пример #16
0
def showDescriptorPopup(connPanel):
  """
  Presents consensus descriptor in popup window with the following controls:
  Up, Down, Page Up, Page Down - scroll descriptor
  Right, Left - next / previous connection
  Enter, Space, d, D - close popup
  
  Arguments:
    connPanel - connection panel providing the dialog
  """
  
  # hides the title of the connection panel
  connPanel.setTitleVisible(False)
  connPanel.redraw(True)
  
  control = cli.controller.getController()
  panel.CURSES_LOCK.acquire()
  isDone = False
  
  try:
    while not isDone:
      selection = connPanel.getSelection()
      if not selection: break
      
      fingerprint = selection.foreign.getFingerprint()
      if fingerprint == "UNKNOWN": fingerprint = None
      
      displayText = getDisplayText(fingerprint)
      displayColor = cli.connections.connEntry.CATEGORY_COLOR[selection.getType()]
      showLineNumber = fingerprint != None
      
      # determines the maximum popup size the displayText can fill
      pHeight, pWidth = getPreferredSize(displayText, connPanel.maxX, showLineNumber)
      
      popup, _, height = cli.popups.init(pHeight, pWidth)
      if not popup: break
      scroll, isChanged = 0, True
      
      try:
        while not isDone:
          if isChanged:
            draw(popup, fingerprint, displayText, displayColor, scroll, showLineNumber)
            isChanged = False
          
          key = control.getScreen().getch()
          
          if uiTools.isScrollKey(key):
            # TODO: This is a bit buggy in that scrolling is by displayText
            # lines rather than the displayed lines, causing issues when
            # content wraps. The result is that we can't have a scrollbar and
            # can't scroll to the bottom if there's a multi-line being
            # displayed. However, trying to correct this introduces a big can
            # of worms and after hours decided that this isn't worth the
            # effort...
            
            newScroll = uiTools.getScrollPosition(key, scroll, height - 2, len(displayText))
            
            if scroll != newScroll:
              scroll, isChanged = newScroll, True
          elif uiTools.isSelectionKey(key) or key in (ord('d'), ord('D')):
            isDone = True # closes popup
          elif key in (curses.KEY_LEFT, curses.KEY_RIGHT):
            # navigation - pass on to connPanel and recreate popup
            connPanel.handleKey(curses.KEY_UP if key == curses.KEY_LEFT else curses.KEY_DOWN)
            break
      finally: cli.popups.finalize()
  finally:
    connPanel.setTitleVisible(True)
    connPanel.redraw(True)
    panel.CURSES_LOCK.release()
Пример #17
0
 def handleKey(self, key):
   self.valsLock.acquire()
   isKeystrokeConsumed = True
   if uiTools.isScrollKey(key):
     pageHeight = self.getPreferredSize()[0] - 1
     detailPanelHeight = CONFIG["features.config.selectionDetails.height"]
     if detailPanelHeight > 0 and detailPanelHeight + 2 <= pageHeight:
       pageHeight -= (detailPanelHeight + 1)
     
     isChanged = self.scroller.handleKey(key, self._getConfigOptions(), pageHeight)
     if isChanged: self.redraw(True)
   elif uiTools.isSelectionKey(key) and self._getConfigOptions():
     # Prompts the user to edit the selected configuration value. The
     # interface is locked to prevent updates between setting the value
     # and showing any errors.
     
     panel.CURSES_LOCK.acquire()
     try:
       selection = self.getSelection()
       configOption = selection.get(Field.OPTION)
       if selection.isUnset(): initialValue = ""
       else: initialValue = selection.get(Field.VALUE)
       
       promptMsg = "%s Value (esc to cancel): " % configOption
       isPrepopulated = CONFIG["features.config.prepopulateEditValues"]
       newValue = popups.inputPrompt(promptMsg, initialValue if isPrepopulated else "")
       
       if newValue != None and newValue != initialValue:
         try:
           if selection.get(Field.TYPE) == "Boolean":
             # if the value's a boolean then allow for 'true' and 'false' inputs
             if newValue.lower() == "true": newValue = "1"
             elif newValue.lower() == "false": newValue = "0"
           elif selection.get(Field.TYPE) == "LineList":
             # setOption accepts list inputs when there's multiple values
             newValue = newValue.split(",")
           
           torTools.getConn().setOption(configOption, newValue)
           
           # forces the label to be remade with the new value
           selection.labelCache = None
           
           # resets the isDefault flag
           customOptions = torConfig.getCustomOptions()
           selection.fields[Field.IS_DEFAULT] = not configOption in customOptions
           
           self.redraw(True)
         except Exception, exc:
           popups.showMsg("%s (press any key)" % exc)
     finally:
       panel.CURSES_LOCK.release()
   elif key == ord('a') or key == ord('A'):
     self.showAll = not self.showAll
     self.redraw(True)
   elif key == ord('s') or key == ord('S'):
     self.showSortDialog()
   elif key == ord('v') or key == ord('V'):
     self.showWriteDialog()
   else: isKeystrokeConsumed = False
   
   self.valsLock.release()
   return isKeystrokeConsumed
Пример #18
0
def showHelpPopup():
  """
  Presents a popup with instructions for the current page's hotkeys. This
  returns the user input used to close the popup. If the popup didn't close
  properly, this is an arrow, enter, or scroll key then this returns None.
  """
  
  popup, _, height = init(9, 80)
  if not popup: return
  
  exitKey = None
  try:
    control = cli.controller.getController()
    pagePanels = control.getDisplayPanels()
    
    # the first page is the only one with multiple panels, and it looks better
    # with the log entries first, so reversing the order
    pagePanels.reverse()
    
    helpOptions = []
    for entry in pagePanels:
      helpOptions += entry.getHelp()
    
    # test doing afterward in case of overwriting
    popup.win.box()
    popup.addstr(0, 0, "Page %i Commands:" % (control.getPage() + 1), curses.A_STANDOUT)
    
    for i in range(len(helpOptions)):
      if i / 2 >= height - 2: break
      
      # draws entries in the form '<key>: <description>[ (<selection>)]', for
      # instance...
      # u: duplicate log entries (hidden)
      key, description, selection = helpOptions[i]
      if key: description = ": " + description
      row = (i / 2) + 1
      col = 2 if i % 2 == 0 else 41
      
      popup.addstr(row, col, key, curses.A_BOLD)
      col += len(key)
      popup.addstr(row, col, description)
      col += len(description)
      
      if selection:
        popup.addstr(row, col, " (")
        popup.addstr(row, col + 2, selection, curses.A_BOLD)
        popup.addstr(row, col + 2 + len(selection), ")")
    
    # tells user to press a key if the lower left is unoccupied
    if len(helpOptions) < 13 and height == 9:
      popup.addstr(7, 2, "Press any key...")
    
    popup.win.refresh()
    curses.cbreak()
    exitKey = control.getScreen().getch()
  finally: finalize()
  
  if not uiTools.isSelectionKey(exitKey) and \
    not uiTools.isScrollKey(exitKey) and \
    not exitKey in (curses.KEY_LEFT, curses.KEY_RIGHT):
    return exitKey
  else: return None
Пример #19
0
def showConfirmationDialog(torrcContents, torrcLocation):
  """
  Shows a confirmation dialog with the given torrc contents, returning CANCEL,
  NEXT, or BACK based on the selection.
  
  Arguments:
    torrcContents - lines of torrc contents to be presented
    torrcLocation - path where the torrc will be placed
  """
  
  torrcLines = torrcContents.split("\n")
  options = ["Cancel", "Back to Setup", "Start Tor"]
  
  control = cli.controller.getController()
  screenHeight = control.getScreen().getmaxyx()[0]
  stickyHeight = sum([stickyPanel.getHeight() for stickyPanel in control.getStickyPanels()])
  isScrollbarVisible = len(torrcLines) + stickyHeight + 5 > screenHeight
  
  xOffset = 3 if isScrollbarVisible else 0
  popup, width, height = cli.popups.init(len(torrcLines) + 5, 84 + xOffset)
  if not popup: return False
  
  try:
    scroll, selection = 0, 2
    curses.cbreak()
    
    while True:
      popup.win.erase()
      popup.win.box()
      
      # renders the scrollbar
      if isScrollbarVisible:
        popup.addScrollBar(scroll, scroll + height - 5, len(torrcLines), 1, height - 4, 1)
      
      # shows the path where the torrc will be placed
      titleMsg = "The following will be placed at '%s':" % torrcLocation
      popup.addstr(0, 0, titleMsg, curses.A_STANDOUT)
      
      # renders the torrc contents
      for i in range(scroll, min(len(torrcLines), height - 5 + scroll)):
        # parses the argument and comment from options
        option, arg, comment = uiTools.cropStr(torrcLines[i], width - 4 - xOffset), "", ""
        
        div = option.find("#")
        if div != -1: option, comment = option[:div], option[div:]
        
        div = option.strip().find(" ")
        if div != -1: option, arg = option[:div], option[div:]
        
        drawX = 2 + xOffset
        popup.addstr(i + 1 - scroll, drawX, option, curses.A_BOLD | uiTools.getColor("green"))
        drawX += len(option)
        popup.addstr(i + 1 - scroll, drawX, arg, curses.A_BOLD | uiTools.getColor("cyan"))
        drawX += len(arg)
        popup.addstr(i + 1 - scroll, drawX, comment, uiTools.getColor("white"))
      
      # divider between the torrc and the options
      popup.addch(height - 4, 0, curses.ACS_LTEE)
      popup.addch(height - 4, width, curses.ACS_RTEE)
      popup.hline(height - 4, 1, width - 1)
      if isScrollbarVisible: popup.addch(height - 4, 2, curses.ACS_BTEE)
      
      # renders the selection options
      confirmationMsg = "Run tor with the above configuration?"
      popup.addstr(height - 3, width - len(confirmationMsg) - 1, confirmationMsg, uiTools.getColor("green") | curses.A_BOLD)
      
      drawX = width - 1
      for i in range(len(options) - 1, -1, -1):
        optionLabel = " %s " % options[i]
        drawX -= (len(optionLabel) + 4)
        
        selectionFormat = curses.A_STANDOUT if i == selection else curses.A_NORMAL
        popup.addstr(height - 2, drawX, "[", uiTools.getColor("green"))
        popup.addstr(height - 2, drawX + 1, optionLabel, uiTools.getColor("green") | selectionFormat | curses.A_BOLD)
        popup.addstr(height - 2, drawX + len(optionLabel) + 1, "]", uiTools.getColor("green"))
        
        drawX -= 1 # space gap between the options
      
      popup.win.refresh()
      key = cli.controller.getController().getScreen().getch()
      
      if key == curses.KEY_LEFT:
        selection = (selection - 1) % len(options)
      elif key == curses.KEY_RIGHT:
        selection = (selection + 1) % len(options)
      elif uiTools.isScrollKey(key):
        scroll = uiTools.getScrollPosition(key, scroll, height - 5, len(torrcLines))
      elif uiTools.isSelectionKey(key):
        if selection == 0: return CANCEL
        elif selection == 1: return BACK
        else: return NEXT
      elif key in (27, ord('q'), ord('Q')): return CANCEL
  finally:
    cli.popups.finalize()
Пример #20
0
def showDescriptorPopup(connPanel):
    """
  Presents consensus descriptor in popup window with the following controls:
  Up, Down, Page Up, Page Down - scroll descriptor
  Right, Left - next / previous connection
  Enter, Space, d, D - close popup
  
  Arguments:
    connPanel - connection panel providing the dialog
  """

    # hides the title of the connection panel
    connPanel.setTitleVisible(False)
    connPanel.redraw(True)

    control = cli.controller.getController()
    panel.CURSES_LOCK.acquire()
    isDone = False

    try:
        while not isDone:
            selection = connPanel.getSelection()
            if not selection: break

            fingerprint = selection.foreign.getFingerprint()
            if fingerprint == "UNKNOWN": fingerprint = None

            displayText = getDisplayText(fingerprint)
            displayColor = cli.connections.connEntry.CATEGORY_COLOR[
                selection.getType()]
            showLineNumber = fingerprint != None

            # determines the maximum popup size the displayText can fill
            pHeight, pWidth = getPreferredSize(displayText, connPanel.maxX,
                                               showLineNumber)

            popup, _, height = cli.popups.init(pHeight, pWidth)
            if not popup: break
            scroll, isChanged = 0, True

            try:
                while not isDone:
                    if isChanged:
                        draw(popup, fingerprint, displayText, displayColor,
                             scroll, showLineNumber)
                        isChanged = False

                    key = control.getScreen().getch()

                    if uiTools.isScrollKey(key):
                        # TODO: This is a bit buggy in that scrolling is by displayText
                        # lines rather than the displayed lines, causing issues when
                        # content wraps. The result is that we can't have a scrollbar and
                        # can't scroll to the bottom if there's a multi-line being
                        # displayed. However, trying to correct this introduces a big can
                        # of worms and after hours decided that this isn't worth the
                        # effort...

                        newScroll = uiTools.getScrollPosition(
                            key, scroll, height - 2, len(displayText))

                        if scroll != newScroll:
                            scroll, isChanged = newScroll, True
                    elif uiTools.isSelectionKey(key) or key in (ord('d'),
                                                                ord('D')):
                        isDone = True  # closes popup
                    elif key in (curses.KEY_LEFT, curses.KEY_RIGHT):
                        # navigation - pass on to connPanel and recreate popup
                        connPanel.handleKey(curses.KEY_UP if key == curses.
                                            KEY_LEFT else curses.KEY_DOWN)
                        break
            finally:
                cli.popups.finalize()
    finally:
        connPanel.setTitleVisible(True)
        connPanel.redraw(True)
        panel.CURSES_LOCK.release()