<commit_before># Copyright (c) 2010 <NAME>
# See LICENSE for details.

"""
The sparked application launcher.

Sparked applications are launched in a subprocess: so that if the
application crashes, it is started again.
"""

import os
import subprocess
import sys
import time

from twisted.internet import reactor
from twisted.python import usage, log
from twisted.application import service, app

from sparked import application, __version__


class Options(usage.Options):

    longdesc = """The <application> argument specifies a Python module which is executed as the main sparked class. To see which options hold for an application, start:

# sparkd <application> --help
"""

    optFlags = [["debug", "d", "Debug mode"],
                ["no-subprocess", "N", "Do not start a subprocess for crash prevention"],
                ]

    optParameters = [
            ('id', None, None, 'Application id (defaults to the sparked module name)'),
            ('pidfile', None, None, 'Pidfile location (defaults to /tmp/<id>/sparkd.pid)'),
            ('logfile', None, None, 'Pidfile location (defaults to /tmp/<id>/sparkd.log)')
            ]


    def getSynopsis(self):
        return "sparkd [options] <application> [app_options]"

    def opt_version(self):
        print os.path.basename(sys.argv[0]), __version__
        exit(0)


class QuitFlag:
    """
    @ivar file: A C{FilePath} pointing to the quit-flag file.
    """
    def __init__(self, file):
        self.file = file


    def set(self):
        f = self.file.open("w")
        f.write("quit")
        f.close()


    def reset(self):
        try:
            self.file.remove()
        except:
            pass


    def isSet(self):
        try:
            return self.file.open("r").readlines()[0] == "quit"
        except:
            return False




def splitOptions(args):
    try:
        app = [a for a in args if a[0] != "-"][0]
    except IndexError:
        return args, None, []
    i = args.index(app)
    return (args[0:i], app, args[i+1:])


def run(appName):
    application = service.Application(appName)
    
    from sparked import tap
    config = tap.Options()
    config.parseOptions(sys.argv[1:])
    svc = tap.makeService(config)
    svc.setServiceParent(application)
        
    app.startApplication(application, False)
    log.addObserver(log.FileLogObserver(sys.stdout).emit)

    reactor.run()


def launch(baseOptions, env):
    argv = []
    argv.append("twistd")
    argv.append("--pidfile")
    argv.append(baseOptions['pidfile'])
    argv.append('-r')
    argv.append('gtk2')
    argv.append('-n')
    argv.append('sparked')
    argv = argv + sys.argv[1:]

    return subprocess.call(argv, env=env)


def launchLoop(app, options, env, appPath):
    quitFlag = QuitFlag(appPath.child("quitflag"))
    quitFlag.reset()
    respawned = False
    while True:
        start = time.time()
        launch(options, env)
        if time.time() - start < 5:
            if respawned:
                print "*** %s: respawning too fast ***" % app
            break
        if quitFlag.isSet():
            break
        respawned = True

    quitFlag.reset()



def loadModule(app):
    if app[-3:] == ".py" and os.path.exists(app):
        path = os.path.dirname(app)
        if not path: path = "."
        sys.path.insert(0, path)
        app = os.path.basename(app)[:-3]

    try:
        mod = __import__(app, None, None, app.split(".")[-1])
    except ImportError, e:
        log.err(e)
        raise usage.UsageError("Application not found: " + app)
    return mod, app



def main():

    env = os.environ

    try:
        options = Options()
        sparkedOpts, appName, appOpts = splitOptions(sys.argv[1:])
        options.parseOptions(sparkedOpts)

        if not appName:
            options.opt_help()

        appModule, appName = loadModule(appName)

        appPath = application.getTempPath(appName, options['id'])<commit_msg>Fix: --help option triggered a gstreamer help message when importing gst.<commit_after># Copyright (c) 2010 <NAME>
# See LICENSE for details.

"""
The sparked application launcher.

Sparked applications are launched in a subprocess: so that if the
application crashes, it is started again.
"""

import os
import subprocess
import sys
import time

from twisted.internet import reactor
from twisted.python import usage, log
from twisted.application import service, app

from sparked import application, __version__


class Options(usage.Options):

    longdesc = """The <application> argument specifies a Python module which is executed as the main sparked class. To see which options hold for an application, start:

# sparkd <application> --help
"""

    optFlags = [["debug", "d", "Debug mode"],
                ["no-subprocess", "N", "Do not start a subprocess for crash prevention"],
                ]

    optParameters = [
            ('id', None, None, 'Application id (defaults to the sparked module name)'),
            ('pidfile', None, None, 'Pidfile location (defaults to /tmp/<id>/sparkd.pid)'),
            ('logfile', None, None, 'Pidfile location (defaults to /tmp/<id>/sparkd.log)')
            ]


    def getSynopsis(self):
        return "sparkd [options] <application> [app_options]"

    def opt_version(self):
        print os.path.basename(sys.argv[0]), __version__
        exit(0)


class QuitFlag:
    """
    @ivar file: A C{FilePath} pointing to the quit-flag file.
    """
    def __init__(self, file):
        self.file = file


    def set(self):
        f = self.file.open("w")
        f.write("quit")
        f.close()


    def reset(self):
        try:
            self.file.remove()
        except:
            pass


    def isSet(self):
        try:
            return self.file.open("r").readlines()[0] == "quit"
        except:
            return False




def splitOptions(args):
    try:
        app = [a for a in args if a[0] != "-"][0]
    except IndexError:
        return args, None, []
    i = args.index(app)
    return (args[0:i], app, args[i+1:])


def run(appName):
    application = service.Application(appName)
    
    from sparked import tap
    config = tap.Options()
    config.parseOptions(sys.argv[1:])
    svc = tap.makeService(config)
    svc.setServiceParent(application)
        
    app.startApplication(application, False)
    log.addObserver(log.FileLogObserver(sys.stdout).emit)

    reactor.run()


def launch(baseOptions, env):
    argv = []
    argv.append("twistd")
    argv.append("--pidfile")
    argv.append(baseOptions['pidfile'])
    argv.append('-r')
    argv.append('gtk2')
    argv.append('-n')
    argv.append('sparked')
    argv = argv + sys.argv[1:]

    return subprocess.call(argv, env=env)


def launchLoop(app, options, env, appPath):
    quitFlag = QuitFlag(appPath.child("quitflag"))
    quitFlag.reset()
    respawned = False
    while True:
        start = time.time()
        launch(options, env)
        if time.time() - start < 5:
            if respawned:
                print "*** %s: respawning too fast ***" % app
            break
        if quitFlag.isSet():
            break
        respawned = True

    quitFlag.reset()



def loadModule(app):
    args = sys.argv[:]
    sys.argv = []
    if app[-3:] == ".py" and os.path.exists(app):
        path = os.path.dirname(app)
        if not path: path = "."
        sys.path.insert(0, path)
        app = os.path.basename(app)[:-3]

    try:
        mod = __import__(app, None, None, app.split(".")[-1])
    except ImportError, e:
        log.err(e)
        raise usage.UsageError("Application not found: " + app)
    sys.argv = args
    return mod, app



def main():

    env = os.environ

    try:
        options = Options()
        sparkedOpts, appName, appOpts = splitOptions(sys.argv[1:])
        options.parseOptions(sparkedOpts)

        if not appName:
            options.opt_help()

        appModule, appName = loadModule(appName)

        appPath = application.getTempPath(appName, options['id'])
{'fraction_non_alphanumeric': 0.12895559724828018, 'fraction_numerical': 0.0050031269543464665, 'mean_word_length': 2.4112627986348123, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1958417', 'n_tokens_mistral': 2528, 'n_tokens_neox': 2404, 'n_words': 674}