summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 09d661d)
raw | patch | inline | side by side (parent: 09d661d)
author | richard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2> | |
Thu, 26 Sep 2002 04:15:55 +0000 (04:15 +0000) | ||
committer | richard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2> | |
Thu, 26 Sep 2002 04:15:55 +0000 (04:15 +0000) |
git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@1257 57a73879-2fb5-44c3-a270-3262357dd7e2
17 files changed:
diff --git a/roundup/templates/minimal/.cvsignore b/roundup/templates/minimal/.cvsignore
--- /dev/null
@@ -0,0 +1,4 @@
+*.pyc
+*.pyo
+htmlbase.py
+*.cover
diff --git a/roundup/templates/minimal/__init__.py b/roundup/templates/minimal/__init__.py
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# Copyright (c) 2001 Bizar Software Pty Ltd (http://www.bizarsoftware.com.au/)
+# This module is free software, and you may redistribute it and/or modify
+# under the same terms as Python, so long as this copyright message and
+# disclaimer are retained in their original form.
+#
+# IN NO EVENT SHALL BIZAR SOFTWARE PTY LTD BE LIABLE TO ANY PARTY FOR
+# DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING
+# OUT OF THE USE OF THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# BIZAR SOFTWARE PTY LTD SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS"
+# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
+# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+#
+# $Id: __init__.py,v 1.1 2002-09-26 04:15:07 richard Exp $
+
+import config
+from dbinit import open, init
+from interfaces import Client, MailGW
+
+# vim: set filetype=python ts=4 sw=4 et si
diff --git a/roundup/templates/minimal/config.py b/roundup/templates/minimal/config.py
--- /dev/null
@@ -0,0 +1,92 @@
+#
+# Copyright (c) 2001 Bizar Software Pty Ltd (http://www.bizarsoftware.com.au/)
+# This module is free software, and you may redistribute it and/or modify
+# under the same terms as Python, so long as this copyright message and
+# disclaimer are retained in their original form.
+#
+# IN NO EVENT SHALL BIZAR SOFTWARE PTY LTD BE LIABLE TO ANY PARTY FOR
+# DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING
+# OUT OF THE USE OF THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# BIZAR SOFTWARE PTY LTD SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS"
+# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
+# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+#
+# $Id: config.py,v 1.1 2002-09-26 04:15:06 richard Exp $
+
+import os
+
+# roundup home is this package's directory
+TRACKER_HOME=os.path.split(__file__)[0]
+
+# The SMTP mail host that roundup will use to send mail
+MAILHOST = 'localhost'
+
+# The domain name used for email addresses.
+MAIL_DOMAIN = 'your.tracker.email.domain.example'
+
+# This is the directory that the database is going to be stored in
+DATABASE = os.path.join(TRACKER_HOME, 'db')
+
+# This is the directory that the HTML templates reside in
+TEMPLATES = os.path.join(TRACKER_HOME, 'html')
+
+# A descriptive name for your roundup instance
+TRACKER_NAME = 'Roundup issue tracker'
+
+# The email address that mail to roundup should go to
+TRACKER_EMAIL = 'issue_tracker@%s'%MAIL_DOMAIN
+
+# The web address that the instance is viewable at
+TRACKER_WEB = 'http://your.tracker.url.example/'
+
+# The email address that roundup will complain to if it runs into trouble
+ADMIN_EMAIL = 'roundup-admin@%s'%MAIL_DOMAIN
+
+# Where to place the web filtering HTML on the index page
+FILTER_POSITION = 'bottom' # one of 'top', 'bottom', 'top and bottom'
+
+#
+# SECURITY DEFINITIONS
+#
+# define the Roles that a user gets when they register with the tracker
+# these are a comma-separated string of role names (e.g. 'Admin,User')
+NEW_WEB_USER_ROLES = 'User'
+NEW_EMAIL_USER_ROLES = 'User'
+
+# Send nosy messages to the author of the message
+MESSAGES_TO_AUTHOR = 'no' # either 'yes' or 'no'
+
+# Does the author of a message get placed on the nosy list automatically?
+# If 'new' is used, then the author will only be added when a message
+# creates a new issue. If 'yes', then the author will be added on followups
+# too. If 'no', they're never added to the nosy.
+ADD_AUTHOR_TO_NOSY = 'new' # one of 'yes', 'no', 'new'
+
+# Do the recipients (To:, Cc:) of a message get placed on the nosy list?
+# If 'new' is used, then the recipients will only be added when a message
+# creates a new issue. If 'yes', then the recipients will be added on followups
+# too. If 'no', they're never added to the nosy.
+ADD_RECIPIENTS_TO_NOSY = 'new' # either 'yes', 'no', 'new'
+
+# Where to place the email signature
+EMAIL_SIGNATURE_POSITION = 'bottom' # one of 'top', 'bottom', 'none'
+
+# Keep email citations when accepting messages. Setting this to "no" strips
+# out "quoted" text from the message. Signatures are also stripped.
+EMAIL_KEEP_QUOTED_TEXT = 'yes' # either 'yes' or 'no'
+
+# Preserve the email body as is - that is, keep the citations _and_
+# signatures.
+EMAIL_LEAVE_BODY_UNCHANGED = 'no' # either 'yes' or 'no'
+
+# Default class to use in the mailgw if one isn't supplied in email
+# subjects. To disable, comment out the variable below or leave it blank.
+# Examples:
+MAIL_DEFAULT_CLASS = 'issue' # use "issue" class by default
+#MAIL_DEFAULT_CLASS = '' # disable (or just comment the var out)
+
+# vim: set filetype=python ts=4 sw=4 et si
diff --git a/roundup/templates/minimal/dbinit.py b/roundup/templates/minimal/dbinit.py
--- /dev/null
@@ -0,0 +1,106 @@
+#
+# Copyright (c) 2001 Bizar Software Pty Ltd (http://www.bizarsoftware.com.au/)
+# This module is free software, and you may redistribute it and/or modify
+# under the same terms as Python, so long as this copyright message and
+# disclaimer are retained in their original form.
+#
+# IN NO EVENT SHALL BIZAR SOFTWARE PTY LTD BE LIABLE TO ANY PARTY FOR
+# DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING
+# OUT OF THE USE OF THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# BIZAR SOFTWARE PTY LTD SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS"
+# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
+# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+#
+# $Id: dbinit.py,v 1.1 2002-09-26 04:15:07 richard Exp $
+
+import os
+
+import config
+from select_db import Database, Class, FileClass, IssueClass
+
+def open(name=None):
+ ''' as from the roundupdb method openDB
+ '''
+ from roundup.hyperdb import String, Password, Date, Link, Multilink
+
+ # open the database
+ db = Database(config, name)
+
+ #
+ # Now initialise the schema. Must do this each time the database is
+ # opened.
+ #
+
+ # The "Minimal" template gets only one class, the required "user"
+ # class. That's it. And even that has the bare minimum of properties.
+
+ # Note: roles is a comma-separated string of Role names
+ user = Class(db, "user", username=String(), password=Password(),
+ address=String(), alternate_addresses=String(), roles=String())
+ user.setkey("username")
+
+ #
+ # SECURITY SETTINGS
+ #
+ # new permissions for this schema
+ for cl in ('user', ):
+ db.security.addPermission(name="Edit", klass=cl,
+ description="User is allowed to edit "+cl)
+ db.security.addPermission(name="View", klass=cl,
+ description="User is allowed to access "+cl)
+
+ # and give the regular users access to the web and email interface
+ p = db.security.getPermission('Web Access')
+ db.security.addPermissionToRole('User', p)
+ p = db.security.getPermission('Email Access')
+ db.security.addPermissionToRole('User', p)
+
+ # May users view other user information? Comment these lines out
+ # if you don't want them to
+ p = db.security.getPermission('View', 'user')
+ db.security.addPermissionToRole('User', p)
+
+ # Assign the appropriate permissions to the anonymous user's Anonymous
+ # Role. Choices here are:
+ # - Allow anonymous users to register through the web
+ p = db.security.getPermission('Web Registration')
+ db.security.addPermissionToRole('Anonymous', p)
+ # - Allow anonymous (new) users to register through the email gateway
+ p = db.security.getPermission('Email Registration')
+ db.security.addPermissionToRole('Anonymous', p)
+
+ import detectors
+ detectors.init(db)
+
+ # schema is set up - run any post-initialisation
+ db.post_init()
+ return db
+
+def init(adminpw):
+ ''' as from the roundupdb method initDB
+
+ Open the new database, and add new nodes - used for initialisation. You
+ can edit this before running the "roundup-admin initialise" command to
+ change the initial database entries.
+ '''
+ dbdir = os.path.join(config.DATABASE, 'files')
+ if not os.path.isdir(dbdir):
+ os.makedirs(dbdir)
+
+ db = open("admin")
+ db.clear()
+
+ # create the two default users
+ user = db.getclass('user')
+ user.create(username="admin", password=adminpw,
+ address=config.ADMIN_EMAIL, roles='Admin')
+ user.create(username="anonymous", roles='Anonymous')
+
+ db.commit()
+
+# vim: set filetype=python ts=4 sw=4 et si
+
diff --git a/roundup/templates/minimal/detectors/.cvsignore b/roundup/templates/minimal/detectors/.cvsignore
--- /dev/null
@@ -0,0 +1,3 @@
+*.pyc
+*.pyo
+*.cover
diff --git a/roundup/templates/minimal/detectors/__init__.py b/roundup/templates/minimal/detectors/__init__.py
--- /dev/null
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2001 Bizar Software Pty Ltd (http://www.bizarsoftware.com.au/)
+# This module is free software, and you may redistribute it and/or modify
+# under the same terms as Python, so long as this copyright message and
+# disclaimer are retained in their original form.
+#
+# IN NO EVENT SHALL BIZAR SOFTWARE PTY LTD BE LIABLE TO ANY PARTY FOR
+# DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING
+# OUT OF THE USE OF THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# BIZAR SOFTWARE PTY LTD SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS"
+# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
+# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+#
+#$Id: __init__.py,v 1.1 2002-09-26 04:15:26 richard Exp $
+
+def init(db):
+ ''' execute the init functions of all the modules in this directory
+ '''
+ import os, sys
+ this_dir = os.path.split(__file__)[0]
+ try:
+ sys.path.insert(0, this_dir)
+ for file in os.listdir(this_dir):
+ file, ext = os.path.splitext(file)
+ if file == '__init__':
+ continue
+ if ext == '.py':
+ module = __import__(file)
+ module.init(db)
+ finally:
+ del sys.path[0]
+
+# vim: set filetype=python ts=4 sw=4 et si
diff --git a/roundup/templates/minimal/html/_generic.help b/roundup/templates/minimal/html/_generic.help
--- /dev/null
@@ -0,0 +1,15 @@
+<html>
+<head>
+<link rel="stylesheet" type="text/css" href="_file/style.css">
+</head>
+<body class="body" marginwidth="0" marginheight="0">
+
+<table class="classhelp"
+ tal:define="props python:request.form['properties'].value.split(',')">
+<tr><th tal:repeat="prop props" tal:content="prop"></th></tr>
+<tr tal:repeat="item context/list">
+ <td tal:repeat="prop props" tal:content="python:item[prop]"></td>
+</tr>
+</table>
+
+</body>
diff --git a/roundup/templates/minimal/html/_generic.index b/roundup/templates/minimal/html/_generic.index
--- /dev/null
@@ -0,0 +1,48 @@
+<!-- dollarId: issue.index,v 1.2 2001/07/29 04:07:37 richard Exp dollar-->
+
+<tal:block metal:use-macro="templates/page/macros/icing">
+<title metal:fill-slot="head_title"
+ tal:content="python:context._classname.capitalize()+' editing'"></title>
+<td class="page-header-top" metal:fill-slot="body_title">
+ <h2 tal:content="python:context._classname.capitalize()+' editing'"></h2>
+</td>
+<td class="content" metal:fill-slot="content">
+
+<span tal:condition="python:not (context.is_view_ok() or context.is_edit_ok())">
+You are not allowed to view this page.
+</span>
+
+<tal:block tal:condition="context/is_edit_ok">
+<p class="form-help">
+ You may edit the contents of the <span tal:replace="request/classname" />
+ class using this form. Commas, newlines and double quotes (") must be
+ handled delicately. You may include commas and newlines by enclosing the
+ values in double-quotes ("). Double quotes themselves must be quoted by
+ doubling ("").
+</p>
+
+<p class="form-help">
+ Multilink properties have their multiple values colon (":") separated
+ (... ,"one:two:three", ...)
+</p>
+
+<p class="form-help">
+ Remove entries by deleting their line. Add new entries by appending
+ them to the table - put an X in the id column.
+</p>
+
+<form onSubmit="return submit_once()" method="POST">
+<textarea rows="15" cols="60" name="rows" tal:content="context/csv"></textarea>
+<br>
+<input type="hidden" name=":action" value="editCSV">
+<input type="submit" value="Edit Items">
+</form>
+</tal:block>
+
+<tal:block tal:condition="context/is_only_view_ok">
+view ok
+</tal:block>
+
+</td>
+
+</tal:block>
diff --git a/roundup/templates/minimal/html/_generic.item b/roundup/templates/minimal/html/_generic.item
--- /dev/null
@@ -0,0 +1,56 @@
+<tal:block metal:use-macro="templates/page/macros/icing">
+<title metal:fill-slot="head_title"
+ tal:content="python:context._classname.capitalize()+' editing'"></title>
+<td class="page-header-top" metal:fill-slot="body_title">
+ <h2 tal:content="python:context._classname.capitalize()+' editing'"></h2>
+</td>
+<td class="content" metal:fill-slot="content">
+
+<span tal:condition="python:not (context.is_view_ok() or context.is_edit_ok())">
+You are not allowed to view this page.
+</span>
+
+<form method="POST" onSubmit="return submit_once()"
+ enctype="multipart/form-data" tal:condition="context/is_edit_ok">
+
+<input type="hidden" name=":template" value="item">
+<input type="hidden" name=":required" value="title">
+
+<table class="form">
+
+<tr tal:repeat="prop python:db[context._classname].properties()">
+ <tal:block tal:condition="python:prop._name not in ('id', 'creator',
+ 'creation', 'activity')">
+ <th tal:content="prop/_name"></th>
+ <td tal:content="structure python:context[prop._name].field()"></td>
+ </tal:block>
+</tr>
+<tr>
+ <td> </td>
+ <td colspan=3 tal:content="structure context/submit">
+ submit button will go here
+ </td>
+</tr>
+</table>
+
+</form>
+
+<table class="form" tal:condition="context/is_only_view_ok">
+
+<tr tal:repeat="prop python:db[context._classname].properties()">
+ <tal:block tal:condition="python:prop._name not in ('id', 'creator',
+ 'creation', 'activity')">
+ <th tal:content="prop/_name"></th>
+ <td tal:content="structure python:context[prop._name].field()"></td>
+ </tal:block>
+</tr>
+</table>
+
+
+<tal:block tal:condition="python:context.id and context.is_view_ok()">
+ <tal:block tal:replace="structure context/history" />
+</tal:block>
+
+</td>
+
+</tal:block>
diff --git a/roundup/templates/minimal/html/home b/roundup/templates/minimal/html/home
--- /dev/null
@@ -0,0 +1,25 @@
+<tal:block metal:use-macro="templates/page/macros/icing">
+<title metal:fill-slot="head_title">Tracker home</title>
+<td class="page-header-top" metal:fill-slot="body_title">
+ <h2>Tracker home</h2>
+</td>
+<td class="content" metal:fill-slot="content">
+
+<!--
+ This is the default body that is displayed when people visit the
+ tracker. The tag below lists the currently open issues. You may
+ replace it with a greeting message, or a different list of issues or
+ whatever. It's a good idea to have the issues on the front page though
+-->
+
+<tal:block tal:define="anon python:request.user.username == 'anonymous'">
+<p tal:condition="not:anon" class="help">
+Please select from one of the menu options on the right.
+</p>
+<p tal:condition="anon" class="help">
+Please log in or register.
+</p>
+</tal:block>
+
+</td>
+</tal:block>
diff --git a/roundup/templates/minimal/html/home.classlist b/roundup/templates/minimal/html/home.classlist
--- /dev/null
@@ -0,0 +1,25 @@
+<tal:block metal:use-macro="templates/page/macros/icing">
+<title metal:fill-slot="head_title">List of classes</title>
+<td class="page-header-top" metal:fill-slot="body_title">
+ <h2>List of classes</h2>
+</td>
+<td class="content" metal:fill-slot="content">
+<table class="classlist">
+
+<tal:block tal:repeat="cl db/classes">
+ <tr>
+ <th class="header" colspan="2" align="left">
+ <a tal:attributes="href string:${cl/classname}"
+ tal:content="python:cl.classname.capitalize()">classname</a>
+ </th>
+ </tr>
+ <tr tal:repeat="prop cl/properties">
+ <th tal:content="prop/_name">name</th>
+ <td tal:content="prop/_prop">type</td>
+ </tr>
+</tal:block>
+
+</table>
+</td>
+
+</tal:block>
diff --git a/roundup/templates/minimal/html/page b/roundup/templates/minimal/html/page
--- /dev/null
@@ -0,0 +1,68 @@
+<html metal:define-macro="icing">
+<head>
+<title metal:define-slot="head_title">title goes here</title>
+
+<link rel="stylesheet" type="text/css" href="_file/style.css">
+
+<script tal:replace="structure request/base_javascript">
+</script>
+
+</head>
+<body class="body" marginwidth="0" marginheight="0">
+
+<table class="body">
+
+<tr>
+ <td class="page-header-left"> </td>
+ <td class="page-header-top" metal:define-slot="body_title"><h2>name</h2></td>
+</tr>
+
+<tr>
+ <td rowspan="2" valign="top" nowrap class="sidebar">
+ <p class="userblock" tal:condition="python:request.user.username=='anonymous'">
+ <form method="POST" action="">
+ <input size="10" name="__login_name"><br>
+ <input size="10" type="password" name="__login_password"><br>
+ <input type="submit" name=":action" value="login">
+ <span tal:replace="structure request/indexargs_form" />
+ </form>
+ <a href="user?:template=register">Register</a>
+ </p>
+
+ <p class="userblock" tal:condition="python:request.user.username != 'anonymous'">
+ <b>Hello,</b><br><b tal:content="request/user/username">username</b><br>
+ <a tal:attributes="href string:user${request/user/id}">My Details</a><br>
+ <a tal:attributes="href python:request.indexargs_href('',
+ {':action':'logout'})">Logout</a>
+ </p>
+
+ <p class="classblock"
+ tal:condition="python:request.user.username != 'anonymous'">
+ <b>Administration</b><br>
+ <a tal:condition="python:request.user.hasPermission('Edit', None)"
+ href="home?:template=classlist">Class List</a><br>
+ <a tal:condition="python:request.user.hasPermission('View', 'user')
+ or request.user.hasPermission('Edit', 'user')"
+ href="user" >User List</a><br>
+ <a tal:condition="python:request.user.hasPermission('Edit', 'user')"
+ href="user?:template=item">Add User</a>
+ </p>
+ </td>
+ <td>
+ <p tal:condition="options/error_message | nothing" class="error-message"
+ tal:repeat="m options/error_message" tal:content="structure m">error</p>
+ <p tal:condition="options/ok_message | nothing" class="ok-message"
+ tal:repeat="m options/ok_message" tal:content="structure m">error</p>
+ </td>
+</tr>
+<tr>
+ <td class="content" metal:define-slot="content">Page content goes here</td>
+</tr>
+
+</table>
+
+<pre tal:condition="request/form/debug | nothing" tal:content="request">
+</pre>
+
+</body>
+</html>
diff --git a/roundup/templates/minimal/html/style.css b/roundup/templates/minimal/html/style.css
--- /dev/null
@@ -0,0 +1,305 @@
+/* main page styles */
+body.body {
+ font-family: sans-serif, Arial, Helvetica;
+ color: #333333;
+}
+a[href]:hover { color:blue; text-decoration: underline; }
+a[href]:link { color:blue; text-decoration: none; }
+a[href] { color:blue; text-decoration: none; }
+
+table.body {
+ border: 0;
+ padding: 0;
+ border-spacing: 0px;
+ border-collapse: separate;
+}
+
+td.page-header-left {
+ padding: 5px;
+ border-bottom: 1px solid #444444;
+}
+
+td.page-header-top {
+ border-bottom: 1px solid #444444;
+ padding: 5px;
+}
+
+td.sidebar {
+ padding: 1 0 0 1;
+}
+
+td.sidebar p.classblock {
+ padding: 0 5 0 5;
+ margin: 1 1 1 1;
+ border: 1px solid #444444;
+ background-color: #eeeeee;
+}
+
+td.sidebar p.userblock {
+ padding: 0 5 0 5;
+ margin: 1 1 1 1;
+ border: 1px solid #444444;
+ background-color: #eeeeff;
+}
+
+td.content {
+ padding: 1 5 1 5;
+ vertical-align: top;
+}
+
+p.ok-message {
+ background-color: #22bb22;
+ padding: 5 5 5 5;
+ color: white;
+ font-weight: bold;
+}
+p.error-message {
+ background-color: #bb2222;
+ padding: 5 5 5 5;
+ color: white;
+ font-weight: bold;
+}
+
+
+/* style for forms */
+table.form {
+ padding: 2;
+ border-spacing: 0px;
+ border-collapse: separate;
+}
+
+table.form th {
+ font-weight: bold;
+ color: #333388;
+ text-align: right;
+ vertical-align: top;
+}
+
+table.form th.header {
+ font-weight: bold;
+ color: #333388;
+ background-color: #eeeeff;
+ text-align: left;
+}
+
+table.form td.optional {
+ font-weight: bold;
+ font-style: italic;
+ color: #333333;
+ empty-cells: show;
+}
+
+table.form td {
+ color: #333333;
+ empty-cells: show;
+}
+
+table.form td.html {
+ color: #777777;
+ empty-cells: show;
+}
+
+/* style for lists */
+table.list {
+ border-spacing: 0px;
+ border-collapse: separate;
+ width: 100%;
+}
+
+table.list th {
+ padding: 0 4 0 4;
+ color: #404070;
+ background-color: #eeeeff;
+ border-right: 1px solid #404070;
+ border-top: 1px solid #404070;
+ border-bottom: 1px solid #404070;
+ vertical-align: top;
+}
+table.list th a[href]:hover { color: #404070 }
+table.list th a[href]:link { color: #404070 }
+table.list th a[href] { color: #404070 }
+table.list th.group {
+ background-color: #f4f4ff;
+ text-align: center;
+}
+
+table.list td {
+ padding: 0 4 0 4;
+ border: 0 2 0 2;
+ border-right: 1px solid #404070;
+ color: #404070;
+ background-color: white;
+ vertical-align: top;
+}
+
+table.list tr.normal td {
+ empty-cells: show;
+}
+
+table.list tr.alt td {
+ background-color: #efefef;
+ empty-cells: show;
+}
+
+table.list td:first-child {
+ border-left: 1px solid #404070;
+ border-right: 1px solid #404070;
+ empty-cells: show;
+}
+
+table.list th:first-child {
+ border-left: 1px solid #404070;
+ border-right: 1px solid #404070;
+ empty-cells: show;
+}
+
+
+/* style for message displays */
+table.messages {
+ border-spacing: 0px;
+ border-collapse: separate;
+ width: 100%;
+}
+
+table.messages th.header{
+ padding-top: 10px;
+ border-bottom: 1px solid gray;
+ font-weight: bold;
+ background-color: white;
+ color: #707040;
+}
+
+table.messages th {
+ font-weight: bold;
+ color: black;
+ text-align: left;
+}
+
+table.messages td {
+ font-family: monospace;
+ background-color: #efefef;
+ border-top: 1px solid #afafaf;
+ border-bottom: 1px solid #afafaf;
+ color: black;
+ empty-cells: show;
+}
+
+/* style for file displays */
+table.files {
+ border-spacing: 0px;
+ border-collapse: separate;
+ width: 100%;
+}
+
+table.files th.header{
+ padding-top: 10px;
+ border-bottom: 1px solid gray;
+ font-weight: bold;
+ background-color: white;
+ color: #707040;
+}
+
+table.files th {
+ border-bottom: 1px solid #afafaf;
+ font-weight: bold;
+ text-align: left;
+}
+
+table.files td {
+ font-family: monospace;
+ empty-cells: show;
+}
+
+/* style for history displays */
+table.history {
+ border-spacing: 0px;
+ border-collapse: separate;
+ width: 100%;
+}
+
+table.history th.header{
+ padding-top: 10px;
+ border-bottom: 1px solid gray;
+ font-weight: bold;
+ background-color: white;
+ color: #707040;
+ font-size: 100%;
+}
+
+table.history th {
+ border-bottom: 1px solid #afafaf;
+ font-weight: bold;
+ text-align: left;
+ font-size: 90%;
+}
+
+table.history td {
+ font-size: 90%;
+ vertical-align: top;
+ empty-cells: show;
+}
+
+
+/* style for class list */
+table.classlist {
+ border-spacing: 0px;
+ border-collapse: separate;
+ width: 100%;
+}
+
+table.classlist th.header{
+ padding-top: 10px;
+ border-bottom: 1px solid gray;
+ font-weight: bold;
+ background-color: white;
+ color: #707040;
+}
+
+table.classlist th {
+ font-weight: bold;
+ text-align: left;
+}
+
+
+/* style for class help display */
+table.classhelp {
+ border-spacing: 0px;
+ border-collapse: separate;
+ width: 100%;
+}
+
+table.classhelp th {
+ font-weight: bold;
+ text-align: left;
+ color: #707040;
+}
+
+table.classhelp td {
+ padding: 2 2 2 2;
+ border: 1px solid black;
+ text-align: left;
+ vertical-align: top;
+ empty-cells: show;
+}
+
+
+/* style for "other" displays */
+table.otherinfo {
+ border-spacing: 0px;
+ border-collapse: separate;
+ width: 100%;
+}
+
+table.otherinfo th.header{
+ padding-top: 10px;
+ border-bottom: 1px solid gray;
+ font-weight: bold;
+ background-color: white;
+ color: #707040;
+}
+
+table.otherinfo th {
+ border-bottom: 1px solid #afafaf;
+ font-weight: bold;
+ text-align: left;
+}
diff --git a/roundup/templates/minimal/html/user.index b/roundup/templates/minimal/html/user.index
--- /dev/null
@@ -0,0 +1,29 @@
+<!-- dollarId: user.index,v 1.3 2002/07/09 05:29:51 richard Exp dollar-->
+<tal:block metal:use-macro="templates/page/macros/icing">
+<title metal:fill-slot="head_title">User listing</title>
+<td class="page-header-top" metal:fill-slot="body_title">
+ <h2>User listing</h2>
+</td>
+<td class="content" metal:fill-slot="content">
+
+<span tal:condition="not:context/is_view_ok">
+You are not allowed to view this page.
+</span>
+
+<table width="100%" tal:condition="context/is_view_ok" class="list">
+<tr>
+ <th>Username</th>
+ <th>Email address</th>
+</tr>
+<tr tal:repeat="user context/list"
+ tal:attributes="class python:['row-normal', 'row-alt'][repeat['user'].even()]">
+ <td>
+ <a tal:attributes="href string:user${user/id}"
+ tal:content="user/username">username</a>
+ </td>
+ <td tal:content="python:user.address.email()">address</td>
+</tr>
+</table>
+</td>
+
+</tal:block>
diff --git a/roundup/templates/minimal/html/user.item b/roundup/templates/minimal/html/user.item
--- /dev/null
@@ -0,0 +1,70 @@
+<!-- dollarId: user.item,v 1.7 2002/08/16 04:29:04 richard Exp dollar-->
+<tal:block metal:use-macro="templates/page/macros/icing">
+<title metal:fill-slot="head_title">User editing</title>
+<td class="page-header-top" metal:fill-slot="body_title">
+ <h2>User editing</h2>
+</td>
+<td class="content" metal:fill-slot="content">
+<span tal:condition="python:not (context.is_view_ok() or context.is_edit_ok())">
+You are not allowed to view this page.
+</span>
+
+<form method="POST" onSubmit="return submit_once()"
+ enctype="multipart/form-data" tal:condition="context/is_edit_ok">
+
+<input type="hidden" name=":required" value="username,address">
+
+<table class="form">
+ <tr>
+ <th>Login Name</th>
+ <td tal:content="structure context/username/field">username</td>
+ </tr>
+ <tr>
+ <th>Login Password</th>
+ <td tal:content="structure context/password/field">password</td>
+ </tr>
+ <tr>
+ <th>Confirm Password</th>
+ <td tal:content="structure context/password/confirm">password</td>
+ </tr>
+ <tr tal:condition="python:request.user.hasPermission('Web Roles')">
+ <th>Roles</th>
+ <td tal:condition="context/id"
+ tal:content="structure context/roles/field">roles</td>
+ <td tal:condition="not:context/id">
+ <input name="roles" tal:attributes="value db/config/NEW_WEB_USER_ROLES">
+ </td>
+ </tr>
+ <tr>
+ <th>E-mail address</th>
+ <td tal:content="structure context/address/field">address</td>
+ </tr>
+ <tr>
+ <th>Alternate E-mail addresses<br>One address per line</th>
+ <td tal:content="structure context/alternate_addresses/multiline">alternate_addresses</td>
+ </tr>
+
+ <tr>
+ <td> </td>
+ <td tal:content="structure context/submit">submit button here</td>
+ </tr>
+</table>
+</form>
+
+<table class="form" tal:condition="context/is_only_view_ok">
+ <tr>
+ <th>Login Name</th>
+ <td tal:content="context/username">username</td>
+ </tr>
+ <tr>
+ <th>E-mail address</th>
+ <td tal:content="context/address/email">address</td>
+ </tr>
+</table>
+
+<tal:block tal:condition="python:context.id and context.is_view_ok()"
+ tal:replace="structure context/history" />
+
+</td>
+
+</tal:block>
diff --git a/roundup/templates/minimal/html/user.register b/roundup/templates/minimal/html/user.register
--- /dev/null
@@ -0,0 +1,82 @@
+<!-- dollarId: user.item,v 1.7 2002/08/16 04:29:04 richard Exp dollar-->
+<tal:block metal:use-macro="templates/page/macros/icing">
+<title metal:fill-slot="head_title"
+ tal:content="string:Registering with ${db/config/TRACKER_NAME}"></title>
+<td class="page-header-top" metal:fill-slot="body_title">
+ <h2 tal:content="string:Registering with ${db/config/TRACKER_NAME}"></h2>
+</td>
+<td class="content" metal:fill-slot="content">
+
+<tal:block tal:define=" editok python:request.user.username=='anonymous' and
+ request.user.hasPermission('Web Registration')">
+
+<span tal:condition="python:not editok">
+You are not allowed to view this page.
+</span>
+
+<tal:block tal:condition="editok">
+<form method="POST" onSubmit="return submit_once()" enctype="multipart/form-data">
+<input type="hidden" name=":template" value="register">
+<input type="hidden" name=":required" value="username">
+<input type="hidden" name=":required" value="password">
+<input type="hidden" name=":required" value="address">
+
+<table class="form">
+ <tr>
+ <th>Name</th>
+ <td tal:content="structure context/realname/field">realname</td>
+ </tr>
+ <tr>
+ <th>Login Name</th>
+ <td tal:content="structure context/username/field">username</td>
+ </tr>
+ <tr>
+ <th>Login Password</th>
+ <td tal:content="structure context/password/field">password</td>
+ </tr>
+ <tr>
+ <th>Confirm Password</th>
+ <td tal:content="structure context/password/confirm">password</td>
+ </tr>
+ <tr tal:condition="python:request.user.hasPermission('Web Roles')">
+ <th>Roles</th>
+ <td tal:condition="exists:item"
+ tal:content="structure context/roles/field">roles</td>
+ <td tal:condition="not:exists:item">
+ <input name="roles" tal:attributes="value db/config/NEW_WEB_USER_ROLES">
+ </td>
+ </tr>
+ <tr>
+ <th>Phone</th>
+ <td tal:content="structure context/phone/field">phone</td>
+ </tr>
+ <tr>
+ <th>Organisation</th>
+ <td tal:content="structure context/organisation/field">organisation</td>
+ </tr>
+ <tr>
+ <th>E-mail address</th>
+ <td tal:content="structure context/address/field">address</td>
+ </tr>
+ <tr>
+ <th>Alternate E-mail addresses<br>One address per line</th>
+ <td tal:content="structure context/alternate_addresses/multiline">alternate_addresses</td>
+ </tr>
+
+ <tr>
+ <td> </td>
+ <td>
+ <input type="hidden" name=":action" value="register">
+ <input type="submit" name="submit" value="Register">
+ </td>
+ </tr>
+</table>
+</form>
+
+</tal:block>
+
+</tal:block>
+
+</td>
+
+</tal:block>
diff --git a/roundup/templates/minimal/interfaces.py b/roundup/templates/minimal/interfaces.py
--- /dev/null
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2001 Bizar Software Pty Ltd (http://www.bizarsoftware.com.au/)
+# This module is free software, and you may redistribute it and/or modify
+# under the same terms as Python, so long as this copyright message and
+# disclaimer are retained in their original form.
+#
+# IN NO EVENT SHALL BIZAR SOFTWARE PTY LTD BE LIABLE TO ANY PARTY FOR
+# DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING
+# OUT OF THE USE OF THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# BIZAR SOFTWARE PTY LTD SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS"
+# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
+# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+#
+# $Id: interfaces.py,v 1.1 2002-09-26 04:15:07 richard Exp $
+
+from roundup import mailgw
+from roundup.cgi import client
+
+class Client(client.Client):
+ ''' derives basic CGI implementation from the standard module,
+ with any specific extensions
+ '''
+ pass
+
+class MailGW(mailgw.MailGW):
+ ''' derives basic mail gateway implementation from the standard module,
+ with any specific extensions
+ '''
+ pass
+
+# vim: set filetype=python ts=4 sw=4 et si