o bqZ@sddlZddlZddlZddlZddlZddlZddlZddlmZddl m Z m Z m Z ddl mZmZddlmZmZddlmZddlmZddlmZdd lmZmZmZmZmZmZdd l m!Z!m"Z"m#Z#Gd d d Z$Gd dde$Z%Gddde$Z&GdddZ'GdddZ(ddZ)d/ddZ*ddZ+ddZ,GdddZ-dd Z.d!d"Z/Gd#d$d$Z0Gd%d&d&ej1e0Z2d'd(Z3d)d*Z4d+d,Z5d-d.Z6dS)0N) attrgetter) copyrightloggerplugin)reactorsservice) NoSuchReactorinstallReactor)defer)_ISupportsExitSignalCapturing)sob)failureloglogfileruntimeusageutil)namedAny namedModulequalc@s eZdZdZddZddZdS)_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} cCs||_||_dSN) profileOutput saveStats)selfrrr9/usr/lib/python3/dist-packages/twisted/application/app.py__init__%s z_BasicProfiler.__init__cCs d|d|}|d7}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. zFailed 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)rmoduleesrrr_reportImportError)sz!_BasicProfiler._reportImportErrorN)__name__ __module__ __qualname____doc__rr#rrrrrs rc@eZdZdZddZdS) ProfileRunnerz1 Runner for the standard profile module. c Cszddl}Wnty}z |d|WYd}~nd}~ww|}||j|jr4||jdSt j t |jd}t _ z| W|t j t _ }| dS|t j t _ }| w)z: Run reactor under the standard profiler. rNprofilea)r* ImportErrorr#Profileruncallrunr dump_statsrsysstdoutopen print_statsclose)rreactorr*r!ptmprrrr/>s"     zProfileRunner.runNr$r%r&r'r/rrrrr)9 r)c@r()CProfileRunnerz) Runner for the cProfile module. c Csz ddl}ddl}Wnty"}z |d|WYd}~nd}~ww|}||j|jr8||j dSt |j d}|j ||d}| | d|WddS1s^wYdS)z: Run reactor under the cProfile profiler. rNcProfilew)stream)r<pstatsr,r#r-r.r/rr0rr3Stats strip_dirs sort_statsr4)rr6r<r@r!r7r>r"rrrr/Ys"    "zCProfileRunner.runNr9rrrrr;Tr:r;c@s"eZdZdZeedZddZdS) AppProfilerz Class which selects a specific profile runner based on configuration options. @ivar profiler: the name of the selected profiler. @type profiler: C{str} )r*cprofilecCsd|dd}|dd}|dd|_|j|jvr*|j|j||}|j|_dStd|j)N savestatsFr*profilerrEzUnsupported profiler name: )getlowerrG profilersr/r)roptionsrrrGrrrrzs    zAppProfiler.__init__N)r$r%r&r'r)r;rJrrrrrrDos  rDc@s<eZdZdZdZddZddZddZd d Zd d Z dS) 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}. NcCs"|dd|_|dp d|_dS)zE Initialize an L{AppLogger} with a L{ServerOptions}. rrN)rH _logfilename_observerFactoryrrKrrrrszAppLogger.__init__cCs|jdur |}n|tjd}|dur|tjd}|dur$|}||_tj|jr3|jg}ntj|jrBt|jg}nt j dt ddt|jg}tj ||dS)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} NaZPassing 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)rO getComponentr ILogObserverr_getLogObserver _observer providedByLegacyLogObserverWrapperwarningswarnDeprecationWarningglobalLogBeginnerbeginLoggingTo _initialLog)r applicationobserver observersrrrstarts(      zAppLogger.startcCsJddlm}t|jdtjtjt dt|jdt |j ddS)z1 Print twistd start log message. rr6z1twistd {version} ({exe} {pyVersion}) starting up.)versionexe pyVersionzreactor class: {reactor}.N) twisted.internetr6r _loggerForinforrdr1 executablershortPythonVersionr __class__)rr6rrrr^s     zAppLogger._initialLogcCs0|jdks|js tj}ntj|j}t|S)zr Create a log observer to be added to the logging system before running this application. -)rNr1r2rLogFile fromFullPathrtextFileLogObserver)rlogFilerrrrUs zAppLogger._getLogObservercCs6t|d|jdurtj|jd|_dSdS)zS Remove all log observers previously set up by L{AppLogger.start}. zServer Shut Down.N)rrhrirVglobalLogPublisherremoveObserverrrrrstops   zAppLogger.stop) r$r%r&r'rVrrbr^rUrurrrrrLs2 rLcCs4dd}dd}dd}|tj_|tj_|tj_dS)NcSs.||ddlm}|d|jdS)Nrrc)clear_all_breaks set_continuergr6 callLaterru)rargr6rrrdo_stops  zfixPdb..do_stopcSs tddS)NzEstop - Continue execution, then cleanly shutdown the twisted reactor.)printrtrrr help_stopszfixPdb..help_stopcSstddS)Nr)os_exitrtrrrset_quitszfixPdb..set_quit)pdbPdbrr{r})r{r}rrrrfixPdbs  rc Cs|dur ddlm}zG|dr|dur||WdSWdS|drK|t_|t_tjdkr?ttj ddttj d dt t |jWdS|WdStyd }|d ra|}ntd d }d}ztj|d|W|r}|YdSYdS|r|www)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. Nrrcr*debugposixcWtSrr set_traceargsrrr+z'runReactorWithLogging..cWrrrrrrrr,rFnodaemonzTWISTD-CRASH.logr+Tfile)rgr6r/r1r2stderrr platformTypesignalSIGUSR2SIGINTrrr. BaseExceptionr3 traceback print_excflushr5)config oldstdout oldstderrrGr6r5rrrrrunReactorWithLogging s>       rcCs|rtdSdS)Nz Passphrase: )getpassneededrrr getPassphrase@ rcCs|rtdSdS)NzEncryption passphrase: )r getPasswordrrrrgetSavePassphraseGrrc@sHeZdZdZeZeZddZddZ ddZ dd Z d d Z d d Z dS)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}. cCs"||_|||_|||_dSr)rprofilerFactoryrG loggerFactoryr)rrrrrrhs zApplicationRunner.__init__cCs6|||_|j|j||jdS)z& Run the application. N)preApplicationcreateOrGetApplicationr_rrbpostApplicationrurtrrrr/ms  zApplicationRunner.runcCsH|dur ddlm}t|j|||j|t|r|j|_dSd|_dS)z Run the reactor with the given configuration. Subclasses should probably call this from C{postApplication}. @see: L{runReactorWithLogging} Nrrc)rgr6rrrGr rW _exitSignal)rr6rrrrr startReactorys     zApplicationRunner.startReactorcCt)z Override in subclass. This should set up any state necessary before loading and running the Application. NotImplementedErrorrtrrrrsz ApplicationRunner.preApplicationcCr)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. rrtrrrrsz!ApplicationRunner.postApplicationcCs^|jjr |jj|jj}||jj}t|j}|||St |jd}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 ApplicationtapnamesetServiceParentrgetApplication)rplgserr_ passphraserrrrs    z(ApplicationRunner.createOrGetApplicationN)r$r%r&r'rDrrLrrr/rrrrrrrrrNs  rc sfdddDd}|dddi|d|d}}ztd|t|||}td W|Styr}z4d |}t|trN|jdd krN|d 7}t j tj d t|t t d|dWYd}~|Sd}~ww)Ncs g|] }|r||fqSrr).0trrr s z"getApplication..)pythonsourcerrrpicklervz Loading %s...zLoaded.zFailed to load application: %sr_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 )rHrmsgrloadApplication Exception isinstanceKeyErrorrrrrdeferrr1exit)rrr"filenamestyler_r!rrrrs$"  rcCstddtDS)NcSsg|]}|jqSr) shortName)rrrrrrsz"_reactorAction..)r CompleteListrgetReactorTypesrrrr_reactorActionsrc@sDeZdZdZejdeidZej Z e e j ZddZddZeZdS) 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. r6) optActionsc Cst|tdd}d}|D]9}zt|j|jd|jdd|jdWqt yG}z|d |j|j|j d 7}WYd }~qd }~ww|r\|jd|jd |j|t d ) zE Display a list of possibly available reactor names. rkeyrMz z<4 rz !{:<4} {} ({}) rNz. reactors not available on this platform: ) sorted_getReactorTypesrr moduleName messageOutputwriter descriptionr,formatrr)rrctsnotWorkingReactorsrr!rrropt_help_reactorss* $  z'ReactorSelectionMixin.opt_help_reactorsc Csfzt|Wn&tyd|f}t|ty,}z d|f}t|d}~ww||d<dS)zX Which reactor to use (see --help-reactors for a list of possibilities) zcThe specified reactor does not exist: '%s'. See the list of available reactors with --help-reactorsztThe specified reactor cannot be used, failed with error: %s. See the list of available reactors with --help-reactorsNr6)r rr UsageErrorr)rrrr!rrr opt_reactors"     z!ReactorSelectionMixin.opt_reactorN)r$r%r&r'r CompletionsrcompDatar1r2r staticmethodrrrrropt_rrrrrrs rc @seZdZdZgdgdgdgZgdgdgddd d d d ejggd gdgdgdgZe j dge de de de ddZ eejZddZddZeZddZd#ddZdd Zed!d"Zd S)$ ServerOptionszQtwistd reads a twisted.application.service.Application out of a file and runs it.)rFNzBsave the Stats object rather than the text output of the profiler.)no_saveozdo not save state on shutdown)rr!z(The specified tap/aos file is encrypted.)rlNz%log to a specified file, - for stdout)rNNzA fully-qualified name to a log observer factory to use for the initial log observer. Takes precedence over --logfile and --syslog (when available).)r*r7Nz7Run in profile mode, dumping results to specified file.rGNrEz!Name of the profiler to use (%s).z, )rfz twistd.tapzread the given .tap file)ryNz:read an application from within a Python file (implies -o))rr"Nz2Read an application from a .tas file (AOT format).)rundird.z-Change to a supplied directory before running)rrrz*.tapz *.(tac|py)z*.tas)rrrr)mutuallyExclusivercOs4d|d<d|vr|d|_ntj|_tj|dS)NFrr2)r2r1rOptionsr)rr+kwrrrrYs  zServerOptions.__init__cCstdtd|d<dS)z Run the application in the Python Debugger (implies nodaemon), sending SIGUSR2 will drop into debugger TrN)r setDebuggingr startDebugModertrrr opt_debugas  zServerOptions.opt_debugcCs>ttjzddl}Wn tyYdSw|tjdS)z Print an insanely verbose log of everything that happens. Useful when debugging freezes or locks in complex code. rN)r1settracerspewer threadingr,)rrrrropt_spewls   zServerOptions.opt_spewcCs.|durtjddp dg}tj||dS)Nrvz--help)r1argvrr parseOptionsrPrrrrxszServerOptions.parseOptionsc Csl|js|dr d|d<|ddur4z t|d|d<WdSty3}z td|d|d}~wwdS)NrTrrz%Logger '{}' could not be imported: {})rrrrrr)rr!rrr postOptions}s zServerOptions.postOptionsccsT|tj}i|_t|tddD]}||j|j<|jd|fdd|jfVqdS)NrrcSs|Sr)rK)plugrrrrrz+ServerOptions.subCommands..) _getPluginsr IServiceMakerrrrrr)rpluginsrrrr subCommandss   zServerOptions.subCommandsr)r$r%r&longdescoptFlagsjoinrDrJ optParametersrr CompleteFiles CompleteDirsrrr getPluginsrrropt_brrrpropertyrrrrrrsJ !    rc Csv|}z|Wn+tjy4}zdtjdd}t|t|d|WYd}~dSd}~ww||dS)N rrQr)rrerrorrr1rr|)runApprruecommstrrrrr/s   r/cCsFt|||}t||t|}|rd}t|j||ddS)N)rr)rrr IPersistablesetStylersave)fileintypeinrfileouttypeoutencryptr_rrr convertStyles rcCsTddlm}t||rt|}|dd|jd|ddt|j dS)Nrrcaftershutdownbefore) rgr6rIService startServicer raddSystemEventTriggerr stopService)r_rr6r7rrrstartApplications  rcCs"t|tjtt|dS)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)rSIG_DFLr~killgetpid)sigrrr_exitWithSignalsr$)NN)7rr~rrr1rrYoperatorrtwistedrrrtwisted.applicationrrtwisted.application.reactorsrr rgr twisted.internet.interfacesr twisted.persistedr twisted.pythonr rrrrrtwisted.python.reflectrrrrr)r;rDrLrrrrrrrrrrr/rrr$rrrrsD     r 3kE~