
    <ik/                        S r SSKrSSKrSSKrSSKrSSKrSSKrSSKrSSKrSSK	rSSK
rSSKrSSKJrJrJrJrJr  SSKJr   SSKJr  SrS r\R4                  S 5       r " S	 S
\R8                  5      rg! \ a	    SSKJr   N;f = f)z7
Handles making requests and formatting the responses.
    N)STANDARD_OUTPUTBOLD_OUTPUTERROR_OUTPUTuses_settingsmsg)format)StringIOd   c                    U (       d   UR                  S5      $ [        R                  R                  R                  U 5      (       a  U $ [        R                  R                  R                  U 5      (       a   UR                  U 5      R                  $ SU ;   d/  [        R                  R                  R                  U 5      (       Ga  SU ;   a  U R                  SS5      u  p#[        R                  R                  R                  U5      (       d  [        SU-  5      eU(       a<  [        R                  R                  R                  U5      (       d  [        SU-  5      e[        U5      nOU Sp20 nUR                  5        HF  nUR                  U:X  d  M  U(       a  UR                   U:X  d  M.  UR                  XER                   '   MH     [#        U5      S	:X  a  [        S
U -  5      e[#        U5      S:X  a  [%        UR'                  5       5      S	   $ SU -  n[)        U5       H  u  pxUSUS-   X(XH   4-  -  nM     [        U5      e[        SU -  5      e!   [        S5      e= f!   [        SU -  5      e= f)a  
Resolves user input into a relay fingerprint. This accepts...

  * Fingerprints
  * Nicknames
  * IPv4 addresses, either with or without an ORPort
  * Empty input, which is resolved to ourselves if we're a relay

:param str arg: input to be resolved to a relay fingerprint
:param stem.control.Controller controller: tor control connection

:returns: **str** for the relay fingerprint

:raises: **ValueError** if we're unable to resolve the input to a relay
fingerprintz,We aren't a relay, no information to providez0Unable to find a relay with the nickname of '%s':   z'%s' isn't a valid IPv4 addressz'%s' isn't a valid portNr   zNo relays found at %szAThere's multiple relays at %s, include a port to specify which.

z  %i. %s:%s, fingerprint: %s
z1'%s' isn't a fingerprint, nickname, or IP address)get_info
ValueErrorstemutil	tor_toolsis_valid_fingerprintis_valid_nicknameget_network_statusr   
connectionis_valid_ipv4_addressrsplitis_valid_portintget_network_statusesaddressor_portlenlistvalues	enumerate)	arg
controllerr   portmatchesdescresponseir   s	            S/home/james-whalen/.local/lib/python3.13/site-packages/stem/interpreter/commands.py_get_fingerprintr+       s*   " 
G  // yy//44Jyy,,S11Q**3/;;; czTYY))??DD
czjja(mgYY!!77@@:WDEE		,,::4@@2T9::Yd4tG//1		 t||t+"&"2"2',,
 2
 7|q.455	W	'.."#A&&VY\\h!'**!4AwQXQa7bbb + x  
H3N
OOSGEFFQICOPPs   I 9I' I$'I7c              #      #    [         R                  [         R                  4nXs[         l        [         l         S v   Uu  [         l        [         l        g ! Uu  [         l        [         l        f = f7fN)sysstdoutstderr)r/   r0   originals      r*   redirectr2   `   sI     ZZ#(!#*cj&	%CJ
XCJ
s   7A2A A2A//A2c                   P    \ rS rSrSrS rS rS rS rS r	S r
\SS	 j5       rS
rg)ControlInterpreterk   zq
Handles issuing requests and providing nicely formed responses, with support
for special irc style subcommands.
c                   ^ ^ / T l         [        R                  R                  T [        [        R
                  UT R                  S.5        UT l        ST l        ST l	        T R                  R                  mUU 4S jnUT R                  l
        g )N)r   zstem.controlr$   eventsTFc                    > T" U 5        TR                   R                  SU 5        [        TR                   5      [        :  a  TR                   R	                  5         g g )Nr   )_received_eventsinsertr   
MAX_EVENTSpop)event_messagehandle_event_realselfs    r*   handle_event_wrapper9ControlInterpreter.__init__.<locals>.handle_event_wrapper   sK    &
""1m4	T""	#j	0!!# 
1    )r9   codeInteractiveConsole__init__r   control
get_events_controller_run_python_commandsis_multiline_context_handle_event)r?   r$   r@   r>   s   `  @r*   rE   ControlInterpreter.__init__q   s    D$$Tll	,  "D $D
 !&D
 ((66$ &:D"rB   c                     [        U R                  5      n[        [        [        R                  U5      5      nU(       a#  U Vs/ s H  o3R
                  U;   d  M  UPM     nnU$ s  snf r-   )r    r9   mapstruppertype)r?   event_typesr7   es       r*   rG   ControlInterpreter.get_events   sQ    $''(Fs399k23K!;6aVV{%:6f;M <s   A%A%c                 j    [         R                  R                  R                  U R                  U5      $ )z{
Performs the '/help' operation, giving usage information for the given
argument or a general summary if there wasn't one.
)r   interpreterhelpr(   rH   )r?   r#   s     r*   do_helpControlInterpreter.do_help   s)       ))$*:*:C@@rB   c           
         UR                  5       R                  5       nSU;   a  U R                  SS2	 [        S/[        Q76 $ SR                  U R                  " U6  Vs/ s H  n[        [        U5      /[        Q76 PM     sn5      $ s  snf )a   
Performs the '/events' operation, dumping the events that we've received
belonging to the given types. If no types are specified then this provides
all buffered events.

If the user runs '/events clear' then this clears the list of events we've
received.
CLEARNzcleared event backlog
)rP   splitr9   r   r   joinrG   rO   )r?   r#   rR   rS   s       r*   	do_eventsControlInterpreter.do_events   sz     ))+##%K+



"+>o>>99Q\@]^@]1fSV6o6@]^__^s    #B
c           	          [        XR                  5      nU R                  R                  US5      nU R                  R                  US5      nSnU R                  R                  US5      nU(       d  [        SU-  /[
        Q76 $ [        R                  R                  R                  SS9nUR                  U5      n	UR                  U5      n
U	 H  nUnM     U
 H  nUnM     / n UR                  [         R"                  " UR$                  5      S   5         UR                  U R                  R'                  SUR$                  -  5      5        U(       a  SSR)                  U5      -  OS	nU(       a  [	        UR*                  5      nOU(       a  [	        UR*                  5      nOS
nUR,                  < SU< S3[        S/[.        Q76 UR$                  < SUR0                  < U< 3-   /nU(       a5  UR                  [        S/[.        Q76 [	        UR2                  5      -   5        UR                  [        S/[.        Q76 SR)                  UR4                  5      -   5        UR                  [        S/[.        Q76 U-   5        U(       a  UR6                  (       a  [        R8                  R:                  R=                  UR6                  5      nS H  nUR?                  US5      nM     S H  nUR?                  US5      nM     UR                  [        S/[.        Q76 U-   5        SU4SU4SU4SU4/n[        S/[@        Q76 nU Hb  u  nnU(       d  M  US	U[        U/[.        Q76 US	/-  nU[	        U5      RC                  5        Vs/ s H  n[        U/[@        Q76 PM     sn-  nMd     SR)                  U5      $ ! [         a#  n[        [	        U5      /[
        Q76 s SnA$ SnAff = f!    GN= f!    GN= fs  snf )z
Performs the '/info' operation, looking up a relay by fingerprint, IP
address, or nickname and printing its descriptor and consensus entries in a
pretty fashion.
Nz+Unable to find consensus information for %s   )timeoutr   zip-to-country/%sz (%s)z,  Unknownz ()z	address: r   ztor version: zflags: zexit policy: )z at z AT @)z dot z DOT .z	contact: zServer Descriptor:zExtrainfo Descriptor:zMicrodescriptor:zRouter Status Entry:zP--------------------------------------------------------------------------------r\   )"r+   rH   r   r   rO   r   r   get_server_descriptorget_microdescriptorr   
descriptorremoteDescriptorDownloaderget_server_descriptorsget_extrainfo_descriptorsappendsocketgethostbyaddrr   r   r^   exit_policynicknamer   r   tor_versionflagscontactr   	str_tools_to_unicodereplacer   
splitlines)r?   r#   r   excns_descserver_descextrainfo_desc
micro_desc
downloaderserver_desc_queryextrainfo_desc_queryr'   address_extrainfoaddress_extrainfo_labelexit_policy_labellinesrw   aliasdescriptor_sectiondivlabellines                         r*   do_infoControlInterpreter.do_info   s   -$S*:*:;k 11+tDG""88dKKN!!55k4HJ AKO_R^__
 ''<<q<IJ"99+F%??L!k " %n % v33GOODQGHt//889Kgoo9]^_ IZg		2C(DD_ak556	j445# ##[1[';'wYp*qqE
 ll6/8K83{?V?V;WWX	LL	0K0499W]]3KKL	LL6+69JJK{**		##//0C0CDg $%//%- $ &%//%- & ll6+44w>? [)/:&w'	 
,O
,C)t	"c6%6+6R@@SY=Q=Q=ST=ST&00=STT *
 99Uo  -CH,|,,-@

^ Us;   O )2O4 7O< P
O1O,&O1,O14O9<Pc                 B   U(       d(  U R                   (       a  SOSn[        SU-  /[        Q76 $ UR                  5       S:X  a  SU l         O/UR                  5       S:X  a  SU l         O[        SU-  /[        Q76 $ U R                   (       a  S	nOS
n[        U/[        Q76 $ )zQ
Performs the '/python' operation, toggling if we accept python commands or
not.
enableddisabledzPython support is currently %s.enableTdisableFzP'%s' is not recognized. Please run either '/python enable' or '/python disable'.zIPython support enabled, we'll now run non-interpreter commands as python.zBPython support disabled, we'll now pass along all commands to tor.)rI   r   r   lowerr   )r?   r#   statusr(   s       r*   	do_pythonControlInterpreter.do_python  s      55y:f5>QQQ		 "&d			!"'dfill|o{||  \hUh(-_--rB   c                    UR                  5       SpTSU;   a  UR                  SS5      u  pESnUR                  S5      (       a  UR                  5       nUS:X  a  [        R
                  " 5       eUS:X  a  U R                  U5      nGOUS:X  a  U R                  U5      nGOUS:X  a  U R                  U5      nGOUS	:X  a  U R                  U5      nGOy[        S
U-  /[        Q76 nGOdUR                  5       nUR                  SS5      S;   a  [        [        S5      /[        Q76 nGO#US:X  a0  U R                  R                  U5        [        R
                  " 5       eXBR!                  S0 5      ;   =(       a    UR                  5       S:g  nU R"                  (       ah  U(       da  [%        5       n['        X5         [(        R*                  R-                  X5      U l        SSS5        UR1                  5       R                  5       nOF [        U R                  R                  U5      R3                  5       R                  5       /[4        Q76 nU(       a  US-  nU(       a  [=        U5        U$ ! , (       d  f       N= f! [        R6                   aC  n	[9        U	[        R
                  5      (       a  e [        [;        U	5      /[        Q76 n Sn	A	NSn	A	ff = f)a  
Runs the given command. Requests starting with a '/' are special commands
to the interpreter, and anything else is sent to the control port.

:param stem.control.Controller controller: tor control connection
:param str command: command to be processed
:param bool print_response: prints the response to stdout if true

:returns: **list** out output lines, each line being a list of
  (msg, format) tuples

:raises: **stem.SocketClosed** if the control connection has been severed
rd    r   /z/quitz/eventsz/infoz/pythonz/helpz'%s' isn't a recognized command+)LOADCONFPOSTDESCRIPTORz"msg.multiline_unimplemented_noticeQUITz
help.usager7   Nr\   )stripr]   
startswithr   r   SocketClosedr_   r   r   rX   r   r   rP   rz   r   rH   getrI   r	   r2   rC   rD   pushrJ   getvalueraw_contentr   ControllerError
isinstancerO   print)
r?   commandconfigprint_responsecmdr#   outputis_tor_commandconsole_outputr|   s
             r*   run_commandControlInterpreter.run_command-  s;   4 }}
cz3"hcF
~~cIIKc	!!)$'>c")$'>c"9GCSlSIIKc	S"	!?	?@AQLQ&=W%!!

< <<XPXAX$$^#:.7(,(?(?(D(DT(SD% 8 "**,224&7D,,009EEGMMObRabF nf	fM' 87 %% 7#t0011c#h66f	7s%   :%I,AI= ,
I:=K9KK)rH   r9   rI   rJ   N)F)__name__
__module____qualname____firstlineno____doc__rE   rG   rX   r_   r   r   r   r   __static_attributes__ rB   r*   r4   r4   k   s@    
:@A`$`D.. Q QrB   r4   )r   rC   
contextlibrq   r.   r   stem.controlstem.descriptor.remotestem.interpreter.helpstem.util.connectionstem.util.str_toolsstem.util.tor_toolsstem.interpreterr   r   r   r   r   stem.util.termr   	cStringIOr	   ImportErrorior;   r+   contextmanagerr2   rD   r4   r   rB   r*   <module>r      s       
        [ [ !  
=P@ & &T00 Tc  s   A7 7BB