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 nosyreaction = os.path.join(home, 'detectors', 'nosyreaction.py')
53 if os.path.exists(nosyreaction):
54 os.remove(nosyreaction)
55 nosyreaction += 'c'
56 if os.path.exists(nosyreaction):
57 os.remove(nosyreaction)
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 # FIXME: Move tracker-specific demo initialization into the tracker templates.
92 if (template == 'minimal'):
93 db.user.create(username='demo', password=password.Password('demo'),
94 roles='User')
95 else:
96 db.user.create(username='demo', password=password.Password('demo'),
97 realname='Demo User', roles='User')
98 db.commit()
99 db.close()
101 def run_demo(home):
102 """Run the demo tracker installed in ``home``"""
103 cfg = configuration.CoreConfig(home)
104 url = cfg["TRACKER_WEB"]
105 hostname, port = urlparse.urlparse(url)[1].split(':')
106 port = int(port)
107 success_message = '''Server running - connect to:
108 %s
109 1. Log in as "demo"/"demo" or "admin"/"admin".
110 2. Hit Control-C to stop the server.
111 3. Re-start the server by running "roundup-demo" again.
112 4. Re-initialise the server by running "roundup-demo nuke".
114 Demo tracker is set up to be accessed by localhost browser. If you
115 run demo on a server host, please stop the demo, open file
116 "demo/config.ini" with your editor, change the host name in the "web"
117 option in section "[tracker]", save the file, then re-run the demo
118 program. If you want to change backend types, you must use "nuke".
120 ''' % url
122 # disable command line processing in roundup_server
123 sys.argv = sys.argv[:1] + ['-p', str(port), 'demo=' + home]
124 roundup_server.run(success_message=success_message)
127 def usage(msg = ''):
129 if msg: print msg
130 print 'Usage: %s [options] [nuke]'%sys.argv[0]
131 print """
132 Options:
133 -h -- print this help message
134 -t template -- specify the tracker template to use
135 -b backend -- specify the database backend to use
136 """
139 def main():
140 """Run a demo server for users to play with for instant gratification.
142 Sets up the web service on localhost. Disables nosy lists.
143 """
145 try:
146 opts, args = getopt.getopt(sys.argv[1:], 't:b:h')
147 except getopt.GetoptError, e:
148 usage(str(e))
149 return 1
151 home = os.path.abspath('demo')
152 nuke = args and args[0] == 'nuke'
153 if not os.path.exists(home) or nuke:
154 backend = 'anydbm'
155 template = 'classic'
156 for opt, arg in opts:
157 if opt == '-h':
158 usage()
159 return 0
160 elif opt == '-t':
161 template = arg
162 elif opt == '-b':
163 backend = arg
164 if (len(args) > 1 or
165 (len(args) == 1 and args[0] != 'nuke')):
166 usage()
167 return 1
169 install_demo(home, backend, template)
170 elif opts:
171 print "Error: Arguments are not allowed when running an existing demo."
172 print " Use the 'nuke' command to start over."
173 sys.exit(1)
175 run_demo(home)
178 if __name__ == '__main__':
179 sys.exit(main())
181 # vim: set filetype=python sts=4 sw=4 et si :