本文整理汇总了Python中stem.util.log.info函数的典型用法代码示例。如果您正苦于以下问题:Python info函数的具体用法?Python info怎么用?Python info使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了info函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。
示例1: __init__
def __init__(self, clone = None):
GraphCategory.__init__(self, clone)
if not clone:
# fill in past bandwidth information
controller = tor_controller()
bw_entries, is_successful = controller.get_info('bw-event-cache', None), True
if bw_entries:
for entry in bw_entries.split():
entry_comp = entry.split(',')
if len(entry_comp) != 2 or not entry_comp[0].isdigit() or not entry_comp[1].isdigit():
log.warn(msg('panel.graphing.bw_event_cache_malformed', response = bw_entries))
is_successful = False
break
self.primary.update(int(entry_comp[0]))
self.secondary.update(int(entry_comp[1]))
if is_successful:
log.info(msg('panel.graphing.prepopulation_successful', duration = str_tools.time_label(len(bw_entries.split()), is_long = True)))
read_total = controller.get_info('traffic/read', None)
write_total = controller.get_info('traffic/written', None)
start_time = system.start_time(controller.get_pid(None))
if read_total and write_total and start_time:
self.primary.total = int(read_total)
self.secondary.total = int(write_total)
self.start_time = start_time
示例2: getCorrections
def getCorrections(self):
"""
Performs validation on the loaded contents and provides back the
corrections. If validation is disabled then this won't provide any
results.
"""
self.valsLock.acquire()
if not self.isLoaded(): returnVal = None
else:
torVersion = torTools.getConn().getVersion()
skipValidation = not CONFIG["features.torrc.validate"]
skipValidation |= (torVersion is None or not torVersion.meets_requirements(stem.version.Requirement.GETINFO_CONFIG_TEXT))
if skipValidation:
log.info("Skipping torrc validation (requires tor 0.2.2.7-alpha)")
returnVal = {}
else:
if self.corrections == None:
self.corrections = validate(self.contents)
returnVal = list(self.corrections)
self.valsLock.release()
return returnVal
示例3: send_message
def send_message(control_file, message, raw = False):
"""
Sends a message to the control socket, adding the expected formatting for
single verses multi-line messages. Neither message type should contain an
ending newline (if so it'll be treated as a multi-line message with a blank
line at the end). If the message doesn't contain a newline then it's sent
as...
::
<message>\\r\\n
and if it does contain newlines then it's split on ``\\n`` and sent as...
::
+<line 1>\\r\\n
<line 2>\\r\\n
<line 3>\\r\\n
.\\r\\n
:param file control_file: file derived from the control socket (see the
socket's makefile() method for more information)
:param str message: message to be sent on the control socket
:param bool raw: leaves the message formatting untouched, passing it to the
socket as-is
:raises:
* :class:`stem.SocketError` if a problem arises in using the socket
* :class:`stem.SocketClosed` if the socket is known to be shut down
"""
if not raw:
message = send_formatting(message)
try:
control_file.write(stem.util.str_tools._to_bytes(message))
control_file.flush()
log_message = message.replace('\r\n', '\n').rstrip()
log.trace('Sent to tor:\n' + log_message)
except socket.error as exc:
log.info('Failed to send message: %s' % exc)
# When sending there doesn't seem to be a reliable method for
# distinguishing between failures from a disconnect verses other things.
# Just accounting for known disconnection responses.
if str(exc) == '[Errno 32] Broken pipe':
raise stem.SocketClosed(exc)
else:
raise stem.SocketError(exc)
except AttributeError:
# if the control_file has been closed then flush will receive:
# AttributeError: 'NoneType' object has no attribute 'sendall'
log.info('Failed to send message: file has been closed')
raise stem.SocketClosed('file has been closed')
示例4: _workerLoop
def _workerLoop(self):
"""
Simple producer-consumer loop followed by worker threads. This takes
addresses from the unresolvedQueue, attempts to look up its hostname, and
adds its results or the error to the resolved cache. Resolver reference
provides shared resources used by the thread pool.
"""
while not self.halt:
# if resolver is paused then put a hold on further resolutions
if self.isPaused:
self.cond.acquire()
if not self.halt: self.cond.wait(1)
self.cond.release()
continue
# snags next available ip, timeout is because queue can't be woken up
# when 'halt' is set
try: ipAddr = self.unresolvedQueue.get_nowait()
except Queue.Empty:
# no elements ready, wait a little while and try again
self.cond.acquire()
if not self.halt: self.cond.wait(1)
self.cond.release()
continue
if self.halt: break
try:
if self.useSocketResolution: result = _resolveViaSocket(ipAddr)
else: result = _resolveViaHost(ipAddr)
except IOError, exc: result = exc # lookup failed
except ValueError, exc: result = exc # dns error
self.resolvedLock.acquire()
self.resolvedCache[ipAddr] = (result, RESOLVER_COUNTER.next())
# trim cache if excessively large (clearing out oldest entries)
if len(self.resolvedCache) > CONFIG["cache.hostnames.size"]:
# Providing for concurrent, non-blocking calls require that entries are
# never removed from the cache, so this creates a new, trimmed version
# instead.
# determines minimum age of entries to be kept
currentCount = RESOLVER_COUNTER.next()
newCacheSize = CONFIG["cache.hostnames.size"] - CONFIG["cache.hostnames.trimSize"]
threshold = currentCount - newCacheSize
newCache = {}
msg = "trimming hostname cache from %i entries to %i" % (len(self.resolvedCache), newCacheSize)
log.info(msg)
# checks age of each entry, adding to toDelete if too old
for ipAddr, entry in self.resolvedCache.iteritems():
if entry[1] >= threshold: newCache[ipAddr] = entry
self.resolvedCache = newCache
self.resolvedLock.release()
示例5: _notify_of_unknown_events
def _notify_of_unknown_events():
"""
Provides a notice about any event types tor supports but nyx doesn't.
"""
missing_events = nyx.arguments.missing_event_types()
if missing_events:
log.info('setup.unknown_event_types', event_types = ', '.join(missing_events))
示例6: _setup_freebsd_chroot
def _setup_freebsd_chroot(controller, config):
"""
If we're running under FreeBSD then check the system for a chroot path.
"""
if not config.get('tor.chroot', None) and platform.system() == 'FreeBSD':
jail_chroot = stem.util.system.bsd_jail_path(controller.get_pid(0))
if jail_chroot and os.path.exists(jail_chroot):
log.info('setup.set_freebsd_chroot', path = jail_chroot)
config.set('tor.chroot', jail_chroot)
示例7: __init__
def __init__(self, processName, processPid = "", resolveRate = None, handle = None):
"""
Initializes a new resolver daemon. When no longer needed it's suggested
that this is stopped.
Arguments:
processName - name of the process being resolved
processPid - pid of the process being resolved
resolveRate - time between resolving connections (in seconds, None if
chosen dynamically)
handle - name used to query this resolver, this is the processName
if undefined
"""
threading.Thread.__init__(self)
self.setDaemon(True)
self.processName = processName
self.processPid = processPid
self.resolveRate = resolveRate
self.handle = handle if handle else processName
self.defaultRate = CONFIG["queries.connections.minRate"]
self.lastLookup = -1
self.overwriteResolver = None
self.defaultResolver = Resolver.PROC
osType = os.uname()[0]
self.resolverOptions = getSystemResolvers(osType)
log.info("Operating System: %s, Connection Resolvers: %s" % (osType, ", ".join(self.resolverOptions)))
# sets the default resolver to be the first found in the system's PATH
# (left as netstat if none are found)
for resolver in self.resolverOptions:
# Resolver strings correspond to their command with the exception of bsd
# resolvers.
resolverCmd = resolver.replace(" (bsd)", "")
if resolver == Resolver.PROC or system.is_available(resolverCmd):
self.defaultResolver = resolver
break
self._connections = [] # connection cache (latest results)
self._resolutionCounter = 0 # number of successful connection resolutions
self._isPaused = False
self._halt = False # terminates thread if true
self._cond = threading.Condition() # used for pausing the thread
self._subsiquentFailures = 0 # number of failed resolutions with the default in a row
self._resolverBlacklist = [] # resolvers that have failed to resolve
# Number of sequential times the threshold rate's been too low. This is to
# avoid having stray spikes up the rate.
self._rateThresholdBroken = 0
示例8: _initColors
def _initColors():
"""
Initializes color mappings usable by curses. This can only be done after
calling curses.initscr().
"""
global COLOR_ATTR_INITIALIZED, COLOR_IS_SUPPORTED
if not COLOR_ATTR_INITIALIZED:
# hack to replace all ACS characters with '+' if ACS support has been
# manually disabled
if not CONFIG["features.acsSupport"]:
for item in curses.__dict__:
if item.startswith("ACS_"):
curses.__dict__[item] = ord('+')
# replace a few common border pipes that are better rendered as '|' or
# '-' instead
curses.ACS_SBSB = ord('|')
curses.ACS_VLINE = ord('|')
curses.ACS_BSBS = ord('-')
curses.ACS_HLINE = ord('-')
COLOR_ATTR_INITIALIZED = True
COLOR_IS_SUPPORTED = False
if not CONFIG["features.colorInterface"]: return
try: COLOR_IS_SUPPORTED = curses.has_colors()
except curses.error: return # initscr hasn't been called yet
# initializes color mappings if color support is available
if COLOR_IS_SUPPORTED:
colorpair = 0
log.info("Terminal color support detected and enabled")
for colorName in COLOR_LIST:
fgColor = COLOR_LIST[colorName]
bgColor = -1 # allows for default (possibly transparent) background
colorpair += 1
curses.init_pair(colorpair, fgColor, bgColor)
COLOR_ATTR[colorName] = curses.color_pair(colorpair)
else:
log.info("Terminal color support unavailable")
示例9: get_corrections
def get_corrections(self):
"""
Performs validation on the loaded contents and provides back the
corrections. If validation is disabled then this won't provide any
results.
"""
with self._vals_lock:
if not self.is_loaded():
return None
else:
tor_version = tor_controller().get_version(None)
skip_validation = not CONFIG['features.torrc.validate']
skip_validation |= (tor_version is None or not tor_version >= stem.version.Requirement.GETINFO_CONFIG_TEXT)
if skip_validation:
log.info('Skipping torrc validation (requires tor 0.2.2.7-alpha)')
return {}
else:
if self.corrections is None:
self.corrections = validate(self.contents)
return list(self.corrections)
示例10: startTorMonitor
def startTorMonitor(startTime):
"""
Initializes the interface and starts the main draw loop.
Arguments:
startTime - unix time for when arm was started
"""
# attempts to fetch the tor pid, warning if unsuccessful (this is needed for
# checking its resource usage, among other things)
conn = torTools.getConn()
torPid = conn.getMyPid()
if not torPid and conn.isAlive():
log.warn("Unable to determine Tor's pid. Some information, like its resource usage will be unavailable.")
# adds events needed for arm functionality to the torTools REQ_EVENTS
# mapping (they're then included with any setControllerEvents call, and log
# a more helpful error if unavailable)
torTools.REQ_EVENTS["BW"] = "bandwidth graph won't function"
if not CONFIG["startup.blindModeEnabled"]:
# The DisableDebuggerAttachment will prevent our connection panel from really
# functioning. It'll have circuits, but little else. If this is the case then
# notify the user and tell them what they can do to fix it.
if conn.getOption("DisableDebuggerAttachment", None) == "1":
log.notice(
"Tor is preventing system utilities like netstat and lsof from working. This means that arm can't provide you with connection information. You can change this by adding 'DisableDebuggerAttachment 0' to your torrc and restarting tor. For more information see...\nhttps://trac.torproject.org/3313"
)
connections.getResolver("tor").setPaused(True)
else:
torTools.REQ_EVENTS["CIRC"] = "may cause issues in identifying client connections"
# Configures connection resoultions. This is paused/unpaused according to
# if Tor's connected or not.
conn.addStatusListener(connResetListener)
if torPid:
# use the tor pid to help narrow connection results
torCmdName = sysTools.getProcessName(torPid, "tor")
connections.getResolver(torCmdName, torPid, "tor")
else:
# constructs singleton resolver and, if tor isn't connected, initizes
# it to be paused
connections.getResolver("tor").setPaused(not conn.isAlive())
# hack to display a better (arm specific) notice if all resolvers fail
connections.RESOLVER_FINAL_FAILURE_MSG = "We were unable to use any of your system's resolvers to get tor's connections. This is fine, but means that the connections page will be empty. This is usually permissions related so if you would like to fix this then run arm with the same user as tor (ie, \"sudo -u <tor user> arm\")."
# provides a notice about any event types tor supports but arm doesn't
missingEventTypes = cli.logPanel.getMissingEventTypes()
if missingEventTypes:
pluralLabel = "s" if len(missingEventTypes) > 1 else ""
log.info(
"arm doesn't recognize the following event type%s: %s (log 'UNKNOWN' events to see them)"
% (pluralLabel, ", ".join(missingEventTypes))
)
try:
curses.wrapper(drawTorMonitor, startTime)
except KeyboardInterrupt:
# Skip printing stack trace in case of keyboard interrupt. The
# HALT_ACTIVITY attempts to prevent daemons from triggering a curses redraw
# (which would leave the user's terminal in a screwed up state). There is
# still a tiny timing issue here (after the exception but before the flag
# is set) but I've never seen it happen in practice.
panel.HALT_ACTIVITY = True
shutdownDaemons()
示例11: msg
def msg(self, message):
"""
Sends a message to our control socket and provides back its reply.
:param str message: message to be formatted and sent to tor
:returns: :class:`stem.response.ControlMessage` with the response
:raises:
* :class:`stem.socket.ProtocolError` the content from the socket is malformed
* :class:`stem.socket.SocketError` if a problem arises in using the socket
* :class:`stem.socket.SocketClosed` if the socket is shut down
"""
with self._msg_lock:
# If our _reply_queue isn't empty then one of a few things happened...
#
# - Our connection was closed and probably re-restablished. This was
# in reply to pulling for an asynchronous event and getting this is
# expected - ignore it.
#
# - Pulling for asynchronous events produced an error. If this was a
# ProtocolError then it's a tor bug, and if a non-closure SocketError
# then it was probably a socket glitch. Deserves an INFO level log
# message.
#
# - This is a leftover response for a msg() call. We can't tell who an
# exception was airmarked for, so we only know that this was the case
# if it's a ControlMessage. This should not be possable and indicates
# a stem bug. This deserves a NOTICE level log message since it
# indicates that one of our callers didn't get their reply.
while not self._reply_queue.empty():
try:
response = self._reply_queue.get_nowait()
if isinstance(response, stem.socket.SocketClosed):
pass # this is fine
elif isinstance(response, stem.socket.ProtocolError):
log.info("Tor provided a malformed message (%s)" % response)
elif isinstance(response, stem.socket.ControllerError):
log.info("Socket experienced a problem (%s)" % response)
elif isinstance(response, stem.response.ControlMessage):
log.notice("BUG: the msg() function failed to deliver a response: %s" % response)
except Queue.Empty:
# the empty() method is documented to not be fully reliable so this
# isn't entirely surprising
break
try:
self._socket.send(message)
response = self._reply_queue.get()
# If the message we received back had an exception then re-raise it to the
# caller. Otherwise return the response.
if isinstance(response, stem.socket.ControllerError):
raise response
else:
return response
except stem.socket.SocketClosed, exc:
# If the recv() thread caused the SocketClosed then we could still be
# in the process of closing. Calling close() here so that we can
# provide an assurance to the caller that when we raise a SocketClosed
# exception we are shut down afterward for realz.
self.close()
raise exc
示例12: authenticate_safecookie
authenticate_safecookie(controller, cookie_path, False)
else:
authenticate_cookie(controller, cookie_path, False)
return # success!
except OpenAuthRejected, exc:
auth_exceptions.append(exc)
except IncorrectPassword, exc:
auth_exceptions.append(exc)
except PasswordAuthRejected, exc:
# Since the PROTOCOLINFO says password auth is available we can assume
# that if PasswordAuthRejected is raised it's being raised in error.
log.debug("The authenticate_password method raised a PasswordAuthRejected when password auth should be available. Stem may need to be corrected to recognize this response: %s" % exc)
auth_exceptions.append(IncorrectPassword(str(exc)))
except AuthSecurityFailure, exc:
log.info("Tor failed to provide the nonce expected for safecookie authentication. (%s)" % exc)
auth_exceptions.append(exc)
except (InvalidClientNonce, UnrecognizedAuthChallengeMethod, AuthChallengeFailed), exc:
auth_exceptions.append(exc)
except (IncorrectCookieSize, UnreadableCookieFile, IncorrectCookieValue), exc:
auth_exceptions.append(exc)
except CookieAuthRejected, exc:
auth_func = "authenticate_safecookie" if exc.is_safecookie else "authenticate_cookie"
log.debug("The %s method raised a CookieAuthRejected when cookie auth should be available. Stem may need to be corrected to recognize this response: %s" % (auth_func, exc))
auth_exceptions.append(IncorrectCookieValue(str(exc), exc.cookie_path, exc.is_safecookie))
except stem.ControllerError, exc:
auth_exceptions.append(AuthenticationFailure(str(exc)))
# All authentication attempts failed. Raise the exception that takes priority
# according to our pydocs.
示例13: _parse_message
def _parse_message(self):
# Example:
# 250-PROTOCOLINFO 1
# 250-AUTH METHODS=COOKIE COOKIEFILE="/home/atagar/.tor/control_auth_cookie"
# 250-VERSION Tor="0.2.1.30"
# 250 OK
self.protocol_version = None
self.tor_version = None
self.auth_methods = ()
self.unknown_auth_methods = ()
self.cookie_path = None
auth_methods, unknown_auth_methods = [], []
remaining_lines = list(self)
if not self.is_ok() or not remaining_lines.pop() == "OK":
raise stem.ProtocolError("PROTOCOLINFO response didn't have an OK status:\n%s" % self)
# sanity check that we're a PROTOCOLINFO response
if not remaining_lines[0].startswith("PROTOCOLINFO"):
raise stem.ProtocolError("Message is not a PROTOCOLINFO response:\n%s" % self)
while remaining_lines:
line = remaining_lines.pop(0)
line_type = line.pop()
if line_type == "PROTOCOLINFO":
# Line format:
# FirstLine = "PROTOCOLINFO" SP PIVERSION CRLF
# PIVERSION = 1*DIGIT
if line.is_empty():
raise stem.ProtocolError("PROTOCOLINFO response's initial line is missing the protocol version: %s" % line)
try:
self.protocol_version = int(line.pop())
except ValueError:
raise stem.ProtocolError("PROTOCOLINFO response version is non-numeric: %s" % line)
# The piversion really should be "1" but, according to the spec, tor
# does not necessarily need to provide the PROTOCOLINFO version that we
# requested. Log if it's something we aren't expecting but still make
# an effort to parse like a v1 response.
if self.protocol_version != 1:
log.info("We made a PROTOCOLINFO version 1 query but got a version %i response instead. We'll still try to use it, but this may cause problems." % self.protocol_version)
elif line_type == "AUTH":
# Line format:
# AuthLine = "250-AUTH" SP "METHODS=" AuthMethod *("," AuthMethod)
# *(SP "COOKIEFILE=" AuthCookieFile) CRLF
# AuthMethod = "NULL" / "HASHEDPASSWORD" / "COOKIE"
# AuthCookieFile = QuotedString
# parse AuthMethod mapping
if not line.is_next_mapping("METHODS"):
raise stem.ProtocolError("PROTOCOLINFO response's AUTH line is missing its mandatory 'METHODS' mapping: %s" % line)
for method in line.pop_mapping()[1].split(","):
if method == "NULL":
auth_methods.append(AuthMethod.NONE)
elif method == "HASHEDPASSWORD":
auth_methods.append(AuthMethod.PASSWORD)
elif method == "COOKIE":
auth_methods.append(AuthMethod.COOKIE)
elif method == "SAFECOOKIE":
auth_methods.append(AuthMethod.SAFECOOKIE)
else:
unknown_auth_methods.append(method)
message_id = "stem.response.protocolinfo.unknown_auth_%s" % method
log.log_once(message_id, log.INFO, "PROTOCOLINFO response included a type of authentication that we don't recognize: %s" % method)
# our auth_methods should have a single AuthMethod.UNKNOWN entry if
# any unknown authentication methods exist
if not AuthMethod.UNKNOWN in auth_methods:
auth_methods.append(AuthMethod.UNKNOWN)
# parse optional COOKIEFILE mapping (quoted and can have escapes)
if line.is_next_mapping("COOKIEFILE", True, True):
self.cookie_path = line.pop_mapping(True, True)[1]
elif line_type == "VERSION":
# Line format:
# VersionLine = "250-VERSION" SP "Tor=" TorVersion OptArguments CRLF
# TorVersion = QuotedString
if not line.is_next_mapping("Tor", True):
raise stem.ProtocolError("PROTOCOLINFO response's VERSION line is missing its mandatory tor version mapping: %s" % line)
try:
self.tor_version = stem.version.Version(line.pop_mapping(True)[1])
except ValueError as exc:
raise stem.ProtocolError(exc)
else:
log.debug("Unrecognized PROTOCOLINFO line type '%s', ignoring it: %s" % (line_type, line))
self.auth_methods = tuple(auth_methods)
self.unknown_auth_methods = tuple(unknown_auth_methods)
示例14: recv_message
def recv_message(control_file):
"""
Pulls from a control socket until we either have a complete message or
encounter a problem.
:param file control_file: file derived from the control socket (see the
socket's makefile() method for more information)
:returns: :class:`~stem.response.ControlMessage` read from the socket
:raises:
* :class:`stem.ProtocolError` the content from the socket is malformed
* :class:`stem.SocketClosed` if the socket closes before we receive
a complete message
"""
parsed_content, raw_content = [], ""
logging_prefix = "Error while receiving a control message (%s): "
while True:
try:
line = control_file.readline()
except AttributeError:
# if the control_file has been closed then we will receive:
# AttributeError: 'NoneType' object has no attribute 'recv'
prefix = logging_prefix % "SocketClosed"
log.info(prefix + "socket file has been closed")
raise stem.SocketClosed("socket file has been closed")
except socket.error, exc:
# when disconnected we get...
# socket.error: [Errno 107] Transport endpoint is not connected
prefix = logging_prefix % "SocketClosed"
log.info(prefix + "received exception \"%s\"" % exc)
raise stem.SocketClosed(exc)
raw_content += line
# Parses the tor control lines. These are of the form...
# <status code><divider><content>\r\n
if len(line) == 0:
# if the socket is disconnected then the readline() method will provide
# empty content
prefix = logging_prefix % "SocketClosed"
log.info(prefix + "empty socket content")
raise stem.SocketClosed("Received empty socket content.")
elif len(line) < 4:
prefix = logging_prefix % "ProtocolError"
log.info(prefix + "line too short, \"%s\"" % log.escape(line))
raise stem.ProtocolError("Badly formatted reply line: too short")
elif not re.match(r'^[a-zA-Z0-9]{3}[-+ ]', line):
prefix = logging_prefix % "ProtocolError"
log.info(prefix + "malformed status code/divider, \"%s\"" % log.escape(line))
raise stem.ProtocolError("Badly formatted reply line: beginning is malformed")
elif not line.endswith("\r\n"):
prefix = logging_prefix % "ProtocolError"
log.info(prefix + "no CRLF linebreak, \"%s\"" % log.escape(line))
raise stem.ProtocolError("All lines should end with CRLF")
line = line[:-2] # strips off the CRLF
status_code, divider, content = line[:3], line[3], line[4:]
if divider == "-":
# mid-reply line, keep pulling for more content
parsed_content.append((status_code, divider, content))
elif divider == " ":
# end of the message, return the message
parsed_content.append((status_code, divider, content))
log_message = raw_content.replace("\r\n", "\n").rstrip()
log.trace("Received from tor:\n" + log_message)
return stem.response.ControlMessage(parsed_content, raw_content)
elif divider == "+":
# data entry, all of the following lines belong to the content until we
# get a line with just a period
while True:
try:
line = control_file.readline()
except socket.error, exc:
prefix = logging_prefix % "SocketClosed"
log.info(prefix + "received an exception while mid-way through a data reply (exception: \"%s\", read content: \"%s\")" % (exc, log.escape(raw_content)))
raise stem.SocketClosed(exc)
raw_content += line
if not line.endswith("\r\n"):
prefix = logging_prefix % "ProtocolError"
log.info(prefix + "CRLF linebreaks missing from a data reply, \"%s\"" % log.escape(raw_content))
raise stem.ProtocolError("All lines should end with CRLF")
elif line == ".\r\n":
break # data block termination
line = line[:-2] # strips off the CRLF
# lines starting with a period are escaped by a second period (as per
#.........这里部分代码省略.........
示例15: drawTorMonitor
def drawTorMonitor(stdscr, startTime):
"""
Main draw loop context.
Arguments:
stdscr - curses window
startTime - unix time for when arm was started
"""
initController(stdscr, startTime)
control = getController()
# provides notice about any unused config keys
for key in conf.get_config("arm").unused_keys():
log.notice("Unused configuration entry: %s" % key)
# tells daemon panels to start
for panelImpl in control.getDaemonPanels():
panelImpl.start()
# allows for background transparency
try:
curses.use_default_colors()
except curses.error:
pass
# makes the cursor invisible
try:
curses.curs_set(0)
except curses.error:
pass
# logs the initialization time
log.info("arm started (initialization took %0.3f seconds)" % (time.time() - startTime))
# main draw loop
overrideKey = None # uses this rather than waiting on user input
isUnresponsive = False # flag for heartbeat responsiveness check
while not control.isDone():
displayPanels = control.getDisplayPanels()
isUnresponsive = heartbeatCheck(isUnresponsive)
# sets panel visability
for panelImpl in control.getAllPanels():
panelImpl.setVisible(panelImpl in displayPanels)
# redraws the interface if it's needed
control.redraw(False)
stdscr.refresh()
# wait for user keyboard input until timeout, unless an override was set
if overrideKey:
key, overrideKey = overrideKey, None
else:
curses.halfdelay(CONFIG["features.redrawRate"] * 10)
key = stdscr.getch()
if key == curses.KEY_RIGHT:
control.nextPage()
elif key == curses.KEY_LEFT:
control.prevPage()
elif key == ord("p") or key == ord("P"):
control.setPaused(not control.isPaused())
elif key == ord("m") or key == ord("M"):
cli.menu.menu.showMenu()
elif key == ord("q") or key == ord("Q"):
# provides prompt to confirm that arm should exit
if CONFIG["features.confirmQuit"]:
msg = "Are you sure (q again to confirm)?"
confirmationKey = cli.popups.showMsg(msg, attr=curses.A_BOLD)
quitConfirmed = confirmationKey in (ord("q"), ord("Q"))
else:
quitConfirmed = True
if quitConfirmed:
control.quit()
elif key == ord("x") or key == ord("X"):
# provides prompt to confirm that arm should issue a sighup
msg = "This will reset Tor's internal state. Are you sure (x again to confirm)?"
confirmationKey = cli.popups.showMsg(msg, attr=curses.A_BOLD)
if confirmationKey in (ord("x"), ord("X")):
try:
torTools.getConn().reload()
except IOError, exc:
log.error("Error detected when reloading tor: %s" % sysTools.getFileErrorMsg(exc))
elif key == ord("h") or key == ord("H"):
overrideKey = cli.popups.showHelpPopup()