Code

Minor pre- 0.3.0 changes
[roundup.git] / doc / index.html
1 <html><head>
2 <title>Roundup: an Issue-Tracking System for Knowledge Workers</title>
3 </head><body>
5 <h1 align=center>Roundup (0.3.0)</h1>
6 <h3 align=center>An Issue-Tracking System for Knowledge Workers</h2>
8 <h1>Contents</h1>
10 <ul>
11     <li><a href="overview.html">Overview</a> (Initial submission to SC Track)
12 <li><a href="#installation">Installation</a>
13     <ul>
14         <li><a href="#requires">Prerequisites</a>
15         <li><a href="#getting">Getting Roundup</a>
16         <li><a href="#installing">Installing Roundup</a>
17     </ul>
18 <li><a href="#starting">Getting Started</a>
19     <ul>
20         <li><a href="#instance">The Instance</a>
21         <li><a href="#startcmd">Command Line Tool</a>
22         <li><a href="#startweb">E-Mail Interface</a>
23         <li><a href="#startweb">Web Interface</a>
24         <li><a href="#users">Users</a> (Users and permissions, Adding users)
25         <li><a href="#issues">Issues</a>
26     </ul>
27 <li><a href="#guide">User Guide</a>
28     <ul>
29         <li><a href="#cmd">Command Line Tool</a>
30         <li><a href="#web">Web Interface</a>
31         <li><a href="#mail">E-Mail Gateway</a> (Message content summary, Address handling, Performing Actions)
32     </ul>
33 <li><a href="#custom">Customising Roundup</a>
34     <ul>
35         <li><a href="#config">Instance Configuration</a>
36         <li><a href="#custinst">Instance Schema</a> (Creating a new information store)
37         <li><a href="#custweb">Web Interface</a> (Displaying properties, Index views, Item views)
38     </ul>
39 <li><a href="spec.html">Roundup's Design Document</a> ("Implementation Guide")
40 <li><a href="#ack">Acknowledgements</a>
41 </ul>
43 <p><hr>
44 <h1><a name="installation">Installation</a></h1>
47 <h2><a name="requires">Prerequisites</a></h2>
49 <dl>
50     <dt>Either:
51     <dd>Python 2.0 with pydoc installed. See http://www.lfw.org/ for pydoc.
52     <dt>or
53     <dd>Python 2.1 or later
54 </dl>
56 Download the latest version from
57 <a href="http://www.python.org/">http://www.python.org/</a>.
61 <h2><a name="getting">Getting Roundup</a></h2>
63 Download the latest version from
64 <a href="http://roundup.sf.net/">http://roundup.sf.net/</a>.
67 <h2><a name="installing">Installing Roundup</a></h2>
69 <ol>
70     <li>Run:
71     <br><tt>python setup.py install</tt>
72     <li>If you would prefer the scripts installed in somewhere other than
73     <tt>/usr/local/bin</tt>, add <tt>"--install-scripts=&lt;dir&gt;"</tt>
74     to the command:
75     <br><tt>python setup.py install --install-scripts=&lt;dir&gt;</tt>
76     <li>The command:
77     <br><tt>python setup.py install --help</tt>
78     <br>gives all the options available for installation.
79 </ol>
82 <p><hr>
83 <h1><a name="starting">Getting Started</a></h1>
85 The following instructions assume that you have installed roundup. If you
86 haven't, you may still proceed - just preface all commands with "./"
87 ie. "./roundup-admin init".
90 <h2><a name="instance">The Instance</a></h2>
92 We'll be referring to the term <em>instance</em> a lot from now on. An
93 instance is
94 a directory in your filesystem that is where all the information about a
95 live issue tracker database is stored. The data that is entered as issues,
96 the users who access the database and the definition of the database itself
97 all reside there:
98 <ol>
99     <li><strong>Hyperdatabase</strong>
100     <br>This is the lowest component of Roundup and is where all the
101     issues, users, file attachments and messages are stored.
102     <li><strong>Database schema</strong>
103     <br>This describes the content of the hyperdatabase - what fields are
104     stored for issues, what user information, etc. Being stored in the
105     instance, this allows it to be customised for a particular application.
106     It also means that changes in the Roundup core code do not affect a
107     running instance.
108     <li><strong>Web Interface</strong>
109     <br>The web interface templates are defined in the instance too - and
110     the actual CGI interface class is defined (mostly using base classes in
111     the Roundup core code) so it, like the database, may be customised for
112     each instance in use.
113 </ol>
115 Instances are created using the <tt>roundup-admin</tt> tool.
117 <h2><a name="startcmd">Command Line Tool</a></h2>
119 To initiliase a new instance, run <tt>roundup-admin init</tt>. You will be
120 asked a series of questions:
122 <ol>
123     <li>Instance home directory
124     <li>Schema to use
125     <li>Database back-end to use
126     <li>Administration user "admin" password.
127 </ol>
129 Roundup is configurable using an instance_config.py file in the instance home.
130 It should be edited before roundup is used, and may have the following
131 variable declarations:
132   
133 <ol>
134     <li>MAILHOST
135     <br>The SMTP mail host that roundup will use to send mail
136     <li>MAIL_DOMAIN
137     <br>The domain name used for email addresses
138     <li>ISSUE_TRACKER_WEB
139     <br>The web address of the issue tracker's web interface
140 </ol>
142 <p>
143 The email addresses used by the system by default are:
145 <ol>
146     <li>ISSUE_TRACKER_EMAIL - issue_tracker@MAIL_DOMAIN
147     <br>submissions of issues
148     <li>ADMIN_EMAIL - roundup-admin@MAIL_DOMAIN
149     <br>roundup's internal use (problems, etc)
150 </ol>
152 <em>Note:</em>
153 We run the instance as group "issue_tracker" and add the mail and web user
154 ("mail" and "apache" on our RedHat 7.1 system) to that group, as well as
155 any admin people.
158 <h2><a name="startweb">E-Mail Interface</a></h2>
159 Set up a mail alias called "issue_tracker" as:
160 <blockquote>
161     <tt>|/usr/bin/python /usr/local/bin/roundup-mailgw
162         &lt;instance_home&gt;</tt>
163 </blockquote>
165 In some installations (e.g. RedHat 6.2 I think) you'll need to set up smrsh
166 so sendmail will accept the pipe command. In that case, symlink
167 /etc/smrsh/roundup-mailgw to /usr/local/bin/roundup-mailgw and change the
168 command to:
169 <blockquote>
170     <tt>|roundup-mailgw &lt;instance_home&gt;</tt>
171 </blockquote>
173 To test the mail gateway on unix systems, try:
175 <blockquote>
176     <tt>echo test |mail -s '[issue] test' issue_tracker@your.domain</tt>
177 </blockquote>
181 <h2><a name="startweb">Web Interface</a></h2>
182 This software will work through apache or stand-alone.
183 <p>
184 <strong>Stand-alone:</strong>
185 <ol>
186     <li>Edit roundup-server at the top - ROUNDUP_INSTANCE_HOMES needs to know
187     about your instance. *** command-line option
188     <li><tt>roundup-server [hostname port]</tt>   (hostname may be "")
189     <li>Load up the page <tt>/&lt;instance name&gt;/index</tt> where
190      instance name is the
191      name you nominated in <tt>ROUNDUP_INSTANCE_HOMES</tt>.
192 *** command-line option
193 </ol>
195 <strong>Apache:</strong>
196 <ol>
197     <li>Make sure roundup.cgi is executable. Edit it at the top -
198     ROUNDUP_INSTANCE_HOMES needs to know about your instance.
199     <li>Edit your <tt>/etc/httpd/conf/httpd.conf</tt> and make sure that the
200         <tt>/home/httpd/html/roundup/roundup.cgi</tt> script will be treated as a CGI
201     script.
202     <li>Add the following to your <tt>/etc/httpd/conf/httpd.conf</tt>:
203 <pre>
204 ------8<------- snip here ------8<-------
205 RewriteEngine on
206 RewriteCond %{HTTP:Authorization} ^(.*)
207 RewriteRule ^/roundup/roundup.cgi(.*) /home/httpd/html/roundup/roundup.cgi$1 [e=HTTP_CGI_AUTHORIZATION:%1,t=application/x-httpd-cgi,l]
208 ------8<------- snip here ------8<-------
209 </pre>
210    note: the RewriteRule must be on one line - no breaks
211    <li>Re-start your apache to re-load the config
212    <li>Load up the page <tt>/roundup/roundup.cgi/&lt;instance name&gt;/index</tt> where
213     instance name is the name you nominated in ROUNDUP_INSTANCE_HOMES.
214 </ol>
217 <h2><a name="users">Users</a></h2>
219 <h3>Users and permissions</h3>
220 By default, roundup automatically creates one user when the instance
221 database is initialised (using roundup-admin init). The user is "admin" and
222 the password is the one you supply at that time.
223 <p>
224 If users attempt to use roundup in any manner and are not identified to
225 roundup, they will be using the database in a read-only mode. That is, if
226 roundup doesn't know who they are, they can't change anything. This has the
227 following repurcussions:
228 <dl>
229 <dt><strong>Command-line interface</strong>
230 <dd>The data modification commands (create, init, retire, set) are not
231 available without a login, and if one is not supplied on the command line
232 (-u user:pass) then it will be prompted for.
233 <dt><strong>E-Mail interface</strong>
234 <dd>Users are identified by e-mail address - a new user entry will be
235 created for any e-mail address that is not recognised, so users are
236 <em>always</em> identified by roundup.
237 <dt><strong>Web interface</strong>
238 <dd>Unidentified users have read-only access. If the users database has an
239 entry with the username "anonymous", then unidentified users are
240 automatically logged in as that user. This gives them write access.
241 </dl>
242 <p>
243 There has been only a half-hearted attempt to restrict certain activities
244 to the "admin" user. For example, the "extended" schema web interface enables
245 some fnuctionality for the "admin" user. On the fil-side, it is possible to
246 obtain the admin user's password using the read-only access on the command
247 line (it would also be possible to access the database files directly to
248 obtain this information).
250 <h3>Adding users</h3>
251 To add users, use one of the following interfaces:
253 <ol>
254     <li>On the web, access the URL <tt>.../&lt;instance name&gt;/newuser</tt>
255     to bring up a form which may be used to add a new user.
256     <li>On the command-line, use:
257     <br><tt>roundup-admin -i &lt;instance home&gt; create user
258         username=bozo password=bozo address=richard@clown.org</tt>
259     <br>Supply the admin username and password. roundup-admin will print the
260     id of the new user.
261     <li>Any e-mail sent to roundup from an address that doesn't match an
262     existing user in the database will result in a new user entry being
263     created for that user.
264 </ol>
268 <h2><a name="issues">Issues</a></h2>
269 To add issues, use one of the following interfaces:
271 <ol>
272     <li>On the web, access the URL <tt>.../&lt;instance name&gt;/newissue</tt>
273     to bring up a form which may be used to add a new issue.
274     <li>On the command-line, use:
275     <br><tt>roundup-admin -i &lt;instance home&gt; create issue
276         title="test issue"</tt>
277     <br>Supply the admin username and password. roundup-admin will print the
278     id of the new issue.
279     <li>Any e-mail sent to roundup with the subject line containing [issue]
280     will automatically created a new issue in the database using the
281     contents of the e-mail.
282 </ol>
284 <p><hr>
285 <h1><a name="guide">User Guide</a></h1>
286 <h2><a name="cmd">Command Line Tool</a></h2>
288 Usage:
289 <tt>roundup-admin [-i instance home] [-u login] [-c] &lt;command&gt;
290     &lt;arguments&gt;</tt>
292 <p>
293 <table><tr><th colspan=2>Options:</th></tr>
294    <tr><td>-i instance home </td><td>specify the issue tracker "home directory" to administer
295    </td></tr>
296    <tr><td>-u               </td><td>the user[:password] to use for commands
297    </td></tr>
298    <tr><td>-c               </td><td>when outputting lists of data, just comma-separate them
299     </td></tr>
300 </table>
302 <p>
303 <table border=1 cellspacing=0>
304 <tr><th colspan=2>Command Help</th></tr>
305 <tr><td valign=top><strong>history</strong></td>
306     <td><tt>history designator</tt><p>
307     Lists the journal entries for the node identified by the designator.
308 </td></tr>
309     
310 <tr><td valign=top><strong>find</strong></td>
311     <td><tt>find classname propname=value ...</tt><p>
312     Find the nodes of the given class with a given property value. The
313     value may be either the nodeid of the linked node, or its key value.
314 </td></tr>
315     
316 <tr><td valign=top><strong>list</strong></td>
317     <td><tt>list classname [property]</tt><p>
318     Lists all instances of the given class along. If the property is not
319     specified, the  "label" property is used. The label property is tried
320     in order: the key, "name", "title" and then the first property,
321     alphabetically.
322 </td></tr>
323     
324 <tr><td valign=top><strong>retire</strong></td>
325     <td><tt>retire designator[,designator]*</tt><p>
326     This action indicates that a particular node is not to be retrieved by
327     the list or find commands, and its key value may be re-used.
328 </td></tr>
329     
330 <tr><td valign=top><strong>create</strong></td>
331     <td><tt>create classname property=value ...</tt><p>
332     This creates a new entry of the given class using the property
333     name=value arguments provided on the command line after the "create"
334     command.
335 </td></tr>
336     
337 <tr><td valign=top><strong>get</strong></td>
338     <td><tt>get property designator[,designator]*</tt><p>
339     Retrieves the property value of the nodes specified by the designators.
340 </td></tr>
341     
342 <tr><td valign=top><strong>spec</strong></td>
343     <td><tt>spec classname</tt><p>
344     This lists the properties for a given class.
345 </td></tr>
346     
347 <tr><td valign=top><strong>set</strong></td>
348     <td><tt>set designator[,designator]* propname=value ...</tt><p>
349     Sets the property to the value for all designators given.
350 </td></tr>
351     
352 <tr><td valign=top><strong>init</strong></td>
353     <td><tt>init [template [backend [admin password]]]</tt><p>
354     The command will prompt for the instance home directory (if not supplied
355     through INSTANCE_HOME or the -i option. The template, backend and admin
356     password may be specified on the command-line as arguments, in that order.
357 </td></tr>
358     
359 <tr><td valign=top><strong>freshen</strong></td>
360     <td><tt>freshen</tt><p>
361         <strong>**DO NOT USE**</strong>
362         <p>
363     This currently kills databases!!!!
364     <p>
365     This action should generally not be used. It reads in an instance
366     database and writes it again. In the future, is may also update
367     instance code to account for changes in templates. It's probably wise
368     not to use it anyway. Until we're sure it won't break things...
369 </td></tr>
371 <tr><td><strong>help</strong></td>
372     <td><tt>help [command]</tt><p>
373     Short help about roundup-admin or the specific command.
374     </td></tr>
376 <tr><td><strong>morehelp</strong></td>
377     <td><tt>morehelp</tt><p>
378     All available help from the roundup-admin tool.
379     </td></tr>
380 </table>
382 <p>
383 All commands (except help) require an instance specifier. This is just the path
384 to the roundup instance you're working with. A roundup instance is where 
385 roundup keeps the database and configuration file that defines an issue
386 tracker. It may be thought of as the issue tracker's "home directory". It may
387 be specified in the environment variable ROUNDUP_INSTANCE or on the command
388 line as "-i instance".
390 <p>
391 A designator is a classname and a nodeid concatenated, eg. bug1, user10, ...
393 <p>
394 Property values are represented as strings in command arguments and in the
395 printed results:
396 <ul>
397     <li>Strings are, well, strings.
398     <li>Date values are printed in the full date format in the local time zone, and
399    accepted in the full format or any of the partial formats explained below.
400 <table>
401     <tr><th>Input of...</th><th>Means...</th></tr>
402     <tr><td>"2000-04-17.03:45"</td><td>2000-04-17.08:45:00</td></tr>
403     <tr><td>"2000-04-17"</td><td>2000-04-17.00:00:00</td></tr>
404     <tr><td>"01-25"</td><td>yyyy-01-25.00:00:00</td></tr>
405     <tr><td>"08-13.22:13"</td><td>yyyy-08-14.03:13:00</td></tr>
406     <tr><td>"11-07.09:32:43"</td><td>yyyy-11-07.14:32:43</td></tr>
407     <tr><td>"14:25"</td><td>yyyy-mm-dd.19:25:00</td></tr>
408     <tr><td>"8:47:11"</td><td>yyyy-mm-dd.13:47:11</td></tr>
409     <tr><td>"."</td><td>"right now"</td></tr>
410 </table>
411    <li>Link values are printed as node designators. When given as an argument,
412    node designators and key strings are both accepted.
413    <li>Multilink values are printed as lists of node designators joined by commas.
414    When given as an argument, node designators and key strings are both
415    accepted; an empty string, a single node, or a list of nodes joined by
416    commas is accepted.
417 </ul>
418 When multiple nodes are specified to the roundup get or roundup set
419 commands, the specified properties are retrieved or set on all the listed
420 nodes. 
421 <p>
422 When multiple results are returned by the roundup get or roundup find
423 commands, they are printed one per line (default) or joined by commas (with
424 the -c) option. 
425 <p>
426 Where the command changes data, a login name/password is required. The
427 login may be specified as either "name" or "name:password".
428 <ul>
429     <li>ROUNDUP_LOGIN environment variable
430     <li>the -u command-line option
431 </ul>
432 If either the name or password is not supplied, they are obtained from the
433 command-line. 
435 <h2><a name="web">Web Interface</a></h2>
436 Index views may be modified by the following arguments:
437 <pre>
438     :sort    - sort by prop name, optionally preceeded with '-'
439              to give descending or nothing for ascending sorting.
440     :group   - group by prop name, optionally preceeded with '-' or
441              to sort in descending or nothing for ascending order.
442     :filter  - selects which props should be displayed in the filter
443              section. Default is all.
444     :columns - selects the columns that should be displayed.
445              Default is all.
446     propname - selects the values the node properties given by propname
447              must have (very basic search/filter).
448 </pre>
450 <strong>Not sure what to put in here...</strong>
452 <h2><a name="mail">E-Mail Gateway</a></h2>
454 Incoming messages are examined for multiple parts:
455 <ul>
456 <li>In a multipart/mixed message or part, each subpart is extracted and
457    examined. The text/plain subparts are assembled to form the textual
458    body of the message, to be stored in the file associated with a "msg"
459    class node. Any parts of other types are each stored in separate files
460    and given "file" class nodes that are linked to the "msg" node. 
461 <li>In a multipart/alternative message or part, we look for a text/plain
462    subpart and ignore the other parts.
463 </ul>
465 <h3>Message content summary</h3>
466 The "summary" property on message nodes is taken from the first non-quoting
467 section in the message body. The message body is divided into sections by
468 blank lines. Sections where the second and all subsequent lines begin with
469 a "&gt;" or "|" character are considered "quoting sections". The first line of
470 the first non-quoting section becomes the summary of the message. 
472 <h3>Address handling</h3>
473 All of the addresses in the To: and Cc: headers of the incoming message are
474 looked up among the user nodes, and the corresponding users are placed in
475 the "recipients" property on the new "msg" node. The address in the From:
476 header similarly determines the "author" property of the new "msg"
477 node. The default handling for addresses that don't have corresponding
478 users is to create new users with no passwords and a username equal to the
479 address. (The web interface does not permit logins for users with no
480 passwords.) If we prefer to reject mail from outside sources, we can simply
481 register an auditor on the "user" class that prevents the creation of user
482 nodes with no passwords. 
484 <h3>Performing Actions</h3>
485 The subject line of the incoming message is examined to determine whether
486 the message is an attempt to create a new item or to discuss an existing
487 item. A designator enclosed in square brackets is sought as the first thing
488 on the subject line (after skipping any "Fwd:" or "Re:" prefixes). 
490 If an item designator (class name and id number) is found there, the newly
491 created "msg" node is added to the "messages" property for that item, and
492 any new "file" nodes are added to the "files" property for the item. 
494 If just an item class name is found there, we attempt to create a new item
495 of that class with its "messages" property initialized to contain the new
496 "msg" node and its "files" property initialized to contain any new "file"
497 nodes. 
499 <h3>Triggers</h3>
500 Both cases may trigger detectors (in the first case we are calling the
501 set() method to add the message to the item's spool; in the second case we
502 are calling the create() method to create a new node). If an auditor raises
503 an exception, the original message is bounced back to the sender with the
504 explanatory message given in the exception. 
506 <p><hr>
507 <h1><a name="custom">Customising Roundup</a></h1>
509 Instances have the following structure:
510 <table>
511     <tr><td valign=top><strong>instance_config.py</strong></td>
512     <td>Holds the basic <a href="#config">instance configuration</a></td></tr>
513     <tr><td valign=top><strong>dbinit.py</strong></td>
514         <td>Holds the <a href="#custinst">instance schema</a></td></tr>
515     <tr><td valign=top><strong>interfaces.py</strong></td>
516     <td>Defines the <a href="#custweb">Web</a> and E-Mail interfaces for the instance</td></tr>
517     <tr><td valign=top><strong>select_db.py</strong></td>
518         <td>Selects the database back-end for the instance</td></tr>
519     <tr><td valign=top><strong>db/</strong></td>
520         <td>Holds the instance's database</td></tr>
521     <tr><td valign=top><strong>db/files/</strong></td>
522         <td>Holds the instance's upload files and messages</td></tr>
523     <tr><td valign=top><strong>detectors/</strong></td>
524         <td>Auditors and reactors for this instance</td></tr>
525     <tr><td valign=top><strong>html/</strong></td>
526     <td>Web interface <a href="#custweb">templates</a>, images and style sheets</td></tr>
527 </table>
529 <h2><a name="config">Instance Configuration</a></h2>
530 The <tt>instance_config.py</tt> located in your instance home contains the
531 basic configuration for the web and e-mail components of roundup's
532 interfaces. This file is a Python module. The default
533 <tt>instance_config.py</tt> is given below - as you can see, the
534 MAIL_DOMAIN must be edited before any interaction with the instance is
535 attempted.
537 <p>
538 <pre>
539 MAIL_DOMAIN=MAILHOST=HTTP_HOST=None
540 HTTP_PORT=0
542 # roundup home is this package's directory
543 INSTANCE_HOME=os.path.split(__file__)[0]
545 # The SMTP mail host that roundup will use to send mail
546 if not MAILHOST:
547     MAILHOST = 'localhost'
549 # The domain name used for email addresses.
550 if not MAIL_DOMAIN:
551     MAIL_DOMAIN = 'fill.me.in.'
553 # the next two are only used for the standalone HTTP server.
554 if not HTTP_HOST:
555     HTTP_HOST = ''
556 if not HTTP_PORT:
557     HTTP_PORT = 9080
559 # This is the directory that the database is going to be stored in
560 DATABASE = os.path.join(INSTANCE_HOME, 'db')
562 # This is the directory that the HTML templates reside in
563 TEMPLATES = os.path.join(INSTANCE_HOME, 'html')
565 # The email address that mail to roundup should go to
566 ISSUE_TRACKER_EMAIL = 'issue_tracker@%s'%MAIL_DOMAIN
568 # The web address that the instance is viewable at
569 ISSUE_TRACKER_WEB = 'http://some.useful.url/'
571 # The email address that roundup will complain to if it runs into trouble
572 ADMIN_EMAIL = 'roundup-admin@%s'%MAIL_DOMAIN
574 # Somewhere for roundup to log stuff internally sent to stdout or stderr
575 LOG = os.path.join(INSTANCE_HOME, 'roundup.log')
576 </pre>
578 <h2><a name="custinst">Instance Schema</a></h2>
579 An instance schema defines what data is stored in the instance's database.
580 The two schemas shipped with Roundup turn it into a typical software bug
581 tracker (the extended schema allowing for support issues as well as bugs).
582 Schemas are defined using Python code. The "classic" schema looks like
583 this:
584 <p>
585 <pre>
586     pri = Class(db, "priority", name=String(), order=String())
587     pri.setkey("name")
588     pri.create(name="critical", order="1")
589     pri.create(name="urgent", order="2")
590     pri.create(name="bug", order="3")
591     pri.create(name="feature", order="4")
592     pri.create(name="wish", order="5")
594     stat = Class(db, "status", name=String(), order=String())
595     stat.setkey("name")
596     stat.create(name="unread", order="1")
597     stat.create(name="deferred", order="2")
598     stat.create(name="chatting", order="3")
599     stat.create(name="need-eg", order="4")
600     stat.create(name="in-progress", order="5")
601     stat.create(name="testing", order="6")
602     stat.create(name="done-cbb", order="7")
603     stat.create(name="resolved", order="8")
605     keyword = Class(db, "keyword", name=String())
606     keyword.setkey("name")
608     user = Class(db, "user", username=String(), password=String(),
609         address=String(), realname=String(), phone=String(), organisation=String())
610     user.setkey("username")
611     user.create(username="admin", password=adminpw, address=instance_config.ADMIN_EMAIL)
613     msg = FileClass(db, "msg", author=Link("user"), recipients=Multilink("user"), 
614         date=Date(), summary=String(), files=Multilink("file"))
616     file = FileClass(db, "file", name=String(), type=String())
618     issue = IssueClass(db, "issue", assignedto=Link("user"),
619         topic=Multilink("keyword"), priority=Link("priority"), status=Link("status"))
620     issue.setkey('title')
621 </pre>
623 <h3>Class, FileClass, IssueClass - creating a new information store</h3>
624 A <em>Class</em> defines a particular class (or type) of data that will be
625 stored in the database. In the instance above, we've defined 7 classes of
626 information:
627 <dl>
628     <dt><strong>priority</strong>
629     <dd>Defines the possible levels of urgency for issues.
630     <dt><strong>status</strong>
631     <dd>Defines the possible states of processing the issue may be in.
632     <dt><strong>keyword</strong>
633     <dd>Initially empty, will hold keywords useful for searching issues.
634     <dt><strong>user</strong>
635     <dd>Initially holding the "admin" user, will eventually have an entry
636     for all users using roundup.
637     <dt><strong>msg</strong>
638     <dd>Initially empty, will all e-mail messages sent to or generated by roundup.
639     <dt><strong>file</strong>
640     <dd>Initially empty, will all files attached to issues.
641     <dt><strong>issue</strong>
642     <dd>Initially emtyp, this is where the issue information is stored.
643 </dl>
644 <p>
645 We define the "priority" and "status" classes to allow two things: reduction in the
646 amount of information stored on the issue and more powerful, accurate
647 searching of issues by priority and status. By only requiring a link on
648 the issue (which is stored as a single number) we reduce the chance
649 that someone mis-types a priority or status - or simply makes a new one
650 up.
651 <p>
653 <strong>Class</strong>
654 <br>
655 Class is the basic store of information.
657 <p>
659 <strong>FileClass</strong>
660 <br>
661 FileClasses save their "content" attribute off in a separate file from the
662 rest of the database. This reduces the number of large entries in the
663 database, which generally makes databases more efficient, and also allows
664 us to use command-line tools to operate on the files. They are stored in
665 the files sub-directory of the db directory in your instance.
667 <p>
669 <strong>IssueClass</strong>
670 <br>
671 IssueClasses automatically include the "messages", "files", "nosy", and
672 "superseder" properties.
673 <p>
674 The messages and files properties list the links to the messages and files
675 related to the issue. The nosy property is a list of links to users who
676 wish to be informed of changes to the issue - they get "CC'ed" e-mails when
677 messages are sent to or generated by the issue. The nosy reactor (in the
678 detectors directory) handles this action. The superceder link indicates an
679 issue which has superceded this one.
680 <p>
681 They also have the dynamically generated
682 "creation", "activity" and "creator" properties.
683 <p>
684 The value of the "creation" property is the date when an item was created,
685 and the value of the "activity" property is the date when any property on
686 the item was last edited (equivalently, these are the dates on the first
687 and last records in the item's journal). The "creator" property holds a
688 link to the user that created the issue.
690 <h4>setkey(property)</h4>
691 Select a String property of the class to be the key property. The key
692 property muse be unique, and allows references to the items in the class by
693 the content of the key property. That is, we can refer to users by their
694 username, e.g. let's say that there's an issue in roundup, issue 23. There's
695 also a user, richard who happens to be user 2. To assign an issue to him,
696 we could do either of:
697 <p>
698 <blockquote><tt>roundup-admin set issue assignedto=2</tt></blockquote>
699 <p>
700 or
701 <p>
702 <blockquote><tt>roundup-admin set issue
703         assignedto=richard</tt></blockquote>
704 <p>
705 Note, the same thing can be done in the web and e-mail interfaces.
707 <h4>create(information)</h4>
708 Create an item in the database. This is generally used to create items in
709 the "definitional" classes like "priority" and "status".
711 <h2><a name="custweb">Web Interface</a></h2>
713 The web interface works behind the cgi-bin/roundup.cgi or roundup-server
714 scripts. In both cases, the scripts determine which instance is being
715 accessed (the first part of the URL path inside the scope of the CGI
716 handler) and pass control on to the instance interfaces.Client class which
717 handles the rest of the access through its main() method. This means that
718 you can do pretty much anything you want as a web interface to your
719 instance.
720 <p>
721 Most customisation of the web view can be done by modifying the templates
722 in the instance html directory. These are divided into index, item and
723 newitem views. The newitem view is optional - the item view will be used if
724 the newitem view doesn't exist.
726 <h3>Displaying Properties</h3>
728 <p>
729 Properties appear in the user interface in three contexts:
730 in indices, in editors, and as filters.  For each type of
731 property, there are several display possibilities.  For example,
732 in an index view, a string property may just be printed as
733 a plain string, but in an editor view, that property should
734 be displayed in an editable field.
736 <p>
737 The display of a property is handled by functions in
738 the htmltemplate module.
740 <p>
741 Displayer functions are triggered by <tt>&lt;display&gt;</tt>
742 tags in templates.  The <tt>call</tt> attribute of the tag
743 provides a Python expression for calling the displayer
744 function.  The three standard arguments are inserted in
745 front of the arguments given.  For example, the occurrence of
747 <blockquote><pre><small
748 >    &lt;display call="plain('status')"&gt;
749 </small></pre></blockquote>
751 in a template triggers a call the "plain" function. The displayer
752 functions can accept extra arguments to further specify
753 details about the widgets that should be generated.  By defining new
754 displayer functions, the user interface can be highly customized.
756 <p>
757 <table border=1 cellspacing=0>
758 <tr><th colspan=2>The displayer functions are</th></tr>
760 <tr><td valign="top"><strong>plain</strong></td>
761 <td>Display a String property directly.
762 <p>
763 Display a Date property in a specified time zone with an option
764 to omit the time from the date stamp.
765 <p>
766 For a Link or Multilink
767 property, display the key strings of the linked nodes (or the
768 ids if the linked class has no key property).
769 <p>
770 <em>Options:</em><br>
771 escape (boolean) - HTML-escape the resulting text.
772 </td></tr>
774 <tr><td valign="top"><strong>field</strong></td>
775 <td>Display a property like the
776 <strong>plain</strong> displayer above, but in a form field
777 to be edited. Strings, Dates and Intervals use TEXT fields, Links use
778 SELECT fields and Multilinks use SELECT MULTIPLE fields.
779 <p>
780 <em>Options:</em><br>
781 size (number) - width of TEXT fields.<br>
782 height (number) - number of nows in SELECT MULTIPLE tags.<br>
783 showid (boolean) - true includes the id of linked items in the SELECT
784 MULTIPLE fields.
785 </td></tr>
787 <tr><td valign="top"><strong>menu</strong></td>
788 <td>For a Links and Multilinks, display the same field as would be
789 generated using <strong>field</strong>.
790 </td></tr>
792 <tr><td valign="top"><strong>link</strong></td>
793 <td>For a Link or Multilink property, display the names of the linked
794 nodes, hyperlinked to the item views on those nodes. For other properties,
795 link to this node with the property as the text.
796 <p>
797 <em>Options:</em><br>
798 property (property name) - the property to use in the second case.
799 </td></tr>
801 <tr><td valign="top"><strong>count</strong></td>
802 <td>For a Multilink property, display
803 a count of the number of links in the list.
804 <p>
805 <em>Arguments:</em><br>
806 property (property name) - the property to use.
808 </td></tr>
810 <tr><td valign="top"><strong>reldate</strong></td>
811 <td>Display a Date property in terms
812 of an interval relative to the current date (e.g. "+ 3w", "- 2d").
813 <p>
814 <em>Arguments:</em><br>
815 property (property name) - the property to use.
816 <p>
817 <em>Options:</em><br>
818 pretty (boolean) - display the relative date in an English form.
819 </td></tr>
821 <tr><td valign="top"><strong>download</strong></td>
822 <td>Show a Link("file") or Multilink("file")
823 property using links that allow you to download files.
824 <p>
825 <em>Arguments:</em><br>
826 property (property name) - the property to use.
827 </td></tr>
829 <tr><td valign="top"><strong>checklist</strong></td>
830 <td>For a Link or Multilink property,
831 display checkboxes for the available choices to permit filtering.
832 <p>
833 <em>Arguments:</em><br>
834 property (property name) - the property to use.
835 </td></tr>
837 <tr><td valign="top"><strong>note</strong></td>
838 <td>Display the special notes field, which is a text area for entering a
839 note to go along with a change.
840 </td></tr>
842 <tr><td valign="top"><strong>list</strong></td>
843 <td>List the items specified by property using the standard index for
844 the class.
845 <p>
846 <em>Arguments:</em><br>
847 property (property name) - the property to use.
848 </td></tr>
850 <tr><td valign="top"><strong>history</strong></td>
851 <td>List the history of the item.
852 </td></tr>
854 <tr><td valign="top"><strong>submit</strong></td>
855 <td>Add a submit button for the item.
856 </td></tr>
858 </table>
860 <h3>Index Views</h3>
862 <p>An index view contains two sections: a filter section
863 and an index section.
864 The filter section provides some widgets for selecting
865 which items appear in the index.  The index section is
866 a table of items.
868 <h4>Index View Specifiers</h4>
870 <p>An index view specifier (URL fragment) looks like this (whitespace
871 has been added for clarity):
873 <blockquote><pre><small
874 >/issue?status=unread,in-progress,resolved&amp;
875         topic=security,ui&amp;
876         :group=+priority&amp;
877         :sort=-activity&amp;
878         :filters=status,topic&amp;
879         :columns=title,status,fixer
880 </small></pre></blockquote>
882 <p>The index view is determined by two parts of the
883 specifier: the layout part and the filter part.
884 The layout part consists of the query parameters that
885 begin with colons, and it determines the way that the
886 properties of selected nodes are displayed.
887 The filter part consists of all the other query parameters,
888 and it determines the criteria by which nodes 
889 are selected for display.
891 <p>The filter part is interactively manipulated with
892 the form widgets displayed in the filter section.  The
893 layout part is interactively manipulated by clicking
894 on the column headings in the table.
896 <p>The filter part selects the <em>union</em> of the
897 sets of items with values matching any specified Link
898 properties and the <em>intersection</em> of the sets
899 of items with values matching any specified Multilink
900 properties.
902 <p>The example specifies an index of "issue" nodes.
903 Only items with a "status" of <em>either</em>
904 "unread" or "in-progres" or "resolved" are displayed,
905 and only items with "topic" values including <em>both</em>
906 "security" <em>and</em> "ui" are displayed.  The items
907 are grouped by priority, arranged in ascending order;
908 and within groups, sorted by activity, arranged in
909 descending order.  The filter section shows filters
910 for the "status" and "topic" properties, and the
911 table includes columns for the "title", "status", and
912 "fixer" properties.
914 <p>Associated with each item class is a default
915 layout specifier.  The layout specifier in the above
916 example is the default layout to be provided with
917 the default bug-tracker schema described above in
918 section 4.4.
920 <h4>Filter Section</h4>
922 <p>The template for a filter section provides the
923 filtering widgets at the top of the index view.
924 Fragments enclosed in <tt>&lt;property&gt;</tt>...<tt>&lt;/property&gt;</tt>
925 tags are included or omitted depending on whether the
926 view specifier requests a filter for a particular property.
928 <p>Here's a simple example of a filter template.
930 <blockquote><pre><small
931 >&lt;property name=status&gt;
932     &lt;display call="checklist('status')"&gt;
933 &lt;/property&gt;
934 &lt;br&gt;
935 &lt;property name=priority&gt;
936     &lt;display call="checklist('priority')"&gt;
937 &lt;/property&gt;
938 &lt;br&gt;
939 &lt;property name=fixer&gt;
940     &lt;display call="menu('fixer')"&gt;
941 &lt;/property&gt;</small></pre></blockquote>
943 <p>
944 The standard index generation code appends a section to the index pages
945 which allows selection of the filters - from those which are defined in the
946 filter template.
948 <h4>Index Section</h4>
950 <p>The template for an index section describes one row of
951 the index table.
952 Fragments enclosed in <tt>&lt;property&gt;</tt>...<tt>&lt;/property&gt;</tt>
953 tags are included or omitted depending on whether the
954 view specifier requests a column for a particular property.
955 The table cells should contain <tt>&lt;display&gt;</tt> tags
956 to display the values of the item's properties.
958 <p>Here's a simple example of an index template.
960 <blockquote><pre><small
961 >&lt;tr&gt;
962     &lt;property name=title&gt;
963         &lt;td&gt;&lt;display call="plain('title', max=50)"&gt;&lt;/td&gt;
964     &lt;/property&gt;
965     &lt;property name=status&gt;
966         &lt;td&gt;&lt;display call="plain('status')"&gt;&lt;/td&gt;
967     &lt;/property&gt;
968     &lt;property name=fixer&gt;
969         &lt;td&gt;&lt;display call="plain('fixer')"&gt;&lt;/td&gt;
970     &lt;/property&gt;
971 &lt;/tr&gt;</small></pre></blockquote>
973 <h4>Sorting</h4>
975 <p>String and Date values are sorted in the natural way.
976 Link properties are sorted according to the value of the
977 "order" property on the linked nodes if it is present; or
978 otherwise on the key string of the linked nodes; or
979 finally on the node ids.  Multilink properties are
980 sorted according to how many links are present.
982 <h3>Item Views</h3>
984 <p>An item view contains an editor section and a spool section.
985 At the top of an item view, links to superseding and superseded
986 items are always displayed.
990 <h4>Editor Section</h4>
992 <p>The editor section is generated from a template
993 containing <tt>&lt;display&gt;</tt> tags to insert
994 the appropriate widgets for editing properties.
996 <p>Here's an example of a basic editor template.
998 <blockquote><pre><small
999 >&lt;table&gt;
1000 &lt;tr&gt;
1001     &lt;td colspan=2&gt;
1002         &lt;display call="field('title', size=60)"&gt;
1003     &lt;/td&gt;
1004 &lt;/tr&gt;
1005 &lt;tr&gt;
1006     &lt;td&gt;
1007         &lt;display call="field('fixer', size=30)"&gt;
1008     &lt;/td&gt;
1009     &lt;td&gt;
1010         &lt;display call="menu('status')&gt;
1011     &lt;/td&gt;
1012 &lt;/tr&gt;
1013 &lt;tr&gt;
1014     &lt;td&gt;
1015         &lt;display call="field('nosy', size=30)"&gt;
1016     &lt;/td&gt;
1017     &lt;td&gt;
1018         &lt;display call="menu('priority')&gt;
1019     &lt;/td&gt;
1020 &lt;/tr&gt;
1021 &lt;tr&gt;
1022     &lt;td colspan=2&gt;
1023         &lt;display call="note()"&gt;
1024     &lt;/td&gt;
1025 &lt;/tr&gt;
1026 &lt;/table&gt;
1027 </small></pre></blockquote>
1029 <p>As shown in the example, the editor template can also
1030 request the display of a "note" field, which is a
1031 text area for entering a note to go along with a change.
1033 <p>When a change is submitted, the system automatically
1034 generates a message describing the changed properties.
1036 <p>If a note is given in the "note" field, the note is
1037 appended to the description.  The message is then added
1038 to the item's message spool (thus triggering the standard
1039 detector to react by sending out this message to the nosy list).
1041 <p>
1042 The message also displays all of the property values on the
1043 item and indicates which ones have changed.
1044 An example of such a message might be this:
1046 <blockquote><pre>
1047 Polly's taken a turn for the worse - this is now really important!
1048 -----
1049 title: Polly Parrot is dead
1050 priority: critical
1051 status: unread -&gt; in-progress
1052 fixer: terry
1053 keywords: parrot,plumage,perch,nailed,dead
1054 </pre></blockquote>
1056 <h4>Spool Section</h4>
1058 <p>The spool section lists messages in the item's "messages"
1059 property.  The index of messages displays the "date", "author",
1060 and "summary" properties on the message nodes, and selecting a
1061 message takes you to its content.
1063 <p>The &lt;property&gt; tag used in the index may also be used here -
1064 it checks to see if the nominated Multilink property has any entries.
1065 This can be used to eliminate sections of the spool section if the
1066 property has no entries.
1068 <blockquote><pre>
1069 &lt;property name="files"&gt;
1070  &lt;tr class="strong-header"&gt;
1071   &lt;td&gt;&lt;b&gt;Files&lt;/b&gt;&lt;/td&gt;
1072  &lt;/tr&gt;
1074  &lt;tr&gt;            
1075   &lt;td&gt;&lt;display call="list('files')"&gt;&lt;/td&gt;
1076  &lt;/tr&gt;
1077 &lt;/property&gt;
1078 </pre></blockquote>
1080 <p><hr>
1081 <h1><a name="ack">Acknowledgements</a></h1>
1083 Go Ping, you rock! Also, go Bizar Software for letting me implement this
1084 system on their time.
1086 <p>&nbsp;</p>
1087 <hr>
1088 $Id: index.html,v 1.10 2001-10-08 21:49:30 richard Exp $
1089 <p>&nbsp;</p>
1091 </body></html>