1 #! /usr/bin/env python
2 #
3 # Copyright (c) 2003 Richard Jones (richard@mechanicalcat.net)
4 #
6 import errno
7 import os
8 import socket
9 import sys
10 import urlparse
11 from glob import glob
12 import getopt
14 from roundup import configuration
15 from roundup.scripts import roundup_server
17 def install_demo(home, backend, template):
18 """Install a demo tracker
20 Parameters:
21 home:
22 tracker home directory path
23 backend:
24 database backend name
25 template:
26 tracker template
28 """
30 from roundup import init, instance, password, backends
32 # set up the config for this tracker
33 config = configuration.CoreConfig()
34 config['TRACKER_HOME'] = home
35 config['MAIL_DOMAIN'] = 'localhost'
36 config['DATABASE'] = 'db'
37 config['WEB_DEBUG'] = True
38 if backend in ('mysql', 'postgresql'):
39 config['RDBMS_HOST'] = 'localhost'
40 config['RDBMS_USER'] = 'rounduptest'
41 config['RDBMS_PASSWORD'] = 'rounduptest'
42 config['RDBMS_NAME'] = 'rounduptest'
44 # see if we have further db nuking to perform
45 module = backends.get_backend(backend)
46 if module.db_exists(config):
47 module.db_nuke(config)
49 template_dir = os.path.join('share', 'roundup', 'templates', template)
50 init.install(home, template_dir)
51 # don't have email flying around
52 os.remove(os.path.join(home, 'detectors', 'nosyreaction.py'))
53 try:
54 os.remove(os.path.join(home, 'detectors', 'nosyreaction.pyc'))
55 except os.error, error:
56 if error.errno != errno.ENOENT:
57 raise
58 init.write_select_db(home, backend)
60 # figure basic params for server
61 hostname = 'localhost'
62 # pick a fairly odd, random port
63 port = 8917
64 while 1:
65 print 'Trying to set up web server on port %d ...'%port,
66 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
67 s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
68 try:
69 s.connect((hostname, port))
70 except socket.error, e:
71 if not hasattr(e, 'args') or e.args[0] != errno.ECONNREFUSED:
72 raise
73 print 'should be ok.'
74 break
75 else:
76 s.close()
77 print 'already in use.'
78 port += 100
79 config['TRACKER_WEB'] = 'http://%s:%s/demo/'%(hostname, port)
81 # write the config
82 config['INSTANT_REGISTRATION'] = 1
83 config.save(os.path.join(home, config.INI_FILE))
85 # open the tracker and initialise
86 tracker = instance.open(home)
87 tracker.init(password.Password('admin'))
89 # add the "demo" user
90 db = tracker.open('admin')
91 db.user.create(username='demo', password=password.Password('demo'),
92 realname='Demo User', roles='User')
93 db.commit()
94 db.close()
96 def run_demo(home):
97 """Run the demo tracker installed in ``home``"""
98 cfg = configuration.CoreConfig(home)
99 url = cfg["TRACKER_WEB"]
100 hostname, port = urlparse.urlparse(url)[1].split(':')
101 port = int(port)
102 success_message = '''Server running - connect to:
103 %s
104 1. Log in as "demo"/"demo" or "admin"/"admin".
105 2. Hit Control-C to stop the server.
106 3. Re-start the server by running "roundup-demo" again.
107 4. Re-initialise the server by running "roundup-demo nuke".
109 Demo tracker is set up to be accessed by localhost browser. If you
110 run demo on a server host, please stop the demo, open file
111 "demo/config.ini" with your editor, change the host name in the "web"
112 option in section "[tracker]", save the file, then re-run the demo
113 program.
115 ''' % url
117 # disable command line processing in roundup_server
118 sys.argv = sys.argv[:1] + ['-p', str(port), 'demo=' + home]
119 roundup_server.run(success_message=success_message)
122 def usage(msg = ''):
124 if msg: print msg
125 print 'Usage: %s [options] [nuke]'%sys.argv[0]
126 print """
127 Options:
128 -h -- print this help message
129 -t template -- specify the tracker template to use
130 -b backend -- specify the database backend to use
131 """
134 def main():
135 """Run a demo server for users to play with for instant gratification.
137 Sets up the web service on localhost. Disables nosy lists.
138 """
140 try:
141 opts, args = getopt.getopt(sys.argv[1:], 't:b:h')
142 except getopt.GetoptError, e:
143 usage(str(e))
144 return 1
146 home = os.path.abspath('demo')
147 nuke = args and args[0] == 'nuke'
148 if not os.path.exists(home) or nuke:
149 backend = 'anydbm'
150 template = 'classic'
151 for opt, arg in opts:
152 if opt == '-h':
153 usage()
154 return 0
155 elif opt == '-t':
156 template = arg
157 elif opt == '-b':
158 backend = arg
159 if (len(args) > 1 or
160 (len(args) == 1 and args[0] != 'nuke')):
161 usage()
162 return 1
164 install_demo(home, backend, template)
165 elif opts:
166 print "Error: Arguments are not allowed when running an existing demo."
167 print " Use the 'nuke' command to start over."
168 sys.exit(1)
170 run_demo(home)
173 if __name__ == '__main__':
174 sys.exit(main())
176 # vim: set filetype=python sts=4 sw=4 et si :