1
2
3
4 """
5 The Sparked application launcher.
6
7 Sparked applications are launched in a subprocess: so that if the
8 application crashes, it is started again.
9 """
10
11 import os
12 import subprocess
13 import sys
14 import time
15
16 from twisted.internet import reactor
17 from twisted.python import usage, log
18 from twisted.application import service, app
19
20 from sparked import application, __version__
21
22
24
25 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:
26
27 # sparkd <application> --help
28 """
29
30 optFlags = [["debug", "d", "Debug mode"],
31 ["no-subprocess", "N", "Do not start a subprocess for crash prevention"],
32 ]
33
34 optParameters = [
35 ('id', None, None, 'Application id (defaults to the sparked module name)'),
36 ('pidfile', None, None, 'Pidfile location (defaults to /tmp/<id>/sparkd.pid)'),
37 ('logfile', None, None, 'Pidfile location (defaults to /tmp/<id>/sparkd.log)')
38 ]
39
40
42 return "sparkd [options] <application> [app_options]"
43
45 print os.path.basename(sys.argv[0]), __version__
46 exit(0)
47
48
50 """
51 @ivar file: A C{FilePath} pointing to the quit-flag file.
52 """
55
56
58 f = self.file.open("w")
59 f.write("quit")
60 f.close()
61
62
64 try:
65 self.file.remove()
66 except:
67 pass
68
69
71 try:
72 return self.file.open("r").readlines()[0] == "quit"
73 except:
74 return False
75
76
77
78
80 try:
81 app = [a for a in args if a[0] != "-"][0]
82 except IndexError:
83 return args, None, []
84 i = args.index(app)
85 return (args[0:i], app, args[i+1:])
86
87
101
102
104 argv = []
105 argv.append("twistd")
106 argv.append("--pidfile")
107 argv.append(baseOptions['pidfile'])
108 argv.append('-r')
109 argv.append('gtk2')
110 argv.append('-n')
111 argv.append('sparked')
112 argv = argv + sys.argv[1:]
113
114 return subprocess.call(argv, env=env)
115
116
133
134
135
137 args = sys.argv[:]
138 sys.argv = []
139 if app[-3:] == ".py" and os.path.exists(app):
140 path = os.path.dirname(app)
141 if not path: path = "."
142 sys.path.insert(0, path)
143 app = os.path.basename(app)[:-3]
144
145 try:
146 mod = __import__(app, None, None, app.split(".")[-1])
147 except ImportError, e:
148 log.err(e)
149 raise usage.UsageError("Application not found: " + app)
150 sys.argv = args
151 return mod, app
152
153
155 print "This file is a Sparked application, and is meant to run like this:"
156 print
157 print " sparkd " + app
158 print
159 exit(1)
160
161
163
164 env = os.environ
165
166 try:
167 options = Options()
168 sparkedOpts, appName, appOpts = splitOptions(sys.argv[1:])
169 options.parseOptions(sparkedOpts)
170
171 if not appName:
172 options.opt_help()
173
174 appModule, appName = loadModule(appName)
175
176 appPath = application.getTempPath(appName, options['id'])
177
178 if hasattr(appModule, 'Options'):
179 opts = appModule.Options()
180 else:
181 opts = application.Options()
182
183 opts.appName = appName
184 if not hasattr(opts, 'longdesc'):
185 opts.longdesc = appModule.__doc__
186 opts.parseOptions(appOpts)
187
188 if not options['pidfile']:
189 options['pidfile'] = appPath.child("sparkd.pid").path
190
191
192 if options['no-subprocess']:
193 run(appName)
194 else:
195 launchLoop(appName, options, env, appPath)
196
197
198 except usage.UsageError, errortext:
199 print '%s: %s' % (sys.argv[0], errortext)
200 print '%s: Try --help for usage details.' % (sys.argv[0])
201 sys.exit(1)
202