diff options
Diffstat (limited to 'lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/app.py')
-rwxr-xr-x | lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/app.py | 674 |
1 files changed, 0 insertions, 674 deletions
diff --git a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/app.py b/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/app.py deleted file mode 100755 index 97f7a42f..00000000 --- a/lib/python2.7/site-packages/Twisted-12.2.0-py2.7-linux-x86_64.egg/twisted/application/app.py +++ /dev/null @@ -1,674 +0,0 @@ -# -*- test-case-name: twisted.test.test_application,twisted.test.test_twistd -*- -# Copyright (c) Twisted Matrix Laboratories. -# See LICENSE for details. - -import sys, os, pdb, getpass, traceback, signal -from operator import attrgetter - -from twisted.python import runtime, log, usage, failure, util, logfile -from twisted.python.versions import Version -from twisted.python.reflect import qual, namedAny -from twisted.python.deprecate import deprecated -from twisted.python.log import ILogObserver -from twisted.persisted import sob -from twisted.application import service, reactors -from twisted.internet import defer -from twisted import copyright, plugin - -# Expose the new implementation of installReactor at the old location. -from twisted.application.reactors import installReactor -from twisted.application.reactors import NoSuchReactor - - - -class _BasicProfiler(object): - """ - @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} - """ - - def __init__(self, profileOutput, saveStats): - self.profileOutput = profileOutput - self.saveStats = saveStats - - - def _reportImportError(self, module, e): - """ - 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. - """ - s = "Failed to import module %s: %s" % (module, e) - s += """ -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. -""" - raise SystemExit(s) - - - -class ProfileRunner(_BasicProfiler): - """ - Runner for the standard profile module. - """ - - def run(self, reactor): - """ - Run reactor under the standard profiler. - """ - try: - import profile - except ImportError, e: - self._reportImportError("profile", e) - - p = profile.Profile() - p.runcall(reactor.run) - if self.saveStats: - p.dump_stats(self.profileOutput) - else: - tmp, sys.stdout = sys.stdout, open(self.profileOutput, 'a') - try: - p.print_stats() - finally: - sys.stdout, tmp = tmp, sys.stdout - tmp.close() - - - -class HotshotRunner(_BasicProfiler): - """ - Runner for the hotshot profile module. - """ - - def run(self, reactor): - """ - Run reactor under the hotshot profiler. - """ - try: - import hotshot.stats - except (ImportError, SystemExit), e: - # Certain versions of Debian (and Debian derivatives) raise - # SystemExit when importing hotshot if the "non-free" profiler - # module is not installed. Someone eventually recognized this - # as a bug and changed the Debian packaged Python to raise - # ImportError instead. Handle both exception types here in - # order to support the versions of Debian which have this - # behavior. The bug report which prompted the introduction of - # this highly undesirable behavior should be available online at - # <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=334067>. - # There seems to be no corresponding bug report which resulted - # in the behavior being removed. -exarkun - self._reportImportError("hotshot", e) - - # this writes stats straight out - p = hotshot.Profile(self.profileOutput) - p.runcall(reactor.run) - if self.saveStats: - # stats are automatically written to file, nothing to do - return - else: - s = hotshot.stats.load(self.profileOutput) - s.strip_dirs() - s.sort_stats(-1) - if getattr(s, 'stream', None) is not None: - # Python 2.5 and above supports a stream attribute - s.stream = open(self.profileOutput, 'w') - s.print_stats() - s.stream.close() - else: - # But we have to use a trick for Python < 2.5 - tmp, sys.stdout = sys.stdout, open(self.profileOutput, 'w') - try: - s.print_stats() - finally: - sys.stdout, tmp = tmp, sys.stdout - tmp.close() - - - -class CProfileRunner(_BasicProfiler): - """ - Runner for the cProfile module. - """ - - def run(self, reactor): - """ - Run reactor under the cProfile profiler. - """ - try: - import cProfile, pstats - except ImportError, e: - self._reportImportError("cProfile", e) - - p = cProfile.Profile() - p.runcall(reactor.run) - if self.saveStats: - p.dump_stats(self.profileOutput) - else: - stream = open(self.profileOutput, 'w') - s = pstats.Stats(p, stream=stream) - s.strip_dirs() - s.sort_stats(-1) - s.print_stats() - stream.close() - - - -class AppProfiler(object): - """ - Class which selects a specific profile runner based on configuration - options. - - @ivar profiler: the name of the selected profiler. - @type profiler: C{str} - """ - profilers = {"profile": ProfileRunner, "hotshot": HotshotRunner, - "cprofile": CProfileRunner} - - def __init__(self, options): - saveStats = options.get("savestats", False) - profileOutput = options.get("profile", None) - self.profiler = options.get("profiler", "hotshot").lower() - if self.profiler in self.profilers: - profiler = self.profilers[self.profiler](profileOutput, saveStats) - self.run = profiler.run - else: - raise SystemExit("Unsupported profiler name: %s" % (self.profiler,)) - - - -class AppLogger(object): - """ - Class managing logging faciliy of the application. - - @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: C{callable} - """ - _observer = None - - def __init__(self, options): - self._logfilename = options.get("logfile", "") - self._observerFactory = options.get("logger") or None - - - def start(self, application): - """ - Initialize the logging system. - - If a customer logger was specified on the command line it will be - used. If not, and an L{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{ILogObserver}. - """ - if self._observerFactory is not None: - observer = self._observerFactory() - else: - observer = application.getComponent(ILogObserver, None) - - if observer is None: - observer = self._getLogObserver() - self._observer = observer - log.startLoggingWithObserver(self._observer) - self._initialLog() - - - def _initialLog(self): - """ - Print twistd start log message. - """ - from twisted.internet import reactor - log.msg("twistd %s (%s %s) starting up." % (copyright.version, - sys.executable, - runtime.shortPythonVersion())) - log.msg('reactor class: %s.' % (qual(reactor.__class__),)) - - - def _getLogObserver(self): - """ - Create a log observer to be added to the logging system before running - this application. - """ - if self._logfilename == '-' or not self._logfilename: - logFile = sys.stdout - else: - logFile = logfile.LogFile.fromFullPath(self._logfilename) - return log.FileLogObserver(logFile).emit - - - def stop(self): - """ - Print twistd stop log message. - """ - log.msg("Server Shut Down.") - if self._observer is not None: - log.removeObserver(self._observer) - self._observer = None - - - -def fixPdb(): - def do_stop(self, arg): - self.clear_all_breaks() - self.set_continue() - from twisted.internet import reactor - reactor.callLater(0, reactor.stop) - return 1 - - - def help_stop(self): - print """stop - Continue execution, then cleanly shutdown the twisted reactor.""" - - - def set_quit(self): - os._exit(0) - - pdb.Pdb.set_quit = set_quit - pdb.Pdb.do_stop = do_stop - pdb.Pdb.help_stop = help_stop - - - -def runReactorWithLogging(config, oldstdout, oldstderr, profiler=None, reactor=None): - """ - 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 C{None}, the global reactor will - be used. - """ - if reactor is None: - from twisted.internet import reactor - try: - if config['profile']: - if profiler is not None: - profiler.run(reactor) - elif config['debug']: - sys.stdout = oldstdout - sys.stderr = oldstderr - if runtime.platformType == 'posix': - signal.signal(signal.SIGUSR2, lambda *args: pdb.set_trace()) - signal.signal(signal.SIGINT, lambda *args: pdb.set_trace()) - fixPdb() - pdb.runcall(reactor.run) - else: - reactor.run() - except: - if config['nodaemon']: - file = oldstdout - else: - file = open("TWISTD-CRASH.log",'a') - traceback.print_exc(file=file) - file.flush() - - - -def getPassphrase(needed): - if needed: - return getpass.getpass('Passphrase: ') - else: - return None - - - -def getSavePassphrase(needed): - if needed: - passphrase = util.getPassword("Encryption passphrase: ") - else: - return None - - - -class ApplicationRunner(object): - """ - 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}. - """ - profilerFactory = AppProfiler - loggerFactory = AppLogger - - def __init__(self, config): - self.config = config - self.profiler = self.profilerFactory(config) - self.logger = self.loggerFactory(config) - - - def run(self): - """ - Run the application. - """ - self.preApplication() - self.application = self.createOrGetApplication() - - self.logger.start(self.application) - - self.postApplication() - self.logger.stop() - - - def startReactor(self, reactor, oldstdout, oldstderr): - """ - Run the reactor with the given configuration. Subclasses should - probably call this from C{postApplication}. - - @see: L{runReactorWithLogging} - """ - runReactorWithLogging( - self.config, oldstdout, oldstderr, self.profiler, reactor) - - - def preApplication(self): - """ - Override in subclass. - - This should set up any state necessary before loading and - running the Application. - """ - raise NotImplementedError() - - - def postApplication(self): - """ - 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. - """ - raise NotImplementedError() - - - def createOrGetApplication(self): - """ - 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. - """ - if self.config.subCommand: - # If a subcommand was given, it's our responsibility to create - # the application, instead of load it from a file. - - # loadedPlugins is set up by the ServerOptions.subCommands - # property, which is iterated somewhere in the bowels of - # usage.Options. - plg = self.config.loadedPlugins[self.config.subCommand] - ser = plg.makeService(self.config.subOptions) - application = service.Application(plg.tapname) - ser.setServiceParent(application) - else: - passphrase = getPassphrase(self.config['encrypted']) - application = getApplication(self.config, passphrase) - return application - - - -def getApplication(config, passphrase): - s = [(config[t], t) - for t in ['python', 'source', 'file'] if config[t]][0] - filename, style = s[0], {'file':'pickle'}.get(s[1],s[1]) - try: - log.msg("Loading %s..." % filename) - application = service.loadApplication(filename, style, passphrase) - log.msg("Loaded.") - except Exception, e: - s = "Failed to load application: %s" % e - if isinstance(e, KeyError) and e.args[0] == "application": - s += """ -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. -""" - traceback.print_exc(file=log.logfile) - log.msg(s) - log.deferr() - sys.exit('\n' + s + '\n') - return application - - - -def _reactorAction(): - return usage.CompleteList([r.shortName for r in reactors.getReactorTypes()]) - - -class ReactorSelectionMixin: - """ - 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. - """ - compData = usage.Completions( - optActions={"reactor": _reactorAction}) - - messageOutput = sys.stdout - _getReactorTypes = staticmethod(reactors.getReactorTypes) - - - def opt_help_reactors(self): - """ - Display a list of possibly available reactor names. - """ - rcts = sorted(self._getReactorTypes(), key=attrgetter('shortName')) - for r in rcts: - self.messageOutput.write(' %-4s\t%s\n' % - (r.shortName, r.description)) - raise SystemExit(0) - - - def opt_reactor(self, shortName): - """ - Which reactor to use (see --help-reactors for a list of possibilities) - """ - # Actually actually actually install the reactor right at this very - # moment, before any other code (for example, a sub-command plugin) - # runs and accidentally imports and installs the default reactor. - # - # This could probably be improved somehow. - try: - installReactor(shortName) - except NoSuchReactor: - msg = ("The specified reactor does not exist: '%s'.\n" - "See the list of available reactors with " - "--help-reactors" % (shortName,)) - raise usage.UsageError(msg) - except Exception, e: - msg = ("The specified reactor cannot be used, failed with error: " - "%s.\nSee the list of available reactors with " - "--help-reactors" % (e,)) - raise usage.UsageError(msg) - else: - self["reactor"] = shortName - opt_r = opt_reactor - - - - -class ServerOptions(usage.Options, ReactorSelectionMixin): - - longdesc = ("twistd reads a twisted.application.service.Application out " - "of a file and runs it.") - - optFlags = [['savestats', None, - "save the Stats object rather than the text output of " - "the profiler."], - ['no_save','o', "do not save state on shutdown"], - ['encrypted', 'e', - "The specified tap/aos file is encrypted."]] - - optParameters = [['logfile','l', None, - "log to a specified file, - for stdout"], - ['logger', None, None, - "A fully-qualified name to a log observer factory to use " - "for the initial log observer. Takes precedence over " - "--logfile and --syslog (when available)."], - ['profile', 'p', None, - "Run in profile mode, dumping results to specified file"], - ['profiler', None, "hotshot", - "Name of the profiler to use (%s)." % - ", ".join(AppProfiler.profilers)], - ['file','f','twistd.tap', - "read the given .tap file"], - ['python','y', None, - "read an application from within a Python file " - "(implies -o)"], - ['source', 's', None, - "Read an application from a .tas file (AOT format)."], - ['rundir','d','.', - 'Change to a supplied directory before running']] - - compData = usage.Completions( - mutuallyExclusive=[("file", "python", "source")], - optActions={"file": usage.CompleteFiles("*.tap"), - "python": usage.CompleteFiles("*.(tac|py)"), - "source": usage.CompleteFiles("*.tas"), - "rundir": usage.CompleteDirs()} - ) - - _getPlugins = staticmethod(plugin.getPlugins) - - def __init__(self, *a, **kw): - self['debug'] = False - usage.Options.__init__(self, *a, **kw) - - - def opt_debug(self): - """ - Run the application in the Python Debugger (implies nodaemon), - sending SIGUSR2 will drop into debugger - """ - defer.setDebugging(True) - failure.startDebugMode() - self['debug'] = True - opt_b = opt_debug - - - def opt_spew(self): - """ - Print an insanely verbose log of everything that happens. - Useful when debugging freezes or locks in complex code.""" - sys.settrace(util.spewer) - try: - import threading - except ImportError: - return - threading.settrace(util.spewer) - - - def parseOptions(self, options=None): - if options is None: - options = sys.argv[1:] or ["--help"] - usage.Options.parseOptions(self, options) - - - def postOptions(self): - if self.subCommand or self['python']: - self['no_save'] = True - if self['logger'] is not None: - try: - self['logger'] = namedAny(self['logger']) - except Exception, e: - raise usage.UsageError("Logger '%s' could not be imported: %s" - % (self['logger'], e)) - - - def subCommands(self): - plugins = self._getPlugins(service.IServiceMaker) - self.loadedPlugins = {} - for plug in sorted(plugins, key=attrgetter('tapname')): - self.loadedPlugins[plug.tapname] = plug - yield (plug.tapname, - None, - # Avoid resolving the options attribute right away, in case - # it's a property with a non-trivial getter (eg, one which - # imports modules). - lambda plug=plug: plug.options(), - plug.description) - subCommands = property(subCommands) - - - -def run(runApp, ServerOptions): - config = ServerOptions() - try: - config.parseOptions() - except usage.error, ue: - print config - print "%s: %s" % (sys.argv[0], ue) - else: - runApp(config) - - - -def convertStyle(filein, typein, passphrase, fileout, typeout, encrypt): - application = service.loadApplication(filein, typein, passphrase) - sob.IPersistable(application).setStyle(typeout) - passphrase = getSavePassphrase(encrypt) - if passphrase: - fileout = None - sob.IPersistable(application).save(filename=fileout, passphrase=passphrase) - - - -def startApplication(application, save): - from twisted.internet import reactor - service.IService(application).startService() - if save: - p = sob.IPersistable(application) - reactor.addSystemEventTrigger('after', 'shutdown', p.save, 'shutdown') - reactor.addSystemEventTrigger('before', 'shutdown', - service.IService(application).stopService) - |