
    ϪfpZ                        d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlmZ d dl	m
Z
mZmZ d dlmZmZ d dlmZmZ d dlmZ d dlmZ d dlmZ d d	lmZmZmZmZmZmZ d d
l m!Z!m"Z"m#Z#  G d d      Z$ G d de$      Z% G d de$      Z& G d d      Z' G d d      Z(d Z)d%dZ*d Z+d Z, G d d      Z-d Z.d Z/ G d d      Z0 G d d ejb                  e0      Z2d! Z3d" Z4d# Z5d$ Z6y)&    N)
attrgetter)	copyrightloggerplugin)reactorsservice)NoSuchReactorinstallReactor)defer)_ISupportsExitSignalCapturing)sob)failureloglogfileruntimeusageutil)namedAnynamedModulequalc                       e Zd ZdZd Zd Zy)_BasicProfilerz
    @ivar saveStats: if C{True}, save the stats information instead of the
        human readable format
    @type saveStats: C{bool}

    @ivar profileOutput: the name of the file use to print profile data.
    @type profileOutput: C{str}
    c                      || _         || _        y N)profileOutput	saveStats)selfr   r   s      9/usr/lib/python3/dist-packages/twisted/application/app.py__init__z_BasicProfiler.__init__%   s    *"    c                 2    d| d| }|dz  }t        |      )z
        Helper method to report an import error with a profile module. This
        has to be explicit because some of these modules are removed by
        distributions due to them being non-free.
        zFailed to import module : z
This is most likely caused by your operating system not including
the module due to it being non-free. Either do not use the option
--profile, or install the module; your operating system vendor
may provide it in a separate package.
)
SystemExit)r   moduleess       r   _reportImportErrorz!_BasicProfiler._reportImportError)   s1     'vhb4	  	 mr    N)__name__
__module____qualname____doc__r   r'    r    r   r   r      s    #r    r   c                       e Zd ZdZd Zy)ProfileRunnerz1
    Runner for the standard profile module.
    c                 @   	 ddl }j                         }|j	                  |j
                         | j                  r|j                  | j                         yt        j                  t        | j                  d      c}t        _
        	 |j                          |t        j                  ct        _
        }|j                          y# t        $ r}| j                  d|       Y d}~d}~ww xY w# |t        j                  ct        _
        }|j                          w xY w)z:
        Run reactor under the standard profiler.
        r   Nprofilea)r0   ImportErrorr'   Profileruncallrunr   
dump_statsr   sysstdoutopenprint_statsclose)r   reactorr0   r%   ptmps         r   r5   zProfileRunner.run>   s    	2 OO			'++>>LL++,!jj$t/A/A3*GOC"%szz
C		  	2##Iq11	2 #&szz
C		s#   C 
C/ 	C,C''C,/.DNr(   r)   r*   r+   r5   r,   r    r   r.   r.   9   s    r    r.   c                       e Zd ZdZd Zy)CProfileRunnerz)
    Runner for the cProfile module.
    c                    	 ddl }ddl}j	                         }|j                  |j                         | j                  r|j                  | j                         yt        | j                  d      5 }j                  ||      }|j                          |j                  d       |j                          ddd       y# t        $ r}| j                  d|       Y d}~d}~ww xY w# 1 sw Y   yxY w)z:
        Run reactor under the cProfile profiler.
        r   NcProfilew)stream)rC   pstatsr2   r'   r3   r4   r5   r   r6   r   r9   Stats
strip_dirs
sort_statsr:   )r   r<   rC   rG   r%   r=   rE   r&   s           r   r5   zCProfileRunner.runY   s    	3 			'++>>LL++,d((#.  &LL6L2R 	     	3##J22	3   s$   C 3AC)	C&
C!!C&)C2Nr?   r,   r    r   rA   rA   T   s     r    rA   c                        e Zd ZdZeedZd Zy)AppProfilerz
    Class which selects a specific profile runner based on configuration
    options.

    @ivar profiler: the name of the selected profiler.
    @type profiler: C{str}
    )r0   cprofilec                 X   |j                  dd      }|j                  dd       }|j                  dd      j                         | _        | j                  | j                  v r2 | j                  | j                     ||      }|j                  | _        y t        d| j                         )N	savestatsFr0   profilerrM   zUnsupported profiler name: )getlowerrP   	profilersr5   r#   )r   optionsr   r   rP   s        r   r   zAppProfiler.__init__z   s    KKU3	It4J
;AAC==DNN*4t~~dmm4]INH||DH:4==/JKKr    N)r(   r)   r*   r+   r.   rA   rS   r   r,   r    r   rL   rL   o   s     *~FILr    rL   c                   2    e Zd ZdZdZd Zd Zd Zd Zd Z	y)	AppLoggera]  
    An L{AppLogger} attaches the configured log observer specified on the
    commandline to a L{ServerOptions} object, a custom L{logger.ILogObserver},
    or a legacy custom {log.ILogObserver}.

    @ivar _logfilename: The name of the file to which to log, if other than the
        default.
    @type _logfilename: C{str}

    @ivar _observerFactory: Callable object that will create a log observer, or
        None.

    @ivar _observer: log observer added at C{start} and removed at C{stop}.
    @type _observer: a callable that implements L{logger.ILogObserver} or
        L{log.ILogObserver}.
    Nc                 f    |j                  dd      | _        |j                  d      xs d| _        y)zE
        Initialize an L{AppLogger} with a L{ServerOptions}.
        r    r   N)rQ   _logfilename_observerFactoryr   rT   s     r   r   zAppLogger.__init__   s-     $KK	26 'H 5 =r    c                    | j                   | j                         }nB|j                  t        j                  d      }| |j                  t        j                  d      }|| j                         }|| _        t        j                  j                  | j                        r| j                  g}nt        j                  j                  | j                        r!t        j                  | j                        g}n<t        j                  dt        d       t        j                  | j                        g}t        j                  j                  |       | j                          y)a  
        Initialize the global logging system for the given application.

        If a custom logger was specified on the command line it will be used.
        If not, and an L{logger.ILogObserver} or legacy L{log.ILogObserver}
        component has been set on C{application}, then it will be used as the
        log observer. Otherwise a log observer will be created based on the
        command line options for built-in loggers (e.g. C{--logfile}).

        @param application: The application on which to check for an
            L{logger.ILogObserver} or legacy L{log.ILogObserver}.
        @type application: L{twisted.python.components.Componentized}
        NaZ  Passing a logger factory which makes log observers which do not implement twisted.logger.ILogObserver or twisted.python.log.ILogObserver to twisted.application.app.AppLogger was deprecated in Twisted 16.2. Please use a factory that produces twisted.logger.ILogObserver (or the legacy twisted.python.log.ILogObserver) implementing objects instead.   )
stacklevel)rZ   getComponentr   ILogObserverr   _getLogObserver	_observer
providedByLegacyLogObserverWrapperwarningswarnDeprecationWarningglobalLogBeginnerbeginLoggingTo_initialLog)r   applicationobserver	observerss       r   startzAppLogger.start   s      ,,,.H"//0C0CTJH&33C4D4DdK++-H!))$..9(I((888HIIMM #  88HII  //	:r    c                 .   ddl m} t        j                  |       j	                  dt
        j                  t        j                  t        j                                t        j                  |       j	                  dt        |j                               y)z1
        Print twistd start log message.
        r   r<   z1twistd {version} ({exe} {pyVersion}) starting up.)versionexe	pyVersionzreactor class: {reactor}.N)twisted.internetr<   r   
_loggerForinfor   rq   r7   
executabler   shortPythonVersionr   	__class__)r   r<   s     r   rj   zAppLogger._initialLog   st     	-$$$?%%002	 	% 	
 	$$$'g6G6G1H 	% 	
r    c                     | j                   dk(  s| j                   st        j                  }n)t        j                  j                  | j                         }t        j                  |      S )zr
        Create a log observer to be added to the logging system before running
        this application.
        -)rY   r7   r8   r   LogFilefromFullPathr   textFileLogObserver)r   logFiles     r   ra   zAppLogger._getLogObserver   sN    
 #4+<+<jjGoo2243D3DEG))'22r    c                     t        j                  |       j                  d       | j                  1t         j                  j                  | j                         d| _        yy)zS
        Remove all log observers previously set up by L{AppLogger.start}.
        zServer Shut Down.N)r   ru   rv   rb   globalLogPublisherremoveObserverr   s    r   stopzAppLogger.stop   sL     	$$$%89>>%%%44T^^D!DN &r    )
r(   r)   r*   r+   rb   r   rn   rj   ra   r   r,   r    r   rV   rV      s(    " I>0d
 	3"r    rV   c                      d } d }d }|t         j                  _        | t         j                  _        |t         j                  _        y )Nc                     | j                          | j                          ddlm} |j	                  d|j
                         y)Nr   rp      )clear_all_breaksset_continuert   r<   	callLaterr   )r   argr<   s      r   do_stopzfixPdb.<locals>.do_stop   s4    ,!W\\*r    c                     t        d       y )NzEstop - Continue execution, then cleanly shutdown the twisted reactor.)printr   s    r   	help_stopzfixPdb.<locals>.help_stop   s    V	
r    c                 .    t        j                  d       y )Nr   )os_exitr   s    r   set_quitzfixPdb.<locals>.set_quit  s    
r    )pdbPdbr   r   r   )r   r   r   s      r   fixPdbr      s6    

  CGGCGGO!CGGr    c                    |ddl m} 	 | d   r||j                  |       y| d   r|t        _        |t        _        t        j                  dk(  rJt        j                  t        j                  d        t        j                  t        j                  d        t                t        j                  |j                         y|j                          yy# t        $ rn d	}| d
   r|}nt        dd      }d}	 t!        j"                  |       |j%                          |r*|j'                          Y y# |r|j'                          w w xY wY yw xY w)aN  
    Start the reactor, using profiling if specified by the configuration, and
    log any error happening in the process.

    @param config: configuration of the twistd application.
    @type config: L{ServerOptions}

    @param oldstdout: initial value of C{sys.stdout}.
    @type oldstdout: C{file}

    @param oldstderr: initial value of C{sys.stderr}.
    @type oldstderr: C{file}

    @param profiler: object used to run the reactor with profiling.
    @type profiler: L{AppProfiler}

    @param reactor: The reactor to use.  If L{None}, the global reactor will
        be used.
    Nr   rp   r0   debugposixc                  *    t        j                         S r   r   	set_traceargss    r   <lambda>z'runReactorWithLogging.<locals>.<lambda>+  s    CMMO r    c                  *    t        j                         S r   r   r   s    r   r   z'runReactorWithLogging.<locals>.<lambda>,  s    3==? r    FnodaemonzTWISTD-CRASH.logr1   Tfile)rt   r<   r5   r7   r8   stderrr   platformTypesignalSIGUSR2SIGINTr   r   r4   BaseExceptionr9   	traceback	print_excflushr;   )config	oldstdout	oldstderrrP   r<   r;   r   s          r   runReactorWithLoggingr     s   ( ,)#W%G_"CJ"CJ##w.fnn.KLfmm-JKHKK$KKM $  *D*C0DE	T*JJL

 

 us5   C B!C C !E9&D3E3EEEc                 2    | rt        j                   d      S y )NzPassphrase: )getpassneededs    r   getPassphraser   @  s    ~..r    c                 2    | rt        j                  d      S y )NzEncryption passphrase: )r   getPasswordr   s    r   getSavePassphraser   G  s     9::r    c                   <    e Zd ZdZeZeZd Zd Z	d Z
d Zd Zd Zy)	ApplicationRunnera  
    An object which helps running an application based on a config object.

    Subclass me and implement preApplication and postApplication
    methods. postApplication generally will want to run the reactor
    after starting the application.

    @ivar config: The config object, which provides a dict-like interface.

    @ivar application: Available in postApplication, but not
       preApplication. This is the application object.

    @ivar profilerFactory: Factory for creating a profiler object, able to
        profile the application if options are set accordingly.

    @ivar profiler: Instance provided by C{profilerFactory}.

    @ivar loggerFactory: Factory for creating object responsible for logging.

    @ivar logger: Instance provided by C{loggerFactory}.
    c                 j    || _         | j                  |      | _        | j                  |      | _        y r   )r   profilerFactoryrP   loggerFactoryr   )r   r   s     r   r   zApplicationRunner.__init__h  s-    ,,V4((0r    c                     | j                          | j                         | _        | j                  j	                  | j                         | j                          | j                  j                          y)z&
        Run the application.
        N)preApplicationcreateOrGetApplicationrk   r   rn   postApplicationr   r   s    r   r5   zApplicationRunner.runm  sU     	668$**+r    c                     |ddl m} t        | j                  ||| j                  |       t        j                  |      r|j                  | _        yd| _        y)z
        Run the reactor with the given configuration.  Subclasses should
        probably call this from C{postApplication}.

        @see: L{runReactorWithLogging}
        Nr   rp   )rt   r<   r   r   rP   r   rc   _exitSignal)r   r<   r   r   s       r   startReactorzApplicationRunner.startReactory  sI     ?0dkk9iPWX(33G<&22D#Dr    c                     t               )z
        Override in subclass.

        This should set up any state necessary before loading and
        running the Application.
        NotImplementedErrorr   s    r   r   z ApplicationRunner.preApplication  s     "##r    c                     t               )z
        Override in subclass.

        This will be called after the application has been loaded (so
        the C{application} attribute will be set). Generally this
        should start the application and run the reactor.
        r   r   s    r   r   z!ApplicationRunner.postApplication  s     "##r    c                    | j                   j                  r| j                   j                  | j                   j                     }|j                  | j                   j                        }t        j                  |j                        }|j                  |       |S t        | j                   d         }t        | j                   |      }|S )a  
        Create or load an Application based on the parameters found in the
        given L{ServerOptions} instance.

        If a subcommand was used, the L{service.IServiceMaker} that it
        represents will be used to construct a service to be added to
        a newly-created Application.

        Otherwise, an application will be loaded based on parameters in
        the config.
        	encrypted)r   
subCommandloadedPluginsmakeService
subOptionsr   ApplicationtapnamesetServiceParentr   getApplication)r   plgserrk   
passphrases        r   r   z(ApplicationRunner.createOrGetApplication  s     ;;!! ++++DKK,B,BCC//$++"8"89C!--ckk:K  -  't{{;'?@J(jAKr    N)r(   r)   r*   r+   rL   r   rV   r   r   r5   r   r   r   r   r,   r    r   r   r   N  s1    , "OM1

$ $$r    r   c                 j   dD cg c]  }| |   s	| |   |f c}d   }|d   ddij                  |d   |d         }}	 t        j                  d|z         t        j                  |||      }t        j                  d       |S c c}w # t
        $ r}d|z  }t        |t              r|j                  d   d	k(  r|d
z  }t        j                  t        j                         t        j                  |       t        j                          t        j                  d|z   dz          Y d }~S d }~ww xY w)N)pythonsourcer   r   r   pickler   zLoading %s...zLoaded.zFailed to load application: %srk   aN  
Could not find 'application' in the file. To use 'twistd -y', your .tac
file must create a suitable object (e.g., by calling service.Application())
and store it in a variable named 'application'. twistd loads your .tac file
and scans the global variables for one of this name.

Please read the 'Using Application' HOWTO for details.
r   
)rQ   r   msgr   loadApplication	Exception
isinstanceKeyErrorr   r   r   r   deferrr7   exit)r   r   tr&   filenamestylerk   r%   s           r   r   r     s   !=KA&)QKANAdVX.221Q41>eH"(*+--hzJ	  + 	L  ",q0a"qvvayM'A  A 	-


D!!"s#   
B	BAB
 
	D2BD--D2c                      t        j                  t        j                         D  cg c]  } | j                   c}       S c c} w r   )r   CompleteListr   getReactorTypes	shortName)rs    r   _reactorActionr     s.    H4L4L4NOqq{{OPPOs   A c                       e Zd ZdZ ej
                  dei      Zej                  Z
 eej                        Zd Zd ZeZy)ReactorSelectionMixinz
    Provides options for selecting a reactor to install.

    If a reactor is installed, the short name which was used to locate it is
    saved as the value for the C{"reactor"} key.
    r<   )
optActionsc           	      L   t        | j                         t        d            }d}|D ]O  }	 t        |j                         | j
                  j                  d|j                  dd|j                   d       Q |rQ| j
                  j                  d       | j
                  j                  d       | j
                  j                  |       t        d	      # t        $ rA}|dj                  |j                  |j                  |j                  d	         z  }Y d
}~d
}~ww xY w)zE
        Display a list of possibly available reactor names.
        r   keyrX   z    z<4	r   z    !{:<4}	{} ({})
r   Nz.    reactors not available on this platform:

)sorted_getReactorTypesr   r   
moduleNamemessageOutputwriter   descriptionr2   formatr   r#   )r   rctsnotWorkingReactorsr   r%   s        r   opt_help_reactorsz'ReactorSelectionMixin.opt_help_reactors  s    d++-:k3JK 		AALL)""((4B/?r!--PR)ST		 $$T*$$E $$%78m  "&=&D&DKKMMFF1I' "s   AC	D#"7DD#c                     	 t        |       || d<   y# t        $ r d|d}t        j                  |      t        $ r }d|d}t        j                  |      d}~ww xY w)zX
        Which reactor to use (see --help-reactors for a list of possibilities)
        r<   z'The specified reactor does not exist: 'z:'.
See the list of available reactors with --help-reactorsz9The specified reactor cannot be used, failed with error: z9.
See the list of available reactors with --help-reactorsN)r
   r	   r   
UsageErrorr   )r   r   r   r%   s       r   opt_reactorz!ReactorSelectionMixin.opt_reactor  sx    	(9%  (DO  	( &/1 
 ""3'' 	( &') 
 ""3''	(s    ,AAAN)r(   r)   r*   r+   r   Completionsr   compDatar7   r8   r   staticmethodr   r   r   r   r   opt_rr,   r    r   r   r     sK     !u  Y,GHHJJM#H$<$<=2(8 Er    r   c            
          e Zd ZdZg dg dg dgZg dg dg ddd	d
ddj                  ej                        z  gg dg dg dg dgZ e	j                  dg e	j                  d       e	j                  d       e	j                  d       e	j                         d      Z eej                         Zd Zd ZeZd ZddZd Zed        Zy	)ServerOptionszQtwistd reads a twisted.application.service.Application out of a file and runs it.)rO   NzBsave the Stats object rather than the text output of the profiler.)no_saveozdo not save state on shutdown)r   r%   z(The specified tap/aos file is encrypted.)r   lNz%log to a specified file, - for stdout)r   NNzA fully-qualified name to a log observer factory to use for the initial log observer.  Takes precedence over --logfile and --syslog (when available).)r0   r=   Nz7Run in profile mode, dumping results to specified file.rP   NrM   z!Name of the profiler to use (%s).z, )r   fz
twistd.tapzread the given .tap file)r   yNz:read an application from within a Python file (implies -o))r   r&   Nz2Read an application from a .tas file (AOT format).)rundird.z-Change to a supplied directory before running)r   r   r   z*.tapz
*.(tac|py)z*.tas)r   r   r   r
  )mutuallyExclusiver   c                     d| d<   d|v r|d   | _         nt        j                   | _         t        j                  j	                  |        y )NFr   r8   )r8   r7   r   Optionsr   )r   r1   kws      r   r   zServerOptions.__init__X  s:    Wr>X,DK**DKt$r    c                 `    t        j                  d       t        j                          d| d<   y)z
        Run the application in the Python Debugger (implies nodaemon),
        sending SIGUSR2 will drop into debugger
        Tr   N)r   setDebuggingr   startDebugModer   s    r   	opt_debugzServerOptions.opt_debug`  s'    
 	4  Wr    c                     t        j                  t        j                         	 ddl}|j                  t        j                         y# t
        $ r Y yw xY w)z
        Print an insanely verbose log of everything that happens.
        Useful when debugging freezes or locks in complex code.
        r   N)r7   settracer   spewer	threadingr2   )r   r  s     r   opt_spewzServerOptions.opt_spewk  sD    
 	T[[!	 	4;;'  		s   A	 		AAc                 x    |t         j                  dd  xs dg}t        j                  j	                  | |       y )Nr   z--help)r7   argvr   r  parseOptionsr[   s     r   r  zServerOptions.parseOptionsw  s1    ?hhqrl0xjG""41r    c                     | j                   s| d   rd| d<   | d   	 t        | d         | d<   y y # t        $ r-}t        j                  dj                  | d   |            d }~ww xY w)Nr   Tr  r   z%Logger '{}' could not be imported: {})r   r   r   r   r   r   )r   r%   s     r   postOptionszServerOptions.postOptions|  sx    ??d8n"DO>%!)$x.!9X &  &&;BB4>STU s   0 	A&(A!!A&c              #      K   | j                  t        j                        }i | _        t	        |t        d            D ]:  }|| j                  |j                  <   |j                  d |fd|j                  f < y w)Nr   r   c                 "    | j                         S r   )rT   )plugs    r   r   z+ServerOptions.subCommands.<locals>.<lambda>  s    $,,. r    )_getPluginsr   IServiceMakerr   r   r   r   r   )r   pluginsr!  s      r   subCommandszServerOptions.subCommands  sx     ""7#8#897
9(=> 
	D/3Dt||, !0   
	s   A;A=r   )r(   r)   r*   longdescoptFlagsjoinrL   rS   optParametersr   r   CompleteFilesCompleteDirsr   r  r   
getPluginsr"  r   r  opt_br  r  r  propertyr%  r,   r    r   r  r    s   	! 	

 	:FH 	H	
	
 /$))K<Q<Q2RR		
 	@	
 	TM=MB !u  78'E''0)e)),7)e))'2(e((*	
H v001K% E
(2
	  r    r  c                      |       }	 |j                           | |       y # t        j                  $ rG}dj                  t        j
                  dd       }t        |       t        | d|        Y d }~y d }~ww xY w)N r   r]   r"   )r  r   errorr(  r7   r  r   )runAppr  r   uecommstrs        r   r5   r5     sn    _F 	v ;; "((388Aa=)f	B4 !!"s   " A<=A77A<c                     t        j                  | ||      }t        j                  |      j	                  |       t        |      }|rd }t        j                  |      j                  ||       y )N)r   r   )r   r   r   IPersistablesetStyler   save)fileintypeinr   fileouttypeoutencryptrk   s          r   convertStyler>    s_    ))&&*EK[!**73"7+J[!&&J&Or    c                     ddl m} t        j                  |       j	                          |r3t        j                  |       }|j                  dd|j                  d       |j                  ddt        j                  |       j                         y )Nr   rp   aftershutdownbefore)
rt   r<   r   IServicestartServicer   r6  addSystemEventTriggerr8  stopService)rk   r8  r<   r=   s       r   startApplicationrG    sm    ([!..0[)%%gz166:N!!*g..{;GGr    c                     t        j                   | t         j                         t        j                  t        j                         |        y)a  
    Force the application to terminate with the specified signal by replacing
    the signal handler with the default and sending the signal to ourselves.

    @param sig:  Signal to use to terminate the process with C{os.kill}.
    @type sig:  C{int}
    N)r   SIG_DFLr   killgetpid)sigs    r   _exitWithSignalrM    s*     MM#v~~&GGBIIKr    )NN)7r   r   r   r   r7   r   re   operatorr   twistedr   r   r   twisted.applicationr   r   twisted.application.reactorsr	   r
   rt   r   twisted.internet.interfacesr   twisted.persistedr   twisted.pythonr   r   r   r   r   r   twisted.python.reflectr   r   r   r   r.   rA   rL   rV   r   r   r   r   r   r   r   r   r  r  r5   r>  rG  rM  r,   r    r   <module>rV     s     	 
  
    - - 1 G " E ! F F > > <N 6 ^  6L L,o" o"d",0fh hV2QB BJzEMM#8 zz	P		r    