From: stefan Date: Mon, 23 Feb 2009 15:31:29 +0000 (+0000) Subject: Move templates/ to share/roundup/templates/ X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=9e6501cd917b0424f4711b7e5ec2399bcaa190f4;p=roundup.git Move templates/ to share/roundup/templates/ git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/roundup/trunk@4161 57a73879-2fb5-44c3-a270-3262357dd7e2 --- diff --git a/demo.py b/demo.py index b911541..66b1e35 100644 --- a/demo.py +++ b/demo.py @@ -127,7 +127,7 @@ def demo_main(): backend = sys.argv[-2] else: backend = 'anydbm' - install_demo(home, backend, os.path.join('templates', 'classic')) + install_demo(home, backend, os.path.join('share', 'roundup', 'templates', 'classic')) run_demo(home) if __name__ == '__main__': diff --git a/setup.py b/setup.py index 27d533d..3a02097 100644 --- a/setup.py +++ b/setup.py @@ -78,7 +78,7 @@ def main(): # add the templates to the data files lists from roundup.init import listTemplates - templates = [t['path'] for t in listTemplates('templates').values()] + templates = [t['path'] for t in listTemplates(os.path.join('share','roundup','templates')).values()] for tdir in templates: # scan for data files for idir in '. detectors extensions html'.split(): diff --git a/share/roundup/templates/classic/.cvsignore b/share/roundup/templates/classic/.cvsignore new file mode 100644 index 0000000..d90d51d --- /dev/null +++ b/share/roundup/templates/classic/.cvsignore @@ -0,0 +1,4 @@ +*.pyc +*.pyo +htmlbase.py +*.cover diff --git a/share/roundup/templates/classic/TEMPLATE-INFO.txt b/share/roundup/templates/classic/TEMPLATE-INFO.txt new file mode 100644 index 0000000..1c20d54 --- /dev/null +++ b/share/roundup/templates/classic/TEMPLATE-INFO.txt @@ -0,0 +1,7 @@ +Name: classic +Description: This is a generic issue tracker that may be used to track bugs, + feature requests, project issues or any number of other types + of issues. Most users of Roundup will find that this template + suits them, with perhaps a few customisations. +Intended-For: All first-time Roundup users + diff --git a/share/roundup/templates/classic/detectors/.cvsignore b/share/roundup/templates/classic/detectors/.cvsignore new file mode 100644 index 0000000..4162d5e --- /dev/null +++ b/share/roundup/templates/classic/detectors/.cvsignore @@ -0,0 +1,3 @@ +*.pyc +*.pyo +*.cover diff --git a/share/roundup/templates/classic/detectors/messagesummary.py b/share/roundup/templates/classic/detectors/messagesummary.py new file mode 100644 index 0000000..def2e82 --- /dev/null +++ b/share/roundup/templates/classic/detectors/messagesummary.py @@ -0,0 +1,19 @@ +#$Id: messagesummary.py,v 1.2 2007-04-03 06:47:21 a1s Exp $ + +from roundup.mailgw import parseContent + +def summarygenerator(db, cl, nodeid, newvalues): + ''' If the message doesn't have a summary, make one for it. + ''' + if newvalues.has_key('summary') or not newvalues.has_key('content'): + return + + summary, content = parseContent(newvalues['content'], config=db.config) + newvalues['summary'] = summary + + +def init(db): + # fire before changes are made + db.msg.audit('create', summarygenerator) + +# vim: set filetype=python ts=4 sw=4 et si diff --git a/share/roundup/templates/classic/detectors/nosyreaction.py b/share/roundup/templates/classic/detectors/nosyreaction.py new file mode 100644 index 0000000..c732fd0 --- /dev/null +++ b/share/roundup/templates/classic/detectors/nosyreaction.py @@ -0,0 +1,143 @@ +# +# 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: nosyreaction.py,v 1.4 2005-04-04 08:47:14 richard Exp $ + +import sets + +from roundup import roundupdb, hyperdb + +def nosyreaction(db, cl, nodeid, oldvalues): + ''' A standard detector is provided that watches for additions to the + "messages" property. + + When a new message is added, the detector sends it to all the users on + the "nosy" list for the issue that are not already on the "recipients" + list of the message. + + Those users are then appended to the "recipients" property on the + message, so multiple copies of a message are never sent to the same + user. + + The journal recorded by the hyperdatabase on the "recipients" property + then provides a log of when the message was sent to whom. + ''' + # send a copy of all new messages to the nosy list + for msgid in determineNewMessages(cl, nodeid, oldvalues): + try: + cl.nosymessage(nodeid, msgid, oldvalues) + except roundupdb.MessageSendError, message: + raise roundupdb.DetectorError, message + +def determineNewMessages(cl, nodeid, oldvalues): + ''' Figure a list of the messages that are being added to the given + node in this transaction. + ''' + messages = [] + if oldvalues is None: + # the action was a create, so use all the messages in the create + messages = cl.get(nodeid, 'messages') + elif oldvalues.has_key('messages'): + # the action was a set (so adding new messages to an existing issue) + m = {} + for msgid in oldvalues['messages']: + m[msgid] = 1 + messages = [] + # figure which of the messages now on the issue weren't there before + for msgid in cl.get(nodeid, 'messages'): + if not m.has_key(msgid): + messages.append(msgid) + return messages + +def updatenosy(db, cl, nodeid, newvalues): + '''Update the nosy list for changes to the assignedto + ''' + # nodeid will be None if this is a new node + current_nosy = sets.Set() + if nodeid is None: + ok = ('new', 'yes') + else: + ok = ('yes',) + # old node, get the current values from the node if they haven't + # changed + if not newvalues.has_key('nosy'): + nosy = cl.get(nodeid, 'nosy') + for value in nosy: + current_nosy.add(value) + + # if the nosy list changed in this transaction, init from the new value + if newvalues.has_key('nosy'): + nosy = newvalues.get('nosy', []) + for value in nosy: + if not db.hasnode('user', value): + continue + current_nosy.add(value) + + new_nosy = sets.Set(current_nosy) + + # add assignedto(s) to the nosy list + if newvalues.has_key('assignedto') and newvalues['assignedto'] is not None: + propdef = cl.getprops() + if isinstance(propdef['assignedto'], hyperdb.Link): + assignedto_ids = [newvalues['assignedto']] + elif isinstance(propdef['assignedto'], hyperdb.Multilink): + assignedto_ids = newvalues['assignedto'] + for assignedto_id in assignedto_ids: + new_nosy.add(assignedto_id) + + # see if there's any new messages - if so, possibly add the author and + # recipient to the nosy + if newvalues.has_key('messages'): + if nodeid is None: + ok = ('new', 'yes') + messages = newvalues['messages'] + else: + ok = ('yes',) + # figure which of the messages now on the issue weren't + oldmessages = cl.get(nodeid, 'messages') + messages = [] + for msgid in newvalues['messages']: + if msgid not in oldmessages: + messages.append(msgid) + + # configs for nosy modifications + add_author = getattr(db.config, 'ADD_AUTHOR_TO_NOSY', 'new') + add_recips = getattr(db.config, 'ADD_RECIPIENTS_TO_NOSY', 'new') + + # now for each new message: + msg = db.msg + for msgid in messages: + if add_author in ok: + authid = msg.get(msgid, 'author') + new_nosy.add(authid) + + # add on the recipients of the message + if add_recips in ok: + for recipient in msg.get(msgid, 'recipients'): + new_nosy.add(recipient) + + if current_nosy != new_nosy: + # that's it, save off the new nosy list + newvalues['nosy'] = list(new_nosy) + +def init(db): + db.issue.react('create', nosyreaction) + db.issue.react('set', nosyreaction) + db.issue.audit('create', updatenosy) + db.issue.audit('set', updatenosy) + +# vim: set filetype=python ts=4 sw=4 et si diff --git a/share/roundup/templates/classic/detectors/statusauditor.py b/share/roundup/templates/classic/detectors/statusauditor.py new file mode 100644 index 0000000..75e4962 --- /dev/null +++ b/share/roundup/templates/classic/detectors/statusauditor.py @@ -0,0 +1,85 @@ +# Copyright (c) 2002 ekit.com Inc (http://www.ekit-inc.com/) +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +#$Id: statusauditor.py,v 1.5 2004-03-27 00:01:48 richard Exp $ + +def chatty(db, cl, nodeid, newvalues): + ''' If the issue is currently 'unread', 'resolved', 'done-cbb' or None, + then set it to 'chatting' + ''' + # don't fire if there's no new message (ie. chat) + if not newvalues.has_key('messages'): + return + if newvalues['messages'] == cl.get(nodeid, 'messages'): + return + + # get the chatting state ID + try: + chatting_id = db.status.lookup('chatting') + except KeyError: + # no chatting state, ignore all this stuff + return + + # get the current value + current_status = cl.get(nodeid, 'status') + + # see if there's an explicit change in this transaction + if newvalues.has_key('status'): + # yep, skip + return + + # determine the id of 'unread', 'resolved' and 'chatting' + fromstates = [] + for state in 'unread resolved done-cbb'.split(): + try: + fromstates.append(db.status.lookup(state)) + except KeyError: + pass + + # ok, there's no explicit change, so check if we are in a state that + # should be changed + if current_status in fromstates + [None]: + # yep, we're now chatting + newvalues['status'] = chatting_id + + +def presetunread(db, cl, nodeid, newvalues): + ''' Make sure the status is set on new issues + ''' + if newvalues.has_key('status') and newvalues['status']: + return + + # get the unread state ID + try: + unread_id = db.status.lookup('unread') + except KeyError: + # no unread state, ignore all this stuff + return + + # ok, do it + newvalues['status'] = unread_id + + +def init(db): + # fire before changes are made + db.issue.audit('set', chatty) + db.issue.audit('create', presetunread) + +# vim: set filetype=python ts=4 sw=4 et si diff --git a/share/roundup/templates/classic/detectors/userauditor.py b/share/roundup/templates/classic/detectors/userauditor.py new file mode 100644 index 0000000..fc71a1c --- /dev/null +++ b/share/roundup/templates/classic/detectors/userauditor.py @@ -0,0 +1,94 @@ +# Copyright (c) 2003 Richard Jones (richard@mechanicalcat.net) +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +#$Id: userauditor.py,v 1.9 2007-09-12 21:11:13 jpend Exp $ + +import re + +# regular expression thanks to: http://www.regular-expressions.info/email.html +# this is the "99.99% solution for syntax only". +email_regexp = (r"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*", r"(localhost|(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9]))") +email_rfc = re.compile('^' + email_regexp[0] + '@' + email_regexp[1] + '$', re.IGNORECASE) +email_local = re.compile('^' + email_regexp[0] + '$', re.IGNORECASE) + +def valid_address(address): + ''' If we see an @-symbol in the address then check against the full + RFC syntax. Otherwise it is a local-only address so only check + the local part of the RFC syntax. + ''' + if '@' in address: + return email_rfc.match(address) + else: + return email_local.match(address) + +def get_addresses(user): + ''' iterate over all known addresses in a newvalues dict + this takes of the address/alterate_addresses handling + ''' + if user.has_key('address'): + yield user['address'] + if user.get('alternate_addresses', None): + for address in user['alternate_addresses'].split('\n'): + yield address + +def audit_user_fields(db, cl, nodeid, newvalues): + ''' Make sure user properties are valid. + + - email address is syntactically valid + - email address is unique + - roles specified exist + - timezone is valid + ''' + + for address in get_addresses(newvalues): + if not valid_address(address): + raise ValueError, 'Email address syntax is invalid' + + check_main = db.user.stringFind(address=address) + # make sure none of the alts are owned by anyone other than us (x!=nodeid) + check_alts = [x for x in db.user.filter(None, {'alternate_addresses' : address}) if x != nodeid] + if check_main or check_alts: + raise ValueError, 'Email address %s already in use' % address + + for rolename in [r.lower().strip() for r in newvalues.get('roles', '').split(',')]: + if rolename and not db.security.role.has_key(rolename): + raise ValueError, 'Role "%s" does not exist'%rolename + + tz = newvalues.get('timezone', None) + if tz: + # if they set a new timezone validate the timezone by attempting to + # use it before we store it to the db. + import roundup.date + import datetime + try: + TZ = roundup.date.get_timezone(tz) + dt = datetime.datetime.now() + local = TZ.localize(dt).utctimetuple() + except IOError: + raise ValueError, 'Timezone "%s" does not exist' % tz + except ValueError: + raise ValueError, 'Timezone "%s" exceeds valid range [-23...23]' % tz + +def init(db): + # fire before changes are made + db.user.audit('set', audit_user_fields) + db.user.audit('create', audit_user_fields) + +# vim: sts=4 sw=4 et si diff --git a/share/roundup/templates/classic/extensions/README.txt b/share/roundup/templates/classic/extensions/README.txt new file mode 100644 index 0000000..ff4dff3 --- /dev/null +++ b/share/roundup/templates/classic/extensions/README.txt @@ -0,0 +1,6 @@ +This directory is for tracker extensions: + +- CGI Actions +- Templating functions + +See the customisation doc for more information. diff --git a/share/roundup/templates/classic/html/_generic.404.html b/share/roundup/templates/classic/html/_generic.404.html new file mode 100644 index 0000000..71c9e0e --- /dev/null +++ b/share/roundup/templates/classic/html/_generic.404.html @@ -0,0 +1,9 @@ + + +Item Not Found + + + +There is no with id + + diff --git a/share/roundup/templates/classic/html/_generic.calendar.html b/share/roundup/templates/classic/html/_generic.calendar.html new file mode 100644 index 0000000..0f9cf40 --- /dev/null +++ b/share/roundup/templates/classic/html/_generic.calendar.html @@ -0,0 +1,18 @@ + + + + + + + + + + + diff --git a/share/roundup/templates/classic/html/_generic.collision.html b/share/roundup/templates/classic/html/_generic.collision.html new file mode 100644 index 0000000..2a2768a --- /dev/null +++ b/share/roundup/templates/classic/html/_generic.collision.html @@ -0,0 +1,16 @@ + +<span tal:replace="python:context._classname.capitalize()" + i18n:name="class" /> Edit Collision - <span i18n:name="tracker" + tal:replace="config/TRACKER_NAME" /> + Edit Collision + + + + diff --git a/share/roundup/templates/classic/html/_generic.help-empty.html b/share/roundup/templates/classic/html/_generic.help-empty.html new file mode 100644 index 0000000..65469fc --- /dev/null +++ b/share/roundup/templates/classic/html/_generic.help-empty.html @@ -0,0 +1,8 @@ + + + Empty page (no search performed yet) + + +

Please specify your search parameters!

+ + diff --git a/share/roundup/templates/classic/html/_generic.help-list.html b/share/roundup/templates/classic/html/_generic.help-list.html new file mode 100644 index 0000000..66cbb90 --- /dev/null +++ b/share/roundup/templates/classic/html/_generic.help-list.html @@ -0,0 +1,83 @@ + + + Search result for user helper + + + + + + +
+
+  

You are not + allowed to view this page.

+ + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + +
 x
+ + + +
+
+
+
+ +
+     
+  
+
diff --git a/share/roundup/templates/classic/html/_generic.help-search.html b/share/roundup/templates/classic/html/_generic.help-search.html
new file mode 100644
index 0000000..01d657e
--- /dev/null
+++ b/share/roundup/templates/classic/html/_generic.help-search.html
@@ -0,0 +1,13 @@
+
+  
+    Frame for search input fields
+  
+  
+    

Generic template + help-search + or version for class + user + is not yet implemented

+ + + diff --git a/share/roundup/templates/classic/html/_generic.help-submit.html b/share/roundup/templates/classic/html/_generic.help-submit.html new file mode 100644 index 0000000..b13aa4a --- /dev/null +++ b/share/roundup/templates/classic/html/_generic.help-submit.html @@ -0,0 +1,73 @@ + + + + + + Generic submit page for framed helper windows + + + + + +
+ 
+
+ +
+ + + + +
+ + + diff --git a/share/roundup/templates/classic/html/_generic.help.html b/share/roundup/templates/classic/html/_generic.help.html new file mode 100644 index 0000000..069c0a6 --- /dev/null +++ b/share/roundup/templates/classic/html/_generic.help.html @@ -0,0 +1,98 @@ + + + + + + + <tal:x i18n:name="property" + tal:content="property" i18n:translate="" /> help - <span i18n:name="tracker" + tal:replace="config/TRACKER_NAME" /> + + + + + +
+ +
+ + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + +
 x
+ + + +
 x
+ +
+ + diff --git a/share/roundup/templates/classic/html/_generic.index.html b/share/roundup/templates/classic/html/_generic.index.html new file mode 100644 index 0000000..a41ab0a --- /dev/null +++ b/share/roundup/templates/classic/html/_generic.index.html @@ -0,0 +1,70 @@ + + + +<span tal:replace="python:context._classname.capitalize()" + i18n:name="class" /> editing - <span i18n:name="tracker" + tal:replace="config/TRACKER_NAME" /> + editing + + + +You are not allowed to view this page. + +Please login with your username and password. + + + +

+ You may edit the contents of the + + 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 (""). +

+ +

+ Multilink properties have their multiple values colon (":") separated + (... ,"one:two:three", ...) +

+ +

+ Remove entries by deleting their line. Add new entries by appending + them to the table - put an X in the id column. +

+
+
+ +
+ + +
+
+ + + + + + + + + + +
 
 
+ + + +
diff --git a/share/roundup/templates/classic/html/_generic.item.html b/share/roundup/templates/classic/html/_generic.item.html new file mode 100644 index 0000000..d9b98ae --- /dev/null +++ b/share/roundup/templates/classic/html/_generic.item.html @@ -0,0 +1,53 @@ + +<span tal:replace="python:context._classname.capitalize()" + i18n:name="class" /> editing - <span i18n:name="tracker" + tal:replace="config/TRACKER_NAME" /> + editing + + + +

+ You are not allowed to view this page.

+ +

+ Please login with your username and password.

+ +
+ +
+ + + + + + + + + + + + + + + +
  + submit button will go here +
+ +
+ + + +
+ + + +
diff --git a/share/roundup/templates/classic/html/file.index.html b/share/roundup/templates/classic/html/file.index.html new file mode 100644 index 0000000..9717920 --- /dev/null +++ b/share/roundup/templates/classic/html/file.index.html @@ -0,0 +1,31 @@ + + +List of files - <span tal:replace="config/TRACKER_NAME" i18n:name="tracker" /> +List of files + + + + + + + + + + + + + + + + + +
DownloadContent TypeUploaded ByDate
+ dld link + content typecreator's namecreation date
+ + + +
diff --git a/share/roundup/templates/classic/html/file.item.html b/share/roundup/templates/classic/html/file.item.html new file mode 100644 index 0000000..d223fd7 --- /dev/null +++ b/share/roundup/templates/classic/html/file.item.html @@ -0,0 +1,53 @@ + +File display - <span + i18n:name="tracker" tal:replace="config/TRACKER_NAME" /> +File display + + + +

+ You are not allowed to view this page.

+ +

+ Please login with your username and password.

+ +
+ + + + + + + + + + + + + + + +
Name
Content Type
+   + + + + submit button here
+
+ +download + + + + + + diff --git a/share/roundup/templates/classic/html/help.html b/share/roundup/templates/classic/html/help.html new file mode 100644 index 0000000..1571a6f --- /dev/null +++ b/share/roundup/templates/classic/html/help.html @@ -0,0 +1,38 @@ + + + + + + x + + + + + + + + + + +
diff --git a/share/roundup/templates/classic/html/help_controls.js b/share/roundup/templates/classic/html/help_controls.js new file mode 100644 index 0000000..480170a --- /dev/null +++ b/share/roundup/templates/classic/html/help_controls.js @@ -0,0 +1,324 @@ +// initial values for either Nosy, Superseder, Keyword and Waiting On, +// depending on which has called +original_field = form[field].value; + +// Some browsers (ok, IE) don't define the "undefined" variable. +undefined = document.geez_IE_is_really_friggin_annoying; + +function trim(value) { + var temp = value; + var obj = /^(\s*)([\W\w]*)(\b\s*$)/; + if (obj.test(temp)) { temp = temp.replace(obj, '$2'); } + var obj = / /g; + while (temp.match(obj)) { temp = temp.replace(obj, " "); } + return temp; +} + +function determineList() { + // generate a comma-separated list of the checked items + var list = new String(''); + + // either a checkbox object or an array of checkboxes + var check = document.frm_help.check; + + if ((check.length == undefined) && (check.checked != undefined)) { + // only one checkbox on page + if (check.checked) { + list = check.value; + } + } else { + // array of checkboxes + for (box=0; box < check.length; box++) { + if (check[box].checked) { + if (list.length == 0) { + separator = ''; + } + else { + separator = ','; + } + // we used to use an Array and push / join, but IE5.0 sux + list = list + separator + check[box].value; + } + } + } + return list; +} + +/** + * update the field in the opening window; + * the text_field variable must be set in the calling page + */ +function updateOpener() { + // write back to opener window + if (document.frm_help.check==undefined) { return; } + form[field].value = text_field.value; +} + +function updateList() { + // write back to opener window + if (document.frm_help.check==undefined) { return; } + form[field].value = determineList(); +} + +function updatePreview() { + // update the preview box + if (document.frm_help.check==undefined) { return; } + writePreview(determineList()); +} + +function clearList() { + // uncheck all checkboxes + if (document.frm_help.check==undefined) { return; } + for (box=0; box < document.frm_help.check.length; box++) { + document.frm_help.check[box].checked = false; + } +} + +function reviseList_framed(form, textfield) { + // update the checkboxes based on the preview field + // alert('reviseList_framed') + // alert(form) + if (form.check==undefined) + return; + // alert(textfield) + var to_check; + var list = textfield.value.split(","); + if (form.check.length==undefined) { + check = form.check; + to_check = false; + for (val in list) { + if (check.value==trim(list[val])) { + to_check = true; + break; + } + } + check.checked = to_check; + } else { + for (box=0; box < form.check.length; box++) { + check = form.check[box]; + to_check = false; + for (val in list) { + if (check.value==trim(list[val])) { + to_check = true; + break; + } + } + check.checked = to_check; + } + } +} + +function reviseList(vals) { + // update the checkboxes based on the preview field + if (document.frm_help.check==undefined) { return; } + var to_check; + var list = vals.split(","); + if (document.frm_help.check.length==undefined) { + check = document.frm_help.check; + to_check = false; + for (val in list) { + if (check.value==trim(list[val])) { + to_check = true; + break; + } + } + check.checked = to_check; + } else { + for (box=0; box < document.frm_help.check.length; box++) { + check = document.frm_help.check[box]; + to_check = false; + for (val in list) { + if (check.value==trim(list[val])) { + to_check = true; + break; + } + } + check.checked = to_check; + } + } +} + +function resetList() { + // reset preview and check boxes to initial values + if (document.frm_help.check==undefined) { return; } + writePreview(original_field); + reviseList(original_field); +} + +function writePreview(val) { + // writes a value to the text_preview + document.frm_help.text_preview.value = val; +} + +function focusField(name) { + for(i=0; i < document.forms.length; ++i) { + var obj = document.forms[i].elements[name]; + if (obj && obj.focus) {obj.focus();} + } +} + +function selectField(name) { + for(i=0; i < document.forms.length; ++i) { + var obj = document.forms[i].elements[name]; + if (obj && obj.focus){obj.focus();} + if (obj && obj.select){obj.select();} + } +} + +function checkRequiredFields(fields) +{ + var bonk=''; + var res=''; + var argv = checkRequiredFields.arguments; + var argc = argv.length; + var input = ''; + var val=''; + + for (var i=0; i < argc; i++) { + fi = argv[i]; + input = document.getElementById(fi); + if (input) { + val = input.value + if (val == '' || val == '-1' || val == -1) { + if (res == '') { + res = fi; + bonk = input; + } else { + res += ', '+fi; + } + } + } else { + alert('Field with id='+fi+' not found!') + } + } + if (res == '') { + return submit_once(); + } else { + alert('Missing value here ('+res+')!'); + if (window.event && window.event.returnvalue) { + event.returnValue = 0; // work-around for IE + } + bonk.focus(); + return false; + } +} + +/** + * seeks the given value (2nd argument) + * in the value of the given input element (1st argument), + * which is considered a list of values, separated by commas + */ +function has_value(input, val) +{ + var actval = input.value + var arr = feld.value.split(','); + var max = arr.length; + for (i=0;i remove_val() + * + * This will work nicely even for batched lists + */ +function append_val(name, val) +{ + var feld = document.itemSynopsis[name]; + var actval = feld.value; + if (actval == '') { + feld.value = val + } else { + var arr = feld.value.split(','); + var max = arr.length; + for (i=0;i append_val() + */ +function remove_val(name, val) +{ + var feld = document.itemSynopsis[name]; + var actval = feld.value; + var changed=false; + if (actval == '') { + return + } else { + var arr = feld.value.split(','); + var max = arr.length; + var neu = '' + for (i=0;i +List of classes - <span + i18n:name="tracker" tal:replace="config/TRACKER_NAME" /> +List of classes + + + + + + + + + + + + + +
+ classname +
nametype
+ + +
diff --git a/share/roundup/templates/classic/html/home.html b/share/roundup/templates/classic/html/home.html new file mode 100644 index 0000000..90d926a --- /dev/null +++ b/share/roundup/templates/classic/html/home.html @@ -0,0 +1,10 @@ + + diff --git a/share/roundup/templates/classic/html/issue.index.html b/share/roundup/templates/classic/html/issue.index.html new file mode 100644 index 0000000..581624c --- /dev/null +++ b/share/roundup/templates/classic/html/issue.index.html @@ -0,0 +1,166 @@ + + + + <span tal:omit-tag="true" i18n:translate="" >List of issues</span> + <span tal:condition="request/dispname" + tal:replace="python:' - %s '%request.dispname" + /> - <span tal:replace="config/TRACKER_NAME" /> + + + List of issues + + + + +

+ You are not allowed to view this page.

+ +

+ Please login with your username and password.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PriorityIDCreationActivityActorKeywordTitleStatusCreatorAssigned To
+ + + +
       + title +    
+ + + + + + +
+
+ +Download as CSV + +
+ + + + + + + + + + + + + + + + + + + +
+ Sort on: + + + Descending: +
+ Group on: + + + Descending: +
+ + +
+
+ +
+ + +
vim: sw=1 ts=8 et si + diff --git a/share/roundup/templates/classic/html/issue.item.html b/share/roundup/templates/classic/html/issue.item.html new file mode 100644 index 0000000..41ee073 --- /dev/null +++ b/share/roundup/templates/classic/html/issue.item.html @@ -0,0 +1,197 @@ + + + +<tal:block condition="context/id" i18n:translate="" + >Issue <tal:x tal:content="context/id" i18n:name="id" + />: <tal:x content="context/title" i18n:name="title" + /> - <tal:x content="config/TRACKER_NAME" i18n:name="tracker" +/></tal:block> +<tal:block condition="not:context/id" i18n:translate="" + >New Issue - <span tal:replace="config/TRACKER_NAME" i18n:name="tracker" +/></tal:block> + + + New Issue + New Issue Editing + Issue + Issue Editing + + + + +

+ You are not allowed to view this page.

+ +

+ Please login with your username and password.

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Titletitle
PrioritypriorityStatusstatus
Superseder + + + +
View: + +
+
Nosy List + +
+
Assigned Toassignedto menuKeywords + + +
Change Note + +
File
+   + + + + submit button + Make a copy +
+
+ + + + + + + + +
Note: highlighted fields are required.
+
+ +

+ Created on + by , + last changed + by . +

+ + + + + + + + + + + + + + + + +
Files
File nameUploadedTypeEditRemove
+ dld link + + creator's name, + creation date + + edit + +
+ + + +
+
+ + + + + + + + + + + + + + +
Messages
msg (view)Author: Date: +
+ + + +
+
+
content
+
+ + + +
+ + + +
diff --git a/share/roundup/templates/classic/html/issue.search.html b/share/roundup/templates/classic/html/issue.search.html new file mode 100644 index 0000000..cff5122 --- /dev/null +++ b/share/roundup/templates/classic/html/issue.search.html @@ -0,0 +1,234 @@ + +Issue searching - <span + i18n:name="tracker" tal:replace="config/TRACKER_NAME" /> +Issue searching + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 Filter onDisplaySort onGroup on
All text*:   
Title: 
Keyword: + +
ID: 
Creation Date:
Creator: + +
Activity: 
Actor: + +  
Priority: + +
Status: + + + + +
Assigned to: + + + + +
No Sort or group:  
Pagesize:
Start With:
Sort Descending: +
Group Descending: +
Query name**: + + +
+   + +
  + + *: The "all text" field will look in message bodies and issue titles +
+ + **: If you supply a name, the query will be saved off and available as a + link in the sidebar + +
+ +
+ + +
diff --git a/share/roundup/templates/classic/html/keyword.item.html b/share/roundup/templates/classic/html/keyword.item.html new file mode 100644 index 0000000..cf1e26a --- /dev/null +++ b/share/roundup/templates/classic/html/keyword.item.html @@ -0,0 +1,55 @@ + + +Keyword editing - <span + i18n:name="tracker" tal:replace="config/TRACKER_NAME" /> +Keyword editing + + + + + + + + + + +
Existing Keywords
+ keyword here +
+ To edit an existing keyword (for spelling or typing errors), + click on its entry above. +
+ +

+ To create a new keyword, enter it below and click "Submit New Entry". +

+ +
+ + + + + + + + + + + +
Keywordname
+   + + + + submit button will go here +
+
+ + +
diff --git a/share/roundup/templates/classic/html/msg.index.html b/share/roundup/templates/classic/html/msg.index.html new file mode 100644 index 0000000..02405dc --- /dev/null +++ b/share/roundup/templates/classic/html/msg.index.html @@ -0,0 +1,25 @@ + +List of messages - <span tal:replace="config/TRACKER_NAME" + i18n:name="tracker"/> +Message listing + + + + + + + + + + + + + + + +
Messages
authordate
content
+ + +
diff --git a/share/roundup/templates/classic/html/msg.item.html b/share/roundup/templates/classic/html/msg.item.html new file mode 100644 index 0000000..e755174 --- /dev/null +++ b/share/roundup/templates/classic/html/msg.item.html @@ -0,0 +1,83 @@ + + + +<tal:block condition="context/id" i18n:translate="" + >Message <span tal:replace="context/id" i18n:name="id" + /> - <span tal:replace="config/TRACKER_NAME" i18n:name="tracker" +/></tal:block> +<tal:block condition="not:context/id" i18n:translate="" + >New Message - <span tal:replace="config/TRACKER_NAME" i18n:name="tracker" +/></tal:block> + + + New Message + New Message Editing + Message + Message Editing + + + +

+ You are not allowed to view this page.

+ +

+ Please login with your username and password.

+ +
+ + + + + + + + + + + + + + + + +
Author
Recipients
Date
+ + + + + + +
Content
+ + + + + + + + + + + +
Files
File nameUploaded
+ dld link + + creator's name, + creation date +
+ + + +
+ + +
diff --git a/share/roundup/templates/classic/html/page.html b/share/roundup/templates/classic/html/page.html new file mode 100644 index 0000000..cd64875 --- /dev/null +++ b/share/roundup/templates/classic/html/page.html @@ -0,0 +1,347 @@ + + + +title goes here + + + + + + + + + + + + + + + + + + + + + + + +
  +
+

body title

+
+ +
+

+

+ + clear this message +

+
Page content goes here
+ +
+
+ + + +
+ + + + + + + + + + + + + + + + (cal) + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
  • + +
  • +
  • + + +
  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/share/roundup/templates/classic/html/query.edit.html b/share/roundup/templates/classic/html/query.edit.html new file mode 100644 index 0000000..2c586f1 --- /dev/null +++ b/share/roundup/templates/classic/html/query.edit.html @@ -0,0 +1,111 @@ + + +"Your Queries" Editing - <span tal:replace="config/TRACKER_NAME" + i18n:name="tracker" /> +"Your Queries" Editing + + + +You are not allowed to edit queries. + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
QueryInclude in "Your Queries"EditPrivate to you? 
query + + + [query is retired]
query + + edit + + + +
query + + + edit + [not yours to edit]
+ + + +
+ +
+ +
diff --git a/share/roundup/templates/classic/html/query.item.html b/share/roundup/templates/classic/html/query.item.html new file mode 100644 index 0000000..453e13d --- /dev/null +++ b/share/roundup/templates/classic/html/query.item.html @@ -0,0 +1,3 @@ + + + diff --git a/share/roundup/templates/classic/html/style.css b/share/roundup/templates/classic/html/style.css new file mode 100644 index 0000000..72e7ffc --- /dev/null +++ b/share/roundup/templates/classic/html/style.css @@ -0,0 +1,433 @@ +/* main page styles */ +body.body { + font-family: sans-serif, Arial, Helvetica; + background-color: white; + color: #333; + margin: 0; +} +a[href]:hover { + color:blue; + text-decoration: underline; +} +a[href], a[href]:link { + color:blue; + text-decoration: none; +} + +table.body { + border: 0; + padding: 0; + border-spacing: 0; + border-collapse: separate; +} + +td.page-header-left { + padding: 5px; + border-bottom: 1px solid #444; +} +td.sidebar { + padding: 1px 0 0 1px; + white-space: nowrap; +} + +/* don't display the sidebar when printing */ +@media print { + td.page-header-left { + display: none; + } + td.sidebar { + display: none; + } + .index-controls { + display: none; + } + #searchbox { + display: none; + } +} + +td.page-header-top { + padding: 5px; + border-bottom: 1px solid #444; +} +#searchbox { + float: right; +} + +div#body-title { + float: left; +} + + +div#searchbox { + float: right; + padding-top: 1em; +} + +div#searchbox input#search-text { + width: 10em; +} + +form { + margin: 0; +} + +textarea { + font-family: monospace; +} + +td.sidebar p.classblock { + padding: 2px 5px 2px 5px; + margin: 1px; + border: 1px solid #444; + background-color: #eee; +} + +td.sidebar p.userblock { + padding: 2px 5px 2px 5px; + margin: 1px 1px 1px 1px; + border: 1px solid #444; + background-color: #eef; +} + +.form-small { + padding: 0; + font-size: 75%; +} + + +td.content { + padding: 1px 5px 1px 5px; + vertical-align: top; + width: 100%; +} + +td.date, th.date { + white-space: nowrap; +} + +p.ok-message { + background-color: #22bb22; + padding: 5px; + color: white; + font-weight: bold; +} +p.error-message { + background-color: #bb2222; + padding: 5px; + color: white; + font-weight: bold; +} +p.error-message a[href] { + color: white; + text-decoration: underline; +} + + +/* style for search forms */ +ul.search-checkboxes { + display: inline; + padding: 0; + list-style: none; +} +ul.search-checkboxes > li { + display: inline; + padding-right: .5em; +} + + +/* style for forms */ +table.form { + padding: 2px; + border-spacing: 0; + border-collapse: separate; +} + +table.form th { + color: #338; + text-align: right; + vertical-align: top; + font-weight: normal; + white-space: nowrap; +} + +table.form th.header { + font-weight: bold; + background-color: #eef; + text-align: left; +} + +table.form th.required { + font-weight: bold; +} + +table.form td { + color: #333; + empty-cells: show; + vertical-align: top; +} + +table.form td.optional { + font-weight: bold; + font-style: italic; +} + +table.form td.html { + color: #777; +} + +/* style for lists */ +table.list { + border-spacing: 0; + border-collapse: separate; + width: 100%; +} + +table.list th { + padding: 0 4px 0 4px; + color: #404070; + background-color: #eef; + border: 1px solid white; + vertical-align: top; + empty-cells: show; +} +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 4px 0 4px; + border: 1px solid white; + color: #404070; + background-color: #efefef; + vertical-align: top; + empty-cells: show; +} + +table.list tr.navigation th { + width: 33%; + border-style: hidden; + text-align: center; +} +table.list tr.navigation td { + border: none +} +table.list tr.navigation th:first-child { + text-align: left; +} +table.list tr.navigation th:last-child { + text-align: right; +} + + +/* style for message displays */ +table.messages { + border-spacing: 0; + 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; + border-bottom: 1px solid #afafaf; +} + +table.messages td { + font-family: monospace; + background-color: #efefef; + border-bottom: 1px solid #afafaf; + color: black; + empty-cells: show; + border-right: 1px solid #afafaf; + vertical-align: top; + padding: 2px 5px 2px 5px; +} + +table.messages td:first-child { + border-left: 1px solid #afafaf; + border-right: 1px solid #afafaf; +} + +/* style for file displays */ +table.files { + border-spacing: 0; + 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: 0; + 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: 0; + 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 { /* the table-layout: fixed; */ + table-layout: fixed; /* compromises quality for speed */ + overflow: hidden; + font-size: .9em; + padding-bottom: 3em; +} + +table.classhelp th { + font-weight: normal; + text-align: left; + color: #444; + background-color: #efefef; + border-bottom: 1px solid #afafaf; + border-top: 1px solid #afafaf; + text-transform: uppercase; + vertical-align: middle; + line-height:1.5em; +} + +table.classhelp td { + vertical-align: middle; + padding-right: .2em; + border-bottom: 1px solid #efefef; + text-align: left; + empty-cells: show; + white-space: nowrap; + vertical-align: middle; +} + +table.classhelp tr:hover { + background-color: #eee; +} + +label.classhelp-label { + cursor: pointer; +} + +#classhelp-controls { + position: fixed; + display: block; + top: auto; + right: 0; + bottom: 0; + left: 0; + padding: .5em; + border-top: 2px solid #444; + background-color: #eee; +} + +#classhelp-controls input.apply { + width: 7em; + font-weight: bold; + margin-right: 2em; + margin-left: 2em; +} + +#classhelp-controls input.preview { + margin-right: 3em; + margin-left: 1em; +} + +/* style for "other" displays */ +table.otherinfo { + border-spacing: 0; + 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; +} +input[type="text"]:focus, +input[type="checkbox"]:focus, +input[type="radio"]:focus, +input[type="password"]:focus, +textarea:focus, select:focus { + background-color: #ffffc0; +} + +/* vim: sts=2 sw=2 et +*/ diff --git a/share/roundup/templates/classic/html/user.forgotten.html b/share/roundup/templates/classic/html/user.forgotten.html new file mode 100644 index 0000000..3f0a472 --- /dev/null +++ b/share/roundup/templates/classic/html/user.forgotten.html @@ -0,0 +1,43 @@ + + +Password reset request - <span + i18n:name="tracker" tal:replace="config/TRACKER_NAME" /> +Password reset request + + +

You have two options if you have forgotten your password. +If you know the email address you registered with, enter it below.

+ +
+ + + + + + + + + +
Email Address:
  + + + +
+ +

Or, if you know your username, then enter it below.

+ + + + +
Username:
+
+ +

A confirmation email will be sent to you - +please follow the instructions within it to complete the reset process.

+ + +
diff --git a/share/roundup/templates/classic/html/user.help-search.html b/share/roundup/templates/classic/html/user.help-search.html new file mode 100644 index 0000000..8436897 --- /dev/null +++ b/share/roundup/templates/classic/html/user.help-search.html @@ -0,0 +1,85 @@ + + + Search input for user helper + + + + + +
+    
+ + + + + + + + + + + + + + + + + + + + + + + + +
Name
Phone
role + +
  + + + + + + +
+ +
+
+
+  
+
diff --git a/share/roundup/templates/classic/html/user.help.html b/share/roundup/templates/classic/html/user.help.html
new file mode 100644
index 0000000..b338c2b
--- /dev/null
+++ b/share/roundup/templates/classic/html/user.help.html
@@ -0,0 +1,49 @@
+
+
+  
+      
+      
+      
+      <tal:x i18n:translate=""><tal:x i18n:name="property"
+       tal:content="property" i18n:translate="" /> help - <span i18n:name="tracker"
+	       tal:replace="config/TRACKER_NAME" /></tal:x>
+      
+      
+      
+  
+
+  
+  
+  
+  
+  
+
+
+  <body>
+<p i18n:translate="">
+Your browser is not capable of using frames; you should be redirected immediately,
+or visit <a href="#" tal:attributes="href string:?${qs}&template=help-noframes"
+i18n:name="link">this link</a>.
+</p>
+</body>
+
+
+
diff --git a/share/roundup/templates/classic/html/user.index.html b/share/roundup/templates/classic/html/user.index.html
new file mode 100644
index 0000000..021e2b8
--- /dev/null
+++ b/share/roundup/templates/classic/html/user.index.html
@@ -0,0 +1,45 @@
+
+
+User listing - <span
+ i18n:name="tracker" tal:replace="config/TRACKER_NAME" />
+User listing
+
+
+You are not allowed to view this page.
+
+Please login with your username and password.
+
+
+
+ 
+ 
+ 
+ 
+ 
+ 
+
+
+
+ 
+ 
+ 
+ 
+ 
+ 
+
+
+
UsernameReal nameOrganisationEmail addressPhone numberRetire
+ username +      + retire +
+ + +
diff --git a/share/roundup/templates/classic/html/user.item.html b/share/roundup/templates/classic/html/user.item.html new file mode 100644 index 0000000..bafccd2 --- /dev/null +++ b/share/roundup/templates/classic/html/user.item.html @@ -0,0 +1,169 @@ + + + +<tal:if condition="context/id" i18n:translate="" + >User <tal:x content="context/id" i18n:name="id" + />: <tal:x content="context/username" i18n:name="title" + /> - <tal:x content="config/TRACKER_NAME" i18n:name="tracker" +/></tal:if> +<tal:if condition="not:context/id" i18n:translate="" + >New User - <span tal:replace="config/TRACKER_NAME" i18n:name="tracker" +/></tal:if> + + + + + + + New User + New User Editing + User + User Editing + + + + +

+ You are not allowed to view this page.

+ +

+ Please login with your username and password.

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Name
Login Name
Login Password
Confirm Password
+ + + + + + + (to give the user more than one role, + enter a comma,separated,list) +
Phone
Organisation
Timezone + (this is a numeric hour offset, the default is + ) +
E-mail address + calvin@the-z.org + + + +   +
+ +
+   + + + + +
+
+ + + + + + + + +
Note: highlighted fields are required.
+
+ + + +
+ + + +
diff --git a/share/roundup/templates/classic/html/user.register.html b/share/roundup/templates/classic/html/user.register.html new file mode 100644 index 0000000..b7b1749 --- /dev/null +++ b/share/roundup/templates/classic/html/user.register.html @@ -0,0 +1,81 @@ + + +Registering with <span i18n:name="tracker" + tal:replace="db/config/TRACKER_NAME" /> +Registering with + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Namerealname
Login Nameusername
Login Passwordpassword
Confirm Passwordpassword
Rolesroles + +
Phonephone
Organisationorganisation
E-mail addressaddress
Alternate E-mail addresses
One address per line
alternate_addresses
  + + + + +
+
+ + + + + + + + +
Note: highlighted fields are required.
+
+ + + +
diff --git a/share/roundup/templates/classic/html/user.rego_progress.html b/share/roundup/templates/classic/html/user.rego_progress.html new file mode 100644 index 0000000..4d6bfe4 --- /dev/null +++ b/share/roundup/templates/classic/html/user.rego_progress.html @@ -0,0 +1,16 @@ + + +Registration in progress - <span i18n:name="tracker" + tal:replace="config/TRACKER_NAME" /> +Registration in progress... + + +

You will shortly receive an email +to confirm your registration. To complete the registration process, +visit the link indicated in the email. +

+ + +
diff --git a/share/roundup/templates/classic/html/user_utils.js b/share/roundup/templates/classic/html/user_utils.js new file mode 100644 index 0000000..7b2946d --- /dev/null +++ b/share/roundup/templates/classic/html/user_utils.js @@ -0,0 +1,114 @@ +// User Editing Utilities + +/** + * for new users: + * Depending on the input field which calls it, takes the value + * and dispatches it to certain other input fields: + * + * address + * +-> username + * | `-> realname + * `-> organisation + */ +function split_name(that) { + var raw = that.value + var val = trim(raw) + if (val == '') { + return + } + var username='' + var realname='' + var address='' + switch (that.name) { + case 'address': + address=val + break + case 'username': + username=val + break + case 'realname': + realname=val + break + case 'firstname': + case 'lastname': + return + default: + alert('Ooops - unknown name field '+that.name+'!') + return + } + var the_form = that.form; + + function field_empty(name) { + return the_form[name].value == '' + } + + // no break statements - on purpose! + switch (that.name) { + case 'address': + var split1 = address.split('@') + if (field_empty('username')) { + username = split1[0] + the_form.username.value = username + } + if (field_empty('organisation')) { + the_form.organisation.value = default_organisation(split1[1]) + } + case 'username': + if (field_empty('realname')) { + realname = Cap(username.split('.').join(' ')) + the_form.realname.value = realname + } + case 'realname': + if (field_empty('username')) { + username = Cap(realname.replace(' ', '.')) + the_form.username.value = username + } + if (the_form.firstname && the_form.lastname) { + var split2 = realname.split(' ') + var firstname='', lastname='' + firstname = split2[0] + lastname = split2.slice(1).join(' ') + if (field_empty('firstname')) { + the_form.firstname.value = firstname + } + if (field_empty('lastname')) { + the_form.lastname.value = lastname + } + } + } +} + +function SubCap(str) { + switch (str) { + case 'de': case 'do': case 'da': + case 'du': case 'von': + return str; + } + if (str.toLowerCase().slice(0,2) == 'mc') { + return 'Mc'+str.slice(2,3).toUpperCase()+str.slice(3).toLowerCase() + } + return str.slice(0,1).toUpperCase()+str.slice(1).toLowerCase() +} + +function Cap(str) { + var liz = str.split(' ') + for (var i=0; i/db/files/] +# type = String() [MIME type of the content, default 'text/plain'] +msg = FileClass(db, "msg", + author=Link("user", do_journal='no'), + recipients=Multilink("user", do_journal='no'), + date=Date(), + summary=String(), + files=Multilink("file"), + messageid=String(), + inreplyto=String()) + +file = FileClass(db, "file", + name=String()) + +# IssueClass automatically gets these properties in addition to the Class ones: +# title = String() +# messages = Multilink("msg") +# files = Multilink("file") +# nosy = Multilink("user") +# superseder = Multilink("issue") +issue = IssueClass(db, "issue", + assignedto=Link("user"), + keyword=Multilink("keyword"), + priority=Link("priority"), + status=Link("status")) + +# +# TRACKER SECURITY SETTINGS +# +# See the configuration and customisation document for information +# about security setup. + +# +# REGULAR USERS +# +# Give the regular users access to the web and email interface +db.security.addPermissionToRole('User', 'Web Access') +db.security.addPermissionToRole('User', 'Email Access') + +# Assign the access and edit Permissions for issue, file and message +# to regular users now +for cl in 'issue', 'file', 'msg', 'keyword': + db.security.addPermissionToRole('User', 'View', cl) + db.security.addPermissionToRole('User', 'Edit', cl) + db.security.addPermissionToRole('User', 'Create', cl) +for cl in 'priority', 'status': + db.security.addPermissionToRole('User', 'View', cl) + +# May users view other user information? Comment these lines out +# if you don't want them to +db.security.addPermissionToRole('User', 'View', 'user') + +# Users should be able to edit their own details -- this permission is +# limited to only the situation where the Viewed or Edited item is their own. +def own_record(db, userid, itemid): + '''Determine whether the userid matches the item being accessed.''' + return userid == itemid +p = db.security.addPermission(name='View', klass='user', check=own_record, + description="User is allowed to view their own user details") +db.security.addPermissionToRole('User', p) +p = db.security.addPermission(name='Edit', klass='user', check=own_record, + description="User is allowed to edit their own user details") +db.security.addPermissionToRole('User', p) + +# Users should be able to edit and view their own queries. They should also +# be able to view any marked as not private. They should not be able to +# edit others' queries, even if they're not private +def view_query(db, userid, itemid): + private_for = db.query.get(itemid, 'private_for') + if not private_for: return True + return userid == private_for +def edit_query(db, userid, itemid): + return userid == db.query.get(itemid, 'creator') +p = db.security.addPermission(name='View', klass='query', check=view_query, + description="User is allowed to view their own and public queries") +db.security.addPermissionToRole('User', p) +p = db.security.addPermission(name='Edit', klass='query', check=edit_query, + description="User is allowed to edit their queries") +db.security.addPermissionToRole('User', p) +p = db.security.addPermission(name='Create', klass='query', + description="User is allowed to create queries") +db.security.addPermissionToRole('User', p) + + +# +# ANONYMOUS USER PERMISSIONS +# +# Let anonymous users access the web interface. Note that almost all +# trackers will need this Permission. The only situation where it's not +# required is in a tracker that uses an HTTP Basic Authenticated front-end. +db.security.addPermissionToRole('Anonymous', 'Web Access') + +# Let anonymous users access the email interface (note that this implies +# that they will be registered automatically, hence they will need the +# "Create" user Permission below) +# This is disabled by default to stop spam from auto-registering users on +# public trackers. +#db.security.addPermissionToRole('Anonymous', 'Email Access') + +# Assign the appropriate permissions to the anonymous user's Anonymous +# Role. Choices here are: +# - Allow anonymous users to register +db.security.addPermissionToRole('Anonymous', 'Create', 'user') + +# Allow anonymous users access to view issues (and the related, linked +# information) +for cl in 'issue', 'file', 'msg', 'keyword', 'priority', 'status': + db.security.addPermissionToRole('Anonymous', 'View', cl) + +# [OPTIONAL] +# Allow anonymous users access to create or edit "issue" items (and the +# related file and message items) +#for cl in 'issue', 'file', 'msg': +# db.security.addPermissionToRole('Anonymous', 'Create', cl) +# db.security.addPermissionToRole('Anonymous', 'Edit', cl) + + +# vim: set filetype=python sts=4 sw=4 et si : diff --git a/share/roundup/templates/minimal/.cvsignore b/share/roundup/templates/minimal/.cvsignore new file mode 100644 index 0000000..d90d51d --- /dev/null +++ b/share/roundup/templates/minimal/.cvsignore @@ -0,0 +1,4 @@ +*.pyc +*.pyo +htmlbase.py +*.cover diff --git a/share/roundup/templates/minimal/TEMPLATE-INFO.txt b/share/roundup/templates/minimal/TEMPLATE-INFO.txt new file mode 100644 index 0000000..0cb35b5 --- /dev/null +++ b/share/roundup/templates/minimal/TEMPLATE-INFO.txt @@ -0,0 +1,8 @@ +Name: minimal +Description: This is an empty tracker - it must be customised for it to be + useful! It only defines the bare minimum of information - the + user database and the two default users (admin and anonymous). + The rest is entirely up to you! Not recommended for first-time + Roundup users (it's easier to tweak the Classic tracker). +Intended-For: Roundup experts who need a clean slate to start with. + diff --git a/share/roundup/templates/minimal/detectors/.cvsignore b/share/roundup/templates/minimal/detectors/.cvsignore new file mode 100644 index 0000000..4162d5e --- /dev/null +++ b/share/roundup/templates/minimal/detectors/.cvsignore @@ -0,0 +1,3 @@ +*.pyc +*.pyo +*.cover diff --git a/share/roundup/templates/minimal/detectors/userauditor.py b/share/roundup/templates/minimal/detectors/userauditor.py new file mode 100644 index 0000000..dd7fcc4 --- /dev/null +++ b/share/roundup/templates/minimal/detectors/userauditor.py @@ -0,0 +1,94 @@ +# Copyright (c) 2003 Richard Jones (richard@mechanicalcat.net) +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +#$Id: userauditor.py,v 1.8 2007-09-12 21:11:14 jpend Exp $ + +import re + +# regular expression thanks to: http://www.regular-expressions.info/email.html +# this is the "99.99% solution for syntax only". +email_regexp = (r"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*", r"(localhost|(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9]))") +email_rfc = re.compile('^' + email_regexp[0] + '@' + email_regexp[1] + '$', re.IGNORECASE) +email_local = re.compile('^' + email_regexp[0] + '$', re.IGNORECASE) + +def valid_address(address): + ''' If we see an @-symbol in the address then check against the full + RFC syntax. Otherwise it is a local-only address so only check + the local part of the RFC syntax. + ''' + if '@' in address: + return email_rfc.match(address) + else: + return email_local.match(address) + +def get_addresses(user): + ''' iterate over all known addresses in a newvalues dict + this takes of the address/alterate_addresses handling + ''' + if user.has_key('address'): + yield user['address'] + if user.get('alternate_addresses', None): + for address in user['alternate_addresses'].split('\n'): + yield address + +def audit_user_fields(db, cl, nodeid, newvalues): + ''' Make sure user properties are valid. + + - email address is syntactically valid + - email address is unique + - roles specified exist + - timezone is valid + ''' + + for address in get_addresses(newvalues): + if not valid_address(address): + raise ValueError, 'Email address syntax is invalid' + + check_main = db.user.stringFind(address=address) + # make sure none of the alts are owned by anyone other than us (x!=nodeid) + check_alts = [x for x in db.user.filter(None, {'alternate_addresses' : address}) if x != nodeid] + if check_main or check_alts: + raise ValueError, 'Email address %s already in use' % address + + for rolename in [r.lower().strip() for r in newvalues.get('roles', '').split(',')]: + if rolename and not db.security.role.has_key(rolename): + raise ValueError, 'Role "%s" does not exist'%rolename + + tz = newvalues.get('timezone', None) + if tz: + # if they set a new timezone validate the timezone by attempting to + # use it before we store it to the db. + import roundup.date + import datetime + try: + TZ = roundup.date.get_timezone(tz) + dt = datetime.datetime.now() + local = TZ.localize(dt).utctimetuple() + except IOError: + raise ValueError, 'Timezone "%s" does not exist' % tz + except ValueError: + raise ValueError, 'Timezone "%s" exceeds valid range [-23...23]' % tz + +def init(db): + # fire before changes are made + db.user.audit('set', audit_user_fields) + db.user.audit('create', audit_user_fields) + +# vim: sts=4 sw=4 et si diff --git a/share/roundup/templates/minimal/extensions/README.txt b/share/roundup/templates/minimal/extensions/README.txt new file mode 100644 index 0000000..ff4dff3 --- /dev/null +++ b/share/roundup/templates/minimal/extensions/README.txt @@ -0,0 +1,6 @@ +This directory is for tracker extensions: + +- CGI Actions +- Templating functions + +See the customisation doc for more information. diff --git a/share/roundup/templates/minimal/html/_generic.404.html b/share/roundup/templates/minimal/html/_generic.404.html new file mode 100644 index 0000000..71c9e0e --- /dev/null +++ b/share/roundup/templates/minimal/html/_generic.404.html @@ -0,0 +1,9 @@ + + +Item Not Found + + + +There is no with id + + diff --git a/share/roundup/templates/minimal/html/_generic.calendar.html b/share/roundup/templates/minimal/html/_generic.calendar.html new file mode 100644 index 0000000..dbc3b57 --- /dev/null +++ b/share/roundup/templates/minimal/html/_generic.calendar.html @@ -0,0 +1,18 @@ + + + + + + + + + + + diff --git a/share/roundup/templates/minimal/html/_generic.collision.html b/share/roundup/templates/minimal/html/_generic.collision.html new file mode 100644 index 0000000..2a2768a --- /dev/null +++ b/share/roundup/templates/minimal/html/_generic.collision.html @@ -0,0 +1,16 @@ + +<span tal:replace="python:context._classname.capitalize()" + i18n:name="class" /> Edit Collision - <span i18n:name="tracker" + tal:replace="config/TRACKER_NAME" /> + Edit Collision + + + + diff --git a/share/roundup/templates/minimal/html/_generic.help.html b/share/roundup/templates/minimal/html/_generic.help.html new file mode 100644 index 0000000..069c0a6 --- /dev/null +++ b/share/roundup/templates/minimal/html/_generic.help.html @@ -0,0 +1,98 @@ + + + + + + + <tal:x i18n:name="property" + tal:content="property" i18n:translate="" /> help - <span i18n:name="tracker" + tal:replace="config/TRACKER_NAME" /> + + + + + +
+ +
+ + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + +
 x
+ + + +
 x
+ +
+ + diff --git a/share/roundup/templates/minimal/html/_generic.index.html b/share/roundup/templates/minimal/html/_generic.index.html new file mode 100644 index 0000000..81918ef --- /dev/null +++ b/share/roundup/templates/minimal/html/_generic.index.html @@ -0,0 +1,70 @@ + + + +<span tal:replace="python:context._classname.capitalize()" + i18n:name="class" /> editing - <span i18n:name="tracker" + tal:replace="config/TRACKER_NAME" /> + editing + + + +You are not allowed to view this page. + +Please login with your username and password. + + + +

+ You may edit the contents of the + + 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 (""). +

+ +

+ Multilink properties have their multiple values colon (":") separated + (... ,"one:two:three", ...) +

+ +

+ Remove entries by deleting their line. Add new entries by appending + them to the table - put an X in the id column. +

+
+
+ +
+ + +
+
+ + + + + + + + + + +
 
 
+ + + +
diff --git a/share/roundup/templates/minimal/html/_generic.item.html b/share/roundup/templates/minimal/html/_generic.item.html new file mode 100644 index 0000000..ac60acb --- /dev/null +++ b/share/roundup/templates/minimal/html/_generic.item.html @@ -0,0 +1,65 @@ + +<span tal:replace="python:context._classname.capitalize()" + i18n:name="class" /> editing - <span i18n:name="tracker" + tal:replace="config/TRACKER_NAME" /> + editing + + + +You are not allowed to view this page. + +Please login with your username and password. + +
+ + + + + + + + + + + + + + + +
  + submit button will go here +
+ +
+ + + + + + + + + +
+ + + + + + + + + diff --git a/share/roundup/templates/minimal/html/help_controls.js b/share/roundup/templates/minimal/html/help_controls.js new file mode 100644 index 0000000..d3b5529 --- /dev/null +++ b/share/roundup/templates/minimal/html/help_controls.js @@ -0,0 +1,111 @@ +// initial values for either Nosy, Superseder, Keyword and Waiting On, +// depending on which has called +original_field = form[field].value; + +// Some browsers (ok, IE) don't define the "undefined" variable. +undefined = document.geez_IE_is_really_friggin_annoying; + +function trim(value) { + var temp = value; + var obj = /^(\s*)([\W\w]*)(\b\s*$)/; + if (obj.test(temp)) { temp = temp.replace(obj, '$2'); } + var obj = / /g; + while (temp.match(obj)) { temp = temp.replace(obj, " "); } + return temp; +} + +function determineList() { + // generate a comma-separated list of the checked items + var list = new String(''); + for (box=0; box < document.frm_help.check.length; box++) { + if (document.frm_help.check[box].checked) { + if (list.length == 0) { + separator = ''; + } + else { + separator = ','; + } + // we used to use an Array and push / join, but IE5.0 sux + list = list + separator + document.frm_help.check[box].value; + } + } + return list; +} + +function updateList() { + // write back to opener window + if (document.frm_help.check==undefined) { return; } + form[field].value = determineList(); +} + +function updatePreview() { + // update the preview box + if (document.frm_help.check==undefined) { return; } + writePreview(determineList()); +} + +function clearList() { + // uncheck all checkboxes + if (document.frm_help.check==undefined) { return; } + for (box=0; box < document.frm_help.check.length; box++) { + document.frm_help.check[box].checked = false; + } +} + +function reviseList(vals) { + // update the checkboxes based on the preview field + if (document.frm_help.check==undefined) { return; } + var to_check; + var list = vals.split(","); + if (document.frm_help.check.length==undefined) { + check = document.frm_help.check; + to_check = false; + for (val in list) { + if (check.value==trim(list[val])) { + to_check = true; + break; + } + } + check.checked = to_check; + } else { + for (box=0; box < document.frm_help.check.length; box++) { + check = document.frm_help.check[box]; + to_check = false; + for (val in list) { + if (check.value==trim(list[val])) { + to_check = true; + break; + } + } + check.checked = to_check; + } + } +} + +function resetList() { + // reset preview and check boxes to initial values + if (document.frm_help.check==undefined) { return; } + writePreview(original_field); + reviseList(original_field); +} + +function writePreview(val) { + // writes a value to the text_preview + document.frm_help.text_preview.value = val; +} + +function focusField(name) { + for(i=0; i < document.forms.length; ++i) { + var obj = document.forms[i].elements[name]; + if (obj && obj.focus) {obj.focus();} + } +} + +function selectField(name) { + for(i=0; i < document.forms.length; ++i) { + var obj = document.forms[i].elements[name]; + if (obj && obj.focus){obj.focus();} + if (obj && obj.select){obj.select();} + } +} + diff --git a/share/roundup/templates/minimal/html/home.classlist.html b/share/roundup/templates/minimal/html/home.classlist.html new file mode 100644 index 0000000..930306b --- /dev/null +++ b/share/roundup/templates/minimal/html/home.classlist.html @@ -0,0 +1,25 @@ + +List of classes - <span + i18n:name="tracker" tal:replace="config/TRACKER_NAME" /> +List of classes + + + + + + + + + + + + + +
+ classname +
nametype
+ + +
diff --git a/share/roundup/templates/minimal/html/home.html b/share/roundup/templates/minimal/html/home.html new file mode 100644 index 0000000..c933c59 --- /dev/null +++ b/share/roundup/templates/minimal/html/home.html @@ -0,0 +1,25 @@ + +Tracker home - <span + i18n:name="tracker" tal:replace="config/TRACKER_NAME" /> +Tracker home + + + + + +

+Please select from one of the menu options on the left. +

+

+Please log in or register. +

+
+ + +
diff --git a/share/roundup/templates/minimal/html/page.html b/share/roundup/templates/minimal/html/page.html new file mode 100644 index 0000000..dbbbb5e --- /dev/null +++ b/share/roundup/templates/minimal/html/page.html @@ -0,0 +1,334 @@ + + + +title goes here + + + + + + + + + + + + + + + + + + + + + + + +
  +
+

body title

+
+ +
+

+

+ + clear this message +

+
Page content goes here
+ +
+
+ + + +
+ + + + + + + + + + + + + + + + (cal) + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
  • + +
  • +
  • + + +
  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/share/roundup/templates/minimal/html/style.css b/share/roundup/templates/minimal/html/style.css new file mode 100644 index 0000000..f7d7eb4 --- /dev/null +++ b/share/roundup/templates/minimal/html/style.css @@ -0,0 +1,423 @@ +/* main page styles */ +body.body { + font-family: sans-serif, Arial, Helvetica; + background-color: white; + color: #333; + margin: 0; +} +a[href]:hover { + color:blue; + text-decoration: underline; +} +a[href], a[href]:link { + color:blue; + text-decoration: none; +} + +table.body { + border: 0; + padding: 0; + border-spacing: 0; + border-collapse: separate; +} + +td.page-header-left { + padding: 5px; + border-bottom: 1px solid #444; +} +td.sidebar { + padding: 1px 0 0 1px; + white-space: nowrap; +} + +/* don't display the sidebar when printing */ +@media print { + td.page-header-left { + display: none; + } + td.sidebar { + display: none; + } + .index-controls { + display: none; + } + #searchbox { + display: none; + } +} + +td.page-header-top { + padding: 5px; + border-bottom: 1px solid #444; +} +#searchbox { + float: right; +} + +div#body-title { + float: left; +} + + +div#searchbox { + float: right; + padding-top: 1em; +} + +div#searchbox input#search-text { + width: 10em; +} + +form { + margin: 0; +} + +textarea { + font-family: monospace; +} + +td.sidebar p.classblock { + padding: 2px 5px 2px 5px; + margin: 1px; + border: 1px solid #444; + background-color: #eee; +} + +td.sidebar p.userblock { + padding: 2px 5px 2px 5px; + margin: 1px 1px 1px 1px; + border: 1px solid #444; + background-color: #eef; +} + +.form-small { + padding: 0; + font-size: 75%; +} + + +td.content { + padding: 1px 5px 1px 5px; + vertical-align: top; + width: 100%; +} + +td.date, th.date { + white-space: nowrap; +} + +p.ok-message { + background-color: #22bb22; + padding: 5px; + color: white; + font-weight: bold; +} +p.error-message { + background-color: #bb2222; + padding: 5px; + color: white; + font-weight: bold; +} +p.error-message a[href] { + color: white; + text-decoration: underline; +} + + +/* style for search forms */ +ul.search-checkboxes { + display: inline; + padding: none; + list-style: none; +} +ul.search-checkboxes > li { + display: inline; + padding-right: .5em; +} + + +/* style for forms */ +table.form { + padding: 2px; + border-spacing: 0; + border-collapse: separate; +} + +table.form th { + color: #338; + text-align: right; + vertical-align: top; + font-weight: normal; + white-space: nowrap; +} + +table.form th.header { + font-weight: bold; + background-color: #eef; + text-align: left; +} + +table.form th.required { + font-weight: bold; +} + +table.form td { + color: #333; + empty-cells: show; + vertical-align: top; +} + +table.form td.optional { + font-weight: bold; + font-style: italic; +} + +table.form td.html { + color: #777; +} + +/* style for lists */ +table.list { + border-spacing: 0; + border-collapse: separate; + width: 100%; +} + +table.list th { + padding: 0 4px 0 4px; + color: #404070; + background-color: #eef; + border: 1px solid white; + vertical-align: top; + empty-cells: show; +} +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 4px 0 4px; + border: 1px solid white; + color: #404070; + background-color: #efefef; + vertical-align: top; + empty-cells: show; +} + +table.list tr.navigation th { + width: 33%; + border-style: hidden; + text-align: center; +} +table.list tr.navigation td { + border: none +} +table.list tr.navigation th:first-child { + text-align: left; +} +table.list tr.navigation th:last-child { + text-align: right; +} + + +/* style for message displays */ +table.messages { + border-spacing: 0; + 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; + border-bottom: 1px solid #afafaf; +} + +table.messages td { + font-family: monospace; + background-color: #efefef; + border-bottom: 1px solid #afafaf; + color: black; + empty-cells: show; + border-right: 1px solid #afafaf; + vertical-align: top; + padding: 2px 5px 2px 5px; +} + +table.messages td:first-child { + border-left: 1px solid #afafaf; + border-right: 1px solid #afafaf; +} + +/* style for file displays */ +table.files { + border-spacing: 0; + 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: 0; + 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: 0; + 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 { /* the table-layout: fixed; */ + table-layout: fixed; /* compromises quality for speed */ + overflow: hidden; + font-size: .9em; + padding-bottom: 3em; +} + +table.classhelp th { + font-weight: normal; + text-align: left; + color: #444; + background-color: #efefef; + border-bottom: 1px solid #afafaf; + border-top: 1px solid #afafaf; + text-transform: uppercase; + vertical-align: middle; + line-height:1.5em; +} + +table.classhelp td { + vertical-align: middle; + padding-right: .2em; + border-bottom: 1px solid #efefef; + text-align: left; + empty-cells: show; + white-space: nowrap; + vertical-align: middle; +} + +table.classhelp tr:hover { + background-color: #eee; +} + +label.classhelp-label { + cursor: pointer; +} + +#classhelp-controls { + position: fixed; + display: block; + top: auto; + right: 0; + bottom: 0; + left: 0; + padding: .5em; + border-top: 2px solid #444; + background-color: #eee; +} + +#classhelp-controls input.apply { + width: 7em; + font-weight: bold; + margin-right: 2em; + margin-left: 2em; +} + +#classhelp-controls input.preview { + margin-right: 3em; + margin-left: 1em; +} + +/* style for "other" displays */ +table.otherinfo { + border-spacing: 0; + 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/share/roundup/templates/minimal/html/user.index.html b/share/roundup/templates/minimal/html/user.index.html new file mode 100644 index 0000000..f0a84b8 --- /dev/null +++ b/share/roundup/templates/minimal/html/user.index.html @@ -0,0 +1,35 @@ + + +User listing - <span + i18n:name="tracker" tal:replace="config/TRACKER_NAME" /> +User listing + + +You are not allowed to view this page. + +Please login with your username and password. + + + + + + + + + + + + +
UsernameEmail address
+ username + address
+ + +
diff --git a/share/roundup/templates/minimal/html/user.item.html b/share/roundup/templates/minimal/html/user.item.html new file mode 100644 index 0000000..bafccd2 --- /dev/null +++ b/share/roundup/templates/minimal/html/user.item.html @@ -0,0 +1,169 @@ + + + +<tal:if condition="context/id" i18n:translate="" + >User <tal:x content="context/id" i18n:name="id" + />: <tal:x content="context/username" i18n:name="title" + /> - <tal:x content="config/TRACKER_NAME" i18n:name="tracker" +/></tal:if> +<tal:if condition="not:context/id" i18n:translate="" + >New User - <span tal:replace="config/TRACKER_NAME" i18n:name="tracker" +/></tal:if> + + + + + + + New User + New User Editing + User + User Editing + + + + +

+ You are not allowed to view this page.

+ +

+ Please login with your username and password.

+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Name
Login Name
Login Password
Confirm Password
+ + + + + + + (to give the user more than one role, + enter a comma,separated,list) +
Phone
Organisation
Timezone + (this is a numeric hour offset, the default is + ) +
E-mail address + calvin@the-z.org + + + +   +
+ +
+   + + + + +
+
+ + + + + + + + +
Note: highlighted fields are required.
+
+ + + +
+ + + +
diff --git a/share/roundup/templates/minimal/html/user.register.html b/share/roundup/templates/minimal/html/user.register.html new file mode 100644 index 0000000..7e7a5d3 --- /dev/null +++ b/share/roundup/templates/minimal/html/user.register.html @@ -0,0 +1,73 @@ + + +Registering with <span i18n:name="tracker" + tal:replace="db/config/TRACKER_NAME" /> +Registering with + + + + +You are not allowed to view this page. + +Please login with your username and password. + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Login Nameusername
Login Passwordpassword
Confirm Passwordpassword
Rolesroles + +
E-mail addressaddress
Alternate E-mail addresses
One address per line
alternate_addresses
  + + +
+
+ +
+ +
+ + + +
diff --git a/share/roundup/templates/minimal/html/user.rego_progress.html b/share/roundup/templates/minimal/html/user.rego_progress.html new file mode 100644 index 0000000..4d6bfe4 --- /dev/null +++ b/share/roundup/templates/minimal/html/user.rego_progress.html @@ -0,0 +1,16 @@ + + +Registration in progress - <span i18n:name="tracker" + tal:replace="config/TRACKER_NAME" /> +Registration in progress... + + +

You will shortly receive an email +to confirm your registration. To complete the registration process, +visit the link indicated in the email. +

+ + +
diff --git a/share/roundup/templates/minimal/initial_data.py b/share/roundup/templates/minimal/initial_data.py new file mode 100644 index 0000000..28bfefe --- /dev/null +++ b/share/roundup/templates/minimal/initial_data.py @@ -0,0 +1,14 @@ +# +# TRACKER DATABASE INITIALIZATION +# + +# create the two default users +user = db.getclass('user') +user.create(username="admin", password=adminpw, + address=admin_email, roles='Admin') +user.create(username="anonymous", roles='Anonymous') + +# add any additional database creation steps here - but only if you +# haven't initialised the database with the admin "initialise" command + +# vim: set et sts=4 sw=4 : diff --git a/share/roundup/templates/minimal/schema.py b/share/roundup/templates/minimal/schema.py new file mode 100644 index 0000000..909c9b1 --- /dev/null +++ b/share/roundup/templates/minimal/schema.py @@ -0,0 +1,65 @@ +# +# TRACKER SCHEMA +# + +# Class automatically gets these properties: +# creation = Date() +# activity = Date() +# creator = Link('user') +# actor = Link('user') + +# 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") +# +# TRACKER SECURITY SETTINGS +# +# See the configuration and customisation document for information +# about security setup. + +# +# REGULAR USERS +# +# Give the regular users access to the web and email interface +db.security.addPermissionToRole('User', 'Web Access') +db.security.addPermissionToRole('User', 'Email Access') + +# May users view other user information? +# Comment these lines out if you don't want them to +db.security.addPermissionToRole('User', 'View', 'user') + +# Users should be able to edit their own details -- this permission is +# limited to only the situation where the Viewed or Edited item is their own. +def own_record(db, userid, itemid): + '''Determine whether the userid matches the item being accessed.''' + return userid == itemid +p = db.security.addPermission(name='View', klass='user', check=own_record, + description="User is allowed to view their own user details") +db.security.addPermissionToRole('User', p) +p = db.security.addPermission(name='Edit', klass='user', check=own_record, + description="User is allowed to edit their own user details") +db.security.addPermissionToRole('User', p) + +# +# ANONYMOUS USER PERMISSIONS +# +# Let anonymous users access the web interface. Note that almost all +# trackers will need this Permission. The only situation where it's not +# required is in a tracker that uses an HTTP Basic Authenticated front-end. +db.security.addPermissionToRole('Anonymous', 'Web Access') + +# Let anonymous users access the email interface (note that this implies +# that they will be registered automatically, hence they will need the +# "Create" user Permission below) +db.security.addPermissionToRole('Anonymous', 'Email Access') + +# Assign the appropriate permissions to the anonymous user's +# Anonymous Role. Choices here are: +# - Allow anonymous users to register +db.security.addPermissionToRole('Anonymous', 'Create', 'user') + +# vim: set et sts=4 sw=4 : diff --git a/templates/classic/.cvsignore b/templates/classic/.cvsignore deleted file mode 100644 index d90d51d..0000000 --- a/templates/classic/.cvsignore +++ /dev/null @@ -1,4 +0,0 @@ -*.pyc -*.pyo -htmlbase.py -*.cover diff --git a/templates/classic/TEMPLATE-INFO.txt b/templates/classic/TEMPLATE-INFO.txt deleted file mode 100644 index 1c20d54..0000000 --- a/templates/classic/TEMPLATE-INFO.txt +++ /dev/null @@ -1,7 +0,0 @@ -Name: classic -Description: This is a generic issue tracker that may be used to track bugs, - feature requests, project issues or any number of other types - of issues. Most users of Roundup will find that this template - suits them, with perhaps a few customisations. -Intended-For: All first-time Roundup users - diff --git a/templates/classic/detectors/.cvsignore b/templates/classic/detectors/.cvsignore deleted file mode 100644 index 4162d5e..0000000 --- a/templates/classic/detectors/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -*.pyc -*.pyo -*.cover diff --git a/templates/classic/detectors/messagesummary.py b/templates/classic/detectors/messagesummary.py deleted file mode 100644 index def2e82..0000000 --- a/templates/classic/detectors/messagesummary.py +++ /dev/null @@ -1,19 +0,0 @@ -#$Id: messagesummary.py,v 1.2 2007-04-03 06:47:21 a1s Exp $ - -from roundup.mailgw import parseContent - -def summarygenerator(db, cl, nodeid, newvalues): - ''' If the message doesn't have a summary, make one for it. - ''' - if newvalues.has_key('summary') or not newvalues.has_key('content'): - return - - summary, content = parseContent(newvalues['content'], config=db.config) - newvalues['summary'] = summary - - -def init(db): - # fire before changes are made - db.msg.audit('create', summarygenerator) - -# vim: set filetype=python ts=4 sw=4 et si diff --git a/templates/classic/detectors/nosyreaction.py b/templates/classic/detectors/nosyreaction.py deleted file mode 100644 index c732fd0..0000000 --- a/templates/classic/detectors/nosyreaction.py +++ /dev/null @@ -1,143 +0,0 @@ -# -# 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: nosyreaction.py,v 1.4 2005-04-04 08:47:14 richard Exp $ - -import sets - -from roundup import roundupdb, hyperdb - -def nosyreaction(db, cl, nodeid, oldvalues): - ''' A standard detector is provided that watches for additions to the - "messages" property. - - When a new message is added, the detector sends it to all the users on - the "nosy" list for the issue that are not already on the "recipients" - list of the message. - - Those users are then appended to the "recipients" property on the - message, so multiple copies of a message are never sent to the same - user. - - The journal recorded by the hyperdatabase on the "recipients" property - then provides a log of when the message was sent to whom. - ''' - # send a copy of all new messages to the nosy list - for msgid in determineNewMessages(cl, nodeid, oldvalues): - try: - cl.nosymessage(nodeid, msgid, oldvalues) - except roundupdb.MessageSendError, message: - raise roundupdb.DetectorError, message - -def determineNewMessages(cl, nodeid, oldvalues): - ''' Figure a list of the messages that are being added to the given - node in this transaction. - ''' - messages = [] - if oldvalues is None: - # the action was a create, so use all the messages in the create - messages = cl.get(nodeid, 'messages') - elif oldvalues.has_key('messages'): - # the action was a set (so adding new messages to an existing issue) - m = {} - for msgid in oldvalues['messages']: - m[msgid] = 1 - messages = [] - # figure which of the messages now on the issue weren't there before - for msgid in cl.get(nodeid, 'messages'): - if not m.has_key(msgid): - messages.append(msgid) - return messages - -def updatenosy(db, cl, nodeid, newvalues): - '''Update the nosy list for changes to the assignedto - ''' - # nodeid will be None if this is a new node - current_nosy = sets.Set() - if nodeid is None: - ok = ('new', 'yes') - else: - ok = ('yes',) - # old node, get the current values from the node if they haven't - # changed - if not newvalues.has_key('nosy'): - nosy = cl.get(nodeid, 'nosy') - for value in nosy: - current_nosy.add(value) - - # if the nosy list changed in this transaction, init from the new value - if newvalues.has_key('nosy'): - nosy = newvalues.get('nosy', []) - for value in nosy: - if not db.hasnode('user', value): - continue - current_nosy.add(value) - - new_nosy = sets.Set(current_nosy) - - # add assignedto(s) to the nosy list - if newvalues.has_key('assignedto') and newvalues['assignedto'] is not None: - propdef = cl.getprops() - if isinstance(propdef['assignedto'], hyperdb.Link): - assignedto_ids = [newvalues['assignedto']] - elif isinstance(propdef['assignedto'], hyperdb.Multilink): - assignedto_ids = newvalues['assignedto'] - for assignedto_id in assignedto_ids: - new_nosy.add(assignedto_id) - - # see if there's any new messages - if so, possibly add the author and - # recipient to the nosy - if newvalues.has_key('messages'): - if nodeid is None: - ok = ('new', 'yes') - messages = newvalues['messages'] - else: - ok = ('yes',) - # figure which of the messages now on the issue weren't - oldmessages = cl.get(nodeid, 'messages') - messages = [] - for msgid in newvalues['messages']: - if msgid not in oldmessages: - messages.append(msgid) - - # configs for nosy modifications - add_author = getattr(db.config, 'ADD_AUTHOR_TO_NOSY', 'new') - add_recips = getattr(db.config, 'ADD_RECIPIENTS_TO_NOSY', 'new') - - # now for each new message: - msg = db.msg - for msgid in messages: - if add_author in ok: - authid = msg.get(msgid, 'author') - new_nosy.add(authid) - - # add on the recipients of the message - if add_recips in ok: - for recipient in msg.get(msgid, 'recipients'): - new_nosy.add(recipient) - - if current_nosy != new_nosy: - # that's it, save off the new nosy list - newvalues['nosy'] = list(new_nosy) - -def init(db): - db.issue.react('create', nosyreaction) - db.issue.react('set', nosyreaction) - db.issue.audit('create', updatenosy) - db.issue.audit('set', updatenosy) - -# vim: set filetype=python ts=4 sw=4 et si diff --git a/templates/classic/detectors/statusauditor.py b/templates/classic/detectors/statusauditor.py deleted file mode 100644 index 75e4962..0000000 --- a/templates/classic/detectors/statusauditor.py +++ /dev/null @@ -1,85 +0,0 @@ -# Copyright (c) 2002 ekit.com Inc (http://www.ekit-inc.com/) -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -# -#$Id: statusauditor.py,v 1.5 2004-03-27 00:01:48 richard Exp $ - -def chatty(db, cl, nodeid, newvalues): - ''' If the issue is currently 'unread', 'resolved', 'done-cbb' or None, - then set it to 'chatting' - ''' - # don't fire if there's no new message (ie. chat) - if not newvalues.has_key('messages'): - return - if newvalues['messages'] == cl.get(nodeid, 'messages'): - return - - # get the chatting state ID - try: - chatting_id = db.status.lookup('chatting') - except KeyError: - # no chatting state, ignore all this stuff - return - - # get the current value - current_status = cl.get(nodeid, 'status') - - # see if there's an explicit change in this transaction - if newvalues.has_key('status'): - # yep, skip - return - - # determine the id of 'unread', 'resolved' and 'chatting' - fromstates = [] - for state in 'unread resolved done-cbb'.split(): - try: - fromstates.append(db.status.lookup(state)) - except KeyError: - pass - - # ok, there's no explicit change, so check if we are in a state that - # should be changed - if current_status in fromstates + [None]: - # yep, we're now chatting - newvalues['status'] = chatting_id - - -def presetunread(db, cl, nodeid, newvalues): - ''' Make sure the status is set on new issues - ''' - if newvalues.has_key('status') and newvalues['status']: - return - - # get the unread state ID - try: - unread_id = db.status.lookup('unread') - except KeyError: - # no unread state, ignore all this stuff - return - - # ok, do it - newvalues['status'] = unread_id - - -def init(db): - # fire before changes are made - db.issue.audit('set', chatty) - db.issue.audit('create', presetunread) - -# vim: set filetype=python ts=4 sw=4 et si diff --git a/templates/classic/detectors/userauditor.py b/templates/classic/detectors/userauditor.py deleted file mode 100644 index fc71a1c..0000000 --- a/templates/classic/detectors/userauditor.py +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright (c) 2003 Richard Jones (richard@mechanicalcat.net) -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -# -#$Id: userauditor.py,v 1.9 2007-09-12 21:11:13 jpend Exp $ - -import re - -# regular expression thanks to: http://www.regular-expressions.info/email.html -# this is the "99.99% solution for syntax only". -email_regexp = (r"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*", r"(localhost|(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9]))") -email_rfc = re.compile('^' + email_regexp[0] + '@' + email_regexp[1] + '$', re.IGNORECASE) -email_local = re.compile('^' + email_regexp[0] + '$', re.IGNORECASE) - -def valid_address(address): - ''' If we see an @-symbol in the address then check against the full - RFC syntax. Otherwise it is a local-only address so only check - the local part of the RFC syntax. - ''' - if '@' in address: - return email_rfc.match(address) - else: - return email_local.match(address) - -def get_addresses(user): - ''' iterate over all known addresses in a newvalues dict - this takes of the address/alterate_addresses handling - ''' - if user.has_key('address'): - yield user['address'] - if user.get('alternate_addresses', None): - for address in user['alternate_addresses'].split('\n'): - yield address - -def audit_user_fields(db, cl, nodeid, newvalues): - ''' Make sure user properties are valid. - - - email address is syntactically valid - - email address is unique - - roles specified exist - - timezone is valid - ''' - - for address in get_addresses(newvalues): - if not valid_address(address): - raise ValueError, 'Email address syntax is invalid' - - check_main = db.user.stringFind(address=address) - # make sure none of the alts are owned by anyone other than us (x!=nodeid) - check_alts = [x for x in db.user.filter(None, {'alternate_addresses' : address}) if x != nodeid] - if check_main or check_alts: - raise ValueError, 'Email address %s already in use' % address - - for rolename in [r.lower().strip() for r in newvalues.get('roles', '').split(',')]: - if rolename and not db.security.role.has_key(rolename): - raise ValueError, 'Role "%s" does not exist'%rolename - - tz = newvalues.get('timezone', None) - if tz: - # if they set a new timezone validate the timezone by attempting to - # use it before we store it to the db. - import roundup.date - import datetime - try: - TZ = roundup.date.get_timezone(tz) - dt = datetime.datetime.now() - local = TZ.localize(dt).utctimetuple() - except IOError: - raise ValueError, 'Timezone "%s" does not exist' % tz - except ValueError: - raise ValueError, 'Timezone "%s" exceeds valid range [-23...23]' % tz - -def init(db): - # fire before changes are made - db.user.audit('set', audit_user_fields) - db.user.audit('create', audit_user_fields) - -# vim: sts=4 sw=4 et si diff --git a/templates/classic/extensions/README.txt b/templates/classic/extensions/README.txt deleted file mode 100644 index ff4dff3..0000000 --- a/templates/classic/extensions/README.txt +++ /dev/null @@ -1,6 +0,0 @@ -This directory is for tracker extensions: - -- CGI Actions -- Templating functions - -See the customisation doc for more information. diff --git a/templates/classic/html/_generic.404.html b/templates/classic/html/_generic.404.html deleted file mode 100644 index 71c9e0e..0000000 --- a/templates/classic/html/_generic.404.html +++ /dev/null @@ -1,9 +0,0 @@ - - -Item Not Found - - - -There is no with id - - diff --git a/templates/classic/html/_generic.calendar.html b/templates/classic/html/_generic.calendar.html deleted file mode 100644 index 0f9cf40..0000000 --- a/templates/classic/html/_generic.calendar.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - diff --git a/templates/classic/html/_generic.collision.html b/templates/classic/html/_generic.collision.html deleted file mode 100644 index 2a2768a..0000000 --- a/templates/classic/html/_generic.collision.html +++ /dev/null @@ -1,16 +0,0 @@ - -<span tal:replace="python:context._classname.capitalize()" - i18n:name="class" /> Edit Collision - <span i18n:name="tracker" - tal:replace="config/TRACKER_NAME" /> - Edit Collision - - - - diff --git a/templates/classic/html/_generic.help-empty.html b/templates/classic/html/_generic.help-empty.html deleted file mode 100644 index 65469fc..0000000 --- a/templates/classic/html/_generic.help-empty.html +++ /dev/null @@ -1,8 +0,0 @@ - - - Empty page (no search performed yet) - - -

Please specify your search parameters!

- - diff --git a/templates/classic/html/_generic.help-list.html b/templates/classic/html/_generic.help-list.html deleted file mode 100644 index 66cbb90..0000000 --- a/templates/classic/html/_generic.help-list.html +++ /dev/null @@ -1,83 +0,0 @@ - - - Search result for user helper - - - - - - -
-
-  

You are not - allowed to view this page.

- - - -
- - - - - - -
- - - - - - - - - - - - - - - - - - - -
 x
- - - -
-
-
-
- -
-     
-  
-
diff --git a/templates/classic/html/_generic.help-search.html b/templates/classic/html/_generic.help-search.html
deleted file mode 100644
index 01d657e..0000000
--- a/templates/classic/html/_generic.help-search.html
+++ /dev/null
@@ -1,13 +0,0 @@
-
-  
-    Frame for search input fields
-  
-  
-    

Generic template - help-search - or version for class - user - is not yet implemented

- - - diff --git a/templates/classic/html/_generic.help-submit.html b/templates/classic/html/_generic.help-submit.html deleted file mode 100644 index b13aa4a..0000000 --- a/templates/classic/html/_generic.help-submit.html +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - Generic submit page for framed helper windows - - - - - -
- 
-
- -
- - - - -
- - - diff --git a/templates/classic/html/_generic.help.html b/templates/classic/html/_generic.help.html deleted file mode 100644 index 069c0a6..0000000 --- a/templates/classic/html/_generic.help.html +++ /dev/null @@ -1,98 +0,0 @@ - - - - - - - <tal:x i18n:name="property" - tal:content="property" i18n:translate="" /> help - <span i18n:name="tracker" - tal:replace="config/TRACKER_NAME" /> - - - - - -
- -
- - - - -
- - - - - - -
- - - - - - - - - - - - - - - - -
 x
- - - -
 x
- -
- - diff --git a/templates/classic/html/_generic.index.html b/templates/classic/html/_generic.index.html deleted file mode 100644 index a41ab0a..0000000 --- a/templates/classic/html/_generic.index.html +++ /dev/null @@ -1,70 +0,0 @@ - - - -<span tal:replace="python:context._classname.capitalize()" - i18n:name="class" /> editing - <span i18n:name="tracker" - tal:replace="config/TRACKER_NAME" /> - editing - - - -You are not allowed to view this page. - -Please login with your username and password. - - - -

- You may edit the contents of the - - 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 (""). -

- -

- Multilink properties have their multiple values colon (":") separated - (... ,"one:two:three", ...) -

- -

- Remove entries by deleting their line. Add new entries by appending - them to the table - put an X in the id column. -

-
-
- -
- - -
-
- - - - - - - - - - -
 
 
- - - -
diff --git a/templates/classic/html/_generic.item.html b/templates/classic/html/_generic.item.html deleted file mode 100644 index d9b98ae..0000000 --- a/templates/classic/html/_generic.item.html +++ /dev/null @@ -1,53 +0,0 @@ - -<span tal:replace="python:context._classname.capitalize()" - i18n:name="class" /> editing - <span i18n:name="tracker" - tal:replace="config/TRACKER_NAME" /> - editing - - - -

- You are not allowed to view this page.

- -

- Please login with your username and password.

- -
- -
- - - - - - - - - - - - - - - -
  - submit button will go here -
- -
- - - -
- - - -
diff --git a/templates/classic/html/file.index.html b/templates/classic/html/file.index.html deleted file mode 100644 index 9717920..0000000 --- a/templates/classic/html/file.index.html +++ /dev/null @@ -1,31 +0,0 @@ - - -List of files - <span tal:replace="config/TRACKER_NAME" i18n:name="tracker" /> -List of files - - - - - - - - - - - - - - - - - -
DownloadContent TypeUploaded ByDate
- dld link - content typecreator's namecreation date
- - - -
diff --git a/templates/classic/html/file.item.html b/templates/classic/html/file.item.html deleted file mode 100644 index d223fd7..0000000 --- a/templates/classic/html/file.item.html +++ /dev/null @@ -1,53 +0,0 @@ - -File display - <span - i18n:name="tracker" tal:replace="config/TRACKER_NAME" /> -File display - - - -

- You are not allowed to view this page.

- -

- Please login with your username and password.

- -
- - - - - - - - - - - - - - - -
Name
Content Type
-   - - - - submit button here
-
- -download - - - - - - diff --git a/templates/classic/html/help.html b/templates/classic/html/help.html deleted file mode 100644 index 1571a6f..0000000 --- a/templates/classic/html/help.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - x - - - - - - - - - - -
diff --git a/templates/classic/html/help_controls.js b/templates/classic/html/help_controls.js deleted file mode 100644 index 480170a..0000000 --- a/templates/classic/html/help_controls.js +++ /dev/null @@ -1,324 +0,0 @@ -// initial values for either Nosy, Superseder, Keyword and Waiting On, -// depending on which has called -original_field = form[field].value; - -// Some browsers (ok, IE) don't define the "undefined" variable. -undefined = document.geez_IE_is_really_friggin_annoying; - -function trim(value) { - var temp = value; - var obj = /^(\s*)([\W\w]*)(\b\s*$)/; - if (obj.test(temp)) { temp = temp.replace(obj, '$2'); } - var obj = / /g; - while (temp.match(obj)) { temp = temp.replace(obj, " "); } - return temp; -} - -function determineList() { - // generate a comma-separated list of the checked items - var list = new String(''); - - // either a checkbox object or an array of checkboxes - var check = document.frm_help.check; - - if ((check.length == undefined) && (check.checked != undefined)) { - // only one checkbox on page - if (check.checked) { - list = check.value; - } - } else { - // array of checkboxes - for (box=0; box < check.length; box++) { - if (check[box].checked) { - if (list.length == 0) { - separator = ''; - } - else { - separator = ','; - } - // we used to use an Array and push / join, but IE5.0 sux - list = list + separator + check[box].value; - } - } - } - return list; -} - -/** - * update the field in the opening window; - * the text_field variable must be set in the calling page - */ -function updateOpener() { - // write back to opener window - if (document.frm_help.check==undefined) { return; } - form[field].value = text_field.value; -} - -function updateList() { - // write back to opener window - if (document.frm_help.check==undefined) { return; } - form[field].value = determineList(); -} - -function updatePreview() { - // update the preview box - if (document.frm_help.check==undefined) { return; } - writePreview(determineList()); -} - -function clearList() { - // uncheck all checkboxes - if (document.frm_help.check==undefined) { return; } - for (box=0; box < document.frm_help.check.length; box++) { - document.frm_help.check[box].checked = false; - } -} - -function reviseList_framed(form, textfield) { - // update the checkboxes based on the preview field - // alert('reviseList_framed') - // alert(form) - if (form.check==undefined) - return; - // alert(textfield) - var to_check; - var list = textfield.value.split(","); - if (form.check.length==undefined) { - check = form.check; - to_check = false; - for (val in list) { - if (check.value==trim(list[val])) { - to_check = true; - break; - } - } - check.checked = to_check; - } else { - for (box=0; box < form.check.length; box++) { - check = form.check[box]; - to_check = false; - for (val in list) { - if (check.value==trim(list[val])) { - to_check = true; - break; - } - } - check.checked = to_check; - } - } -} - -function reviseList(vals) { - // update the checkboxes based on the preview field - if (document.frm_help.check==undefined) { return; } - var to_check; - var list = vals.split(","); - if (document.frm_help.check.length==undefined) { - check = document.frm_help.check; - to_check = false; - for (val in list) { - if (check.value==trim(list[val])) { - to_check = true; - break; - } - } - check.checked = to_check; - } else { - for (box=0; box < document.frm_help.check.length; box++) { - check = document.frm_help.check[box]; - to_check = false; - for (val in list) { - if (check.value==trim(list[val])) { - to_check = true; - break; - } - } - check.checked = to_check; - } - } -} - -function resetList() { - // reset preview and check boxes to initial values - if (document.frm_help.check==undefined) { return; } - writePreview(original_field); - reviseList(original_field); -} - -function writePreview(val) { - // writes a value to the text_preview - document.frm_help.text_preview.value = val; -} - -function focusField(name) { - for(i=0; i < document.forms.length; ++i) { - var obj = document.forms[i].elements[name]; - if (obj && obj.focus) {obj.focus();} - } -} - -function selectField(name) { - for(i=0; i < document.forms.length; ++i) { - var obj = document.forms[i].elements[name]; - if (obj && obj.focus){obj.focus();} - if (obj && obj.select){obj.select();} - } -} - -function checkRequiredFields(fields) -{ - var bonk=''; - var res=''; - var argv = checkRequiredFields.arguments; - var argc = argv.length; - var input = ''; - var val=''; - - for (var i=0; i < argc; i++) { - fi = argv[i]; - input = document.getElementById(fi); - if (input) { - val = input.value - if (val == '' || val == '-1' || val == -1) { - if (res == '') { - res = fi; - bonk = input; - } else { - res += ', '+fi; - } - } - } else { - alert('Field with id='+fi+' not found!') - } - } - if (res == '') { - return submit_once(); - } else { - alert('Missing value here ('+res+')!'); - if (window.event && window.event.returnvalue) { - event.returnValue = 0; // work-around for IE - } - bonk.focus(); - return false; - } -} - -/** - * seeks the given value (2nd argument) - * in the value of the given input element (1st argument), - * which is considered a list of values, separated by commas - */ -function has_value(input, val) -{ - var actval = input.value - var arr = feld.value.split(','); - var max = arr.length; - for (i=0;i remove_val() - * - * This will work nicely even for batched lists - */ -function append_val(name, val) -{ - var feld = document.itemSynopsis[name]; - var actval = feld.value; - if (actval == '') { - feld.value = val - } else { - var arr = feld.value.split(','); - var max = arr.length; - for (i=0;i append_val() - */ -function remove_val(name, val) -{ - var feld = document.itemSynopsis[name]; - var actval = feld.value; - var changed=false; - if (actval == '') { - return - } else { - var arr = feld.value.split(','); - var max = arr.length; - var neu = '' - for (i=0;i -List of classes - <span - i18n:name="tracker" tal:replace="config/TRACKER_NAME" /> -List of classes - - - - - - - - - - - - - -
- classname -
nametype
- - -
diff --git a/templates/classic/html/home.html b/templates/classic/html/home.html deleted file mode 100644 index 90d926a..0000000 --- a/templates/classic/html/home.html +++ /dev/null @@ -1,10 +0,0 @@ - - diff --git a/templates/classic/html/issue.index.html b/templates/classic/html/issue.index.html deleted file mode 100644 index 581624c..0000000 --- a/templates/classic/html/issue.index.html +++ /dev/null @@ -1,166 +0,0 @@ - - - - <span tal:omit-tag="true" i18n:translate="" >List of issues</span> - <span tal:condition="request/dispname" - tal:replace="python:' - %s '%request.dispname" - /> - <span tal:replace="config/TRACKER_NAME" /> - - - List of issues - - - - -

- You are not allowed to view this page.

- -

- Please login with your username and password.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PriorityIDCreationActivityActorKeywordTitleStatusCreatorAssigned To
- - - -
       - title -    
- - - - - - -
-
- -Download as CSV - -
- - - - - - - - - - - - - - - - - - - -
- Sort on: - - - Descending: -
- Group on: - - - Descending: -
- - -
-
- -
- - -
vim: sw=1 ts=8 et si - diff --git a/templates/classic/html/issue.item.html b/templates/classic/html/issue.item.html deleted file mode 100644 index 41ee073..0000000 --- a/templates/classic/html/issue.item.html +++ /dev/null @@ -1,197 +0,0 @@ - - - -<tal:block condition="context/id" i18n:translate="" - >Issue <tal:x tal:content="context/id" i18n:name="id" - />: <tal:x content="context/title" i18n:name="title" - /> - <tal:x content="config/TRACKER_NAME" i18n:name="tracker" -/></tal:block> -<tal:block condition="not:context/id" i18n:translate="" - >New Issue - <span tal:replace="config/TRACKER_NAME" i18n:name="tracker" -/></tal:block> - - - New Issue - New Issue Editing - Issue - Issue Editing - - - - -

- You are not allowed to view this page.

- -

- Please login with your username and password.

- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Titletitle
PrioritypriorityStatusstatus
Superseder - - - -
View: - -
-
Nosy List - -
-
Assigned Toassignedto menuKeywords - - -
Change Note - -
File
-   - - - - submit button - Make a copy -
-
- - - - - - - - -
Note: highlighted fields are required.
-
- -

- Created on - by , - last changed - by . -

- - - - - - - - - - - - - - - - -
Files
File nameUploadedTypeEditRemove
- dld link - - creator's name, - creation date - - edit - -
- - - -
-
- - - - - - - - - - - - - - -
Messages
msg (view)Author: Date: -
- - - -
-
-
content
-
- - - -
- - - -
diff --git a/templates/classic/html/issue.search.html b/templates/classic/html/issue.search.html deleted file mode 100644 index cff5122..0000000 --- a/templates/classic/html/issue.search.html +++ /dev/null @@ -1,234 +0,0 @@ - -Issue searching - <span - i18n:name="tracker" tal:replace="config/TRACKER_NAME" /> -Issue searching - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Filter onDisplaySort onGroup on
All text*:   
Title: 
Keyword: - -
ID: 
Creation Date:
Creator: - -
Activity: 
Actor: - -  
Priority: - -
Status: - - - - -
Assigned to: - - - - -
No Sort or group:  
Pagesize:
Start With:
Sort Descending: -
Group Descending: -
Query name**: - - -
-   - -
  - - *: The "all text" field will look in message bodies and issue titles -
- - **: If you supply a name, the query will be saved off and available as a - link in the sidebar - -
- -
- - -
diff --git a/templates/classic/html/keyword.item.html b/templates/classic/html/keyword.item.html deleted file mode 100644 index cf1e26a..0000000 --- a/templates/classic/html/keyword.item.html +++ /dev/null @@ -1,55 +0,0 @@ - - -Keyword editing - <span - i18n:name="tracker" tal:replace="config/TRACKER_NAME" /> -Keyword editing - - - - - - - - - - -
Existing Keywords
- keyword here -
- To edit an existing keyword (for spelling or typing errors), - click on its entry above. -
- -

- To create a new keyword, enter it below and click "Submit New Entry". -

- -
- - - - - - - - - - - -
Keywordname
-   - - - - submit button will go here -
-
- - -
diff --git a/templates/classic/html/msg.index.html b/templates/classic/html/msg.index.html deleted file mode 100644 index 02405dc..0000000 --- a/templates/classic/html/msg.index.html +++ /dev/null @@ -1,25 +0,0 @@ - -List of messages - <span tal:replace="config/TRACKER_NAME" - i18n:name="tracker"/> -Message listing - - - - - - - - - - - - - - - -
Messages
authordate
content
- - -
diff --git a/templates/classic/html/msg.item.html b/templates/classic/html/msg.item.html deleted file mode 100644 index e755174..0000000 --- a/templates/classic/html/msg.item.html +++ /dev/null @@ -1,83 +0,0 @@ - - - -<tal:block condition="context/id" i18n:translate="" - >Message <span tal:replace="context/id" i18n:name="id" - /> - <span tal:replace="config/TRACKER_NAME" i18n:name="tracker" -/></tal:block> -<tal:block condition="not:context/id" i18n:translate="" - >New Message - <span tal:replace="config/TRACKER_NAME" i18n:name="tracker" -/></tal:block> - - - New Message - New Message Editing - Message - Message Editing - - - -

- You are not allowed to view this page.

- -

- Please login with your username and password.

- -
- - - - - - - - - - - - - - - - -
Author
Recipients
Date
- - - - - - -
Content
- - - - - - - - - - - -
Files
File nameUploaded
- dld link - - creator's name, - creation date -
- - - -
- - -
diff --git a/templates/classic/html/page.html b/templates/classic/html/page.html deleted file mode 100644 index cd64875..0000000 --- a/templates/classic/html/page.html +++ /dev/null @@ -1,347 +0,0 @@ - - - -title goes here - - - - - - - - - - - - - - - - - - - - - - - -
  -
-

body title

-
- -
-

-

- - clear this message -

-
Page content goes here
- -
-
- - - -
- - - - - - - - - - - - - - - - (cal) - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
  • - -
  • -
  • - - -
  • -
- - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/templates/classic/html/query.edit.html b/templates/classic/html/query.edit.html deleted file mode 100644 index 2c586f1..0000000 --- a/templates/classic/html/query.edit.html +++ /dev/null @@ -1,111 +0,0 @@ - - -"Your Queries" Editing - <span tal:replace="config/TRACKER_NAME" - i18n:name="tracker" /> -"Your Queries" Editing - - - -You are not allowed to edit queries. - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
QueryInclude in "Your Queries"EditPrivate to you? 
query - - - [query is retired]
query - - edit - - - -
query - - - edit - [not yours to edit]
- - - -
- -
- -
diff --git a/templates/classic/html/query.item.html b/templates/classic/html/query.item.html deleted file mode 100644 index 453e13d..0000000 --- a/templates/classic/html/query.item.html +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/templates/classic/html/style.css b/templates/classic/html/style.css deleted file mode 100644 index 72e7ffc..0000000 --- a/templates/classic/html/style.css +++ /dev/null @@ -1,433 +0,0 @@ -/* main page styles */ -body.body { - font-family: sans-serif, Arial, Helvetica; - background-color: white; - color: #333; - margin: 0; -} -a[href]:hover { - color:blue; - text-decoration: underline; -} -a[href], a[href]:link { - color:blue; - text-decoration: none; -} - -table.body { - border: 0; - padding: 0; - border-spacing: 0; - border-collapse: separate; -} - -td.page-header-left { - padding: 5px; - border-bottom: 1px solid #444; -} -td.sidebar { - padding: 1px 0 0 1px; - white-space: nowrap; -} - -/* don't display the sidebar when printing */ -@media print { - td.page-header-left { - display: none; - } - td.sidebar { - display: none; - } - .index-controls { - display: none; - } - #searchbox { - display: none; - } -} - -td.page-header-top { - padding: 5px; - border-bottom: 1px solid #444; -} -#searchbox { - float: right; -} - -div#body-title { - float: left; -} - - -div#searchbox { - float: right; - padding-top: 1em; -} - -div#searchbox input#search-text { - width: 10em; -} - -form { - margin: 0; -} - -textarea { - font-family: monospace; -} - -td.sidebar p.classblock { - padding: 2px 5px 2px 5px; - margin: 1px; - border: 1px solid #444; - background-color: #eee; -} - -td.sidebar p.userblock { - padding: 2px 5px 2px 5px; - margin: 1px 1px 1px 1px; - border: 1px solid #444; - background-color: #eef; -} - -.form-small { - padding: 0; - font-size: 75%; -} - - -td.content { - padding: 1px 5px 1px 5px; - vertical-align: top; - width: 100%; -} - -td.date, th.date { - white-space: nowrap; -} - -p.ok-message { - background-color: #22bb22; - padding: 5px; - color: white; - font-weight: bold; -} -p.error-message { - background-color: #bb2222; - padding: 5px; - color: white; - font-weight: bold; -} -p.error-message a[href] { - color: white; - text-decoration: underline; -} - - -/* style for search forms */ -ul.search-checkboxes { - display: inline; - padding: 0; - list-style: none; -} -ul.search-checkboxes > li { - display: inline; - padding-right: .5em; -} - - -/* style for forms */ -table.form { - padding: 2px; - border-spacing: 0; - border-collapse: separate; -} - -table.form th { - color: #338; - text-align: right; - vertical-align: top; - font-weight: normal; - white-space: nowrap; -} - -table.form th.header { - font-weight: bold; - background-color: #eef; - text-align: left; -} - -table.form th.required { - font-weight: bold; -} - -table.form td { - color: #333; - empty-cells: show; - vertical-align: top; -} - -table.form td.optional { - font-weight: bold; - font-style: italic; -} - -table.form td.html { - color: #777; -} - -/* style for lists */ -table.list { - border-spacing: 0; - border-collapse: separate; - width: 100%; -} - -table.list th { - padding: 0 4px 0 4px; - color: #404070; - background-color: #eef; - border: 1px solid white; - vertical-align: top; - empty-cells: show; -} -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 4px 0 4px; - border: 1px solid white; - color: #404070; - background-color: #efefef; - vertical-align: top; - empty-cells: show; -} - -table.list tr.navigation th { - width: 33%; - border-style: hidden; - text-align: center; -} -table.list tr.navigation td { - border: none -} -table.list tr.navigation th:first-child { - text-align: left; -} -table.list tr.navigation th:last-child { - text-align: right; -} - - -/* style for message displays */ -table.messages { - border-spacing: 0; - 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; - border-bottom: 1px solid #afafaf; -} - -table.messages td { - font-family: monospace; - background-color: #efefef; - border-bottom: 1px solid #afafaf; - color: black; - empty-cells: show; - border-right: 1px solid #afafaf; - vertical-align: top; - padding: 2px 5px 2px 5px; -} - -table.messages td:first-child { - border-left: 1px solid #afafaf; - border-right: 1px solid #afafaf; -} - -/* style for file displays */ -table.files { - border-spacing: 0; - 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: 0; - 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: 0; - 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 { /* the table-layout: fixed; */ - table-layout: fixed; /* compromises quality for speed */ - overflow: hidden; - font-size: .9em; - padding-bottom: 3em; -} - -table.classhelp th { - font-weight: normal; - text-align: left; - color: #444; - background-color: #efefef; - border-bottom: 1px solid #afafaf; - border-top: 1px solid #afafaf; - text-transform: uppercase; - vertical-align: middle; - line-height:1.5em; -} - -table.classhelp td { - vertical-align: middle; - padding-right: .2em; - border-bottom: 1px solid #efefef; - text-align: left; - empty-cells: show; - white-space: nowrap; - vertical-align: middle; -} - -table.classhelp tr:hover { - background-color: #eee; -} - -label.classhelp-label { - cursor: pointer; -} - -#classhelp-controls { - position: fixed; - display: block; - top: auto; - right: 0; - bottom: 0; - left: 0; - padding: .5em; - border-top: 2px solid #444; - background-color: #eee; -} - -#classhelp-controls input.apply { - width: 7em; - font-weight: bold; - margin-right: 2em; - margin-left: 2em; -} - -#classhelp-controls input.preview { - margin-right: 3em; - margin-left: 1em; -} - -/* style for "other" displays */ -table.otherinfo { - border-spacing: 0; - 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; -} -input[type="text"]:focus, -input[type="checkbox"]:focus, -input[type="radio"]:focus, -input[type="password"]:focus, -textarea:focus, select:focus { - background-color: #ffffc0; -} - -/* vim: sts=2 sw=2 et -*/ diff --git a/templates/classic/html/user.forgotten.html b/templates/classic/html/user.forgotten.html deleted file mode 100644 index 3f0a472..0000000 --- a/templates/classic/html/user.forgotten.html +++ /dev/null @@ -1,43 +0,0 @@ - - -Password reset request - <span - i18n:name="tracker" tal:replace="config/TRACKER_NAME" /> -Password reset request - - -

You have two options if you have forgotten your password. -If you know the email address you registered with, enter it below.

- -
- - - - - - - - - -
Email Address:
  - - - -
- -

Or, if you know your username, then enter it below.

- - - - -
Username:
-
- -

A confirmation email will be sent to you - -please follow the instructions within it to complete the reset process.

- - -
diff --git a/templates/classic/html/user.help-search.html b/templates/classic/html/user.help-search.html deleted file mode 100644 index 8436897..0000000 --- a/templates/classic/html/user.help-search.html +++ /dev/null @@ -1,85 +0,0 @@ - - - Search input for user helper - - - - - -
-    
- - - - - - - - - - - - - - - - - - - - - - - - -
Name
Phone
role - -
  - - - - - - -
- -
-
-
-  
-
diff --git a/templates/classic/html/user.help.html b/templates/classic/html/user.help.html
deleted file mode 100644
index b338c2b..0000000
--- a/templates/classic/html/user.help.html
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-  
-      
-      
-      
-      <tal:x i18n:translate=""><tal:x i18n:name="property"
-       tal:content="property" i18n:translate="" /> help - <span i18n:name="tracker"
-	       tal:replace="config/TRACKER_NAME" /></tal:x>
-      
-      
-      
-  
-
-  
-  
-  
-  
-  
-
-
-  <body>
-<p i18n:translate="">
-Your browser is not capable of using frames; you should be redirected immediately,
-or visit <a href="#" tal:attributes="href string:?${qs}&template=help-noframes"
-i18n:name="link">this link</a>.
-</p>
-</body>
-
-
-
diff --git a/templates/classic/html/user.index.html b/templates/classic/html/user.index.html
deleted file mode 100644
index 021e2b8..0000000
--- a/templates/classic/html/user.index.html
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
-User listing - <span
- i18n:name="tracker" tal:replace="config/TRACKER_NAME" />
-User listing
-
-
-You are not allowed to view this page.
-
-Please login with your username and password.
-
-
-
- 
- 
- 
- 
- 
- 
-
-
-
- 
- 
- 
- 
- 
- 
-
-
-
UsernameReal nameOrganisationEmail addressPhone numberRetire
- username -      - retire -
- - -
diff --git a/templates/classic/html/user.item.html b/templates/classic/html/user.item.html deleted file mode 100644 index bafccd2..0000000 --- a/templates/classic/html/user.item.html +++ /dev/null @@ -1,169 +0,0 @@ - - - -<tal:if condition="context/id" i18n:translate="" - >User <tal:x content="context/id" i18n:name="id" - />: <tal:x content="context/username" i18n:name="title" - /> - <tal:x content="config/TRACKER_NAME" i18n:name="tracker" -/></tal:if> -<tal:if condition="not:context/id" i18n:translate="" - >New User - <span tal:replace="config/TRACKER_NAME" i18n:name="tracker" -/></tal:if> - - - - - - - New User - New User Editing - User - User Editing - - - - -

- You are not allowed to view this page.

- -

- Please login with your username and password.

- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name
Login Name
Login Password
Confirm Password
- - - - - - - (to give the user more than one role, - enter a comma,separated,list) -
Phone
Organisation
Timezone - (this is a numeric hour offset, the default is - ) -
E-mail address - calvin@the-z.org - - - -   -
- -
-   - - - - -
-
- - - - - - - - -
Note: highlighted fields are required.
-
- - - -
- - - -
diff --git a/templates/classic/html/user.register.html b/templates/classic/html/user.register.html deleted file mode 100644 index b7b1749..0000000 --- a/templates/classic/html/user.register.html +++ /dev/null @@ -1,81 +0,0 @@ - - -Registering with <span i18n:name="tracker" - tal:replace="db/config/TRACKER_NAME" /> -Registering with - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Namerealname
Login Nameusername
Login Passwordpassword
Confirm Passwordpassword
Rolesroles - -
Phonephone
Organisationorganisation
E-mail addressaddress
Alternate E-mail addresses
One address per line
alternate_addresses
  - - - - -
-
- - - - - - - - -
Note: highlighted fields are required.
-
- - - -
diff --git a/templates/classic/html/user.rego_progress.html b/templates/classic/html/user.rego_progress.html deleted file mode 100644 index 4d6bfe4..0000000 --- a/templates/classic/html/user.rego_progress.html +++ /dev/null @@ -1,16 +0,0 @@ - - -Registration in progress - <span i18n:name="tracker" - tal:replace="config/TRACKER_NAME" /> -Registration in progress... - - -

You will shortly receive an email -to confirm your registration. To complete the registration process, -visit the link indicated in the email. -

- - -
diff --git a/templates/classic/html/user_utils.js b/templates/classic/html/user_utils.js deleted file mode 100644 index 7b2946d..0000000 --- a/templates/classic/html/user_utils.js +++ /dev/null @@ -1,114 +0,0 @@ -// User Editing Utilities - -/** - * for new users: - * Depending on the input field which calls it, takes the value - * and dispatches it to certain other input fields: - * - * address - * +-> username - * | `-> realname - * `-> organisation - */ -function split_name(that) { - var raw = that.value - var val = trim(raw) - if (val == '') { - return - } - var username='' - var realname='' - var address='' - switch (that.name) { - case 'address': - address=val - break - case 'username': - username=val - break - case 'realname': - realname=val - break - case 'firstname': - case 'lastname': - return - default: - alert('Ooops - unknown name field '+that.name+'!') - return - } - var the_form = that.form; - - function field_empty(name) { - return the_form[name].value == '' - } - - // no break statements - on purpose! - switch (that.name) { - case 'address': - var split1 = address.split('@') - if (field_empty('username')) { - username = split1[0] - the_form.username.value = username - } - if (field_empty('organisation')) { - the_form.organisation.value = default_organisation(split1[1]) - } - case 'username': - if (field_empty('realname')) { - realname = Cap(username.split('.').join(' ')) - the_form.realname.value = realname - } - case 'realname': - if (field_empty('username')) { - username = Cap(realname.replace(' ', '.')) - the_form.username.value = username - } - if (the_form.firstname && the_form.lastname) { - var split2 = realname.split(' ') - var firstname='', lastname='' - firstname = split2[0] - lastname = split2.slice(1).join(' ') - if (field_empty('firstname')) { - the_form.firstname.value = firstname - } - if (field_empty('lastname')) { - the_form.lastname.value = lastname - } - } - } -} - -function SubCap(str) { - switch (str) { - case 'de': case 'do': case 'da': - case 'du': case 'von': - return str; - } - if (str.toLowerCase().slice(0,2) == 'mc') { - return 'Mc'+str.slice(2,3).toUpperCase()+str.slice(3).toLowerCase() - } - return str.slice(0,1).toUpperCase()+str.slice(1).toLowerCase() -} - -function Cap(str) { - var liz = str.split(' ') - for (var i=0; i/db/files/] -# type = String() [MIME type of the content, default 'text/plain'] -msg = FileClass(db, "msg", - author=Link("user", do_journal='no'), - recipients=Multilink("user", do_journal='no'), - date=Date(), - summary=String(), - files=Multilink("file"), - messageid=String(), - inreplyto=String()) - -file = FileClass(db, "file", - name=String()) - -# IssueClass automatically gets these properties in addition to the Class ones: -# title = String() -# messages = Multilink("msg") -# files = Multilink("file") -# nosy = Multilink("user") -# superseder = Multilink("issue") -issue = IssueClass(db, "issue", - assignedto=Link("user"), - keyword=Multilink("keyword"), - priority=Link("priority"), - status=Link("status")) - -# -# TRACKER SECURITY SETTINGS -# -# See the configuration and customisation document for information -# about security setup. - -# -# REGULAR USERS -# -# Give the regular users access to the web and email interface -db.security.addPermissionToRole('User', 'Web Access') -db.security.addPermissionToRole('User', 'Email Access') - -# Assign the access and edit Permissions for issue, file and message -# to regular users now -for cl in 'issue', 'file', 'msg', 'keyword': - db.security.addPermissionToRole('User', 'View', cl) - db.security.addPermissionToRole('User', 'Edit', cl) - db.security.addPermissionToRole('User', 'Create', cl) -for cl in 'priority', 'status': - db.security.addPermissionToRole('User', 'View', cl) - -# May users view other user information? Comment these lines out -# if you don't want them to -db.security.addPermissionToRole('User', 'View', 'user') - -# Users should be able to edit their own details -- this permission is -# limited to only the situation where the Viewed or Edited item is their own. -def own_record(db, userid, itemid): - '''Determine whether the userid matches the item being accessed.''' - return userid == itemid -p = db.security.addPermission(name='View', klass='user', check=own_record, - description="User is allowed to view their own user details") -db.security.addPermissionToRole('User', p) -p = db.security.addPermission(name='Edit', klass='user', check=own_record, - description="User is allowed to edit their own user details") -db.security.addPermissionToRole('User', p) - -# Users should be able to edit and view their own queries. They should also -# be able to view any marked as not private. They should not be able to -# edit others' queries, even if they're not private -def view_query(db, userid, itemid): - private_for = db.query.get(itemid, 'private_for') - if not private_for: return True - return userid == private_for -def edit_query(db, userid, itemid): - return userid == db.query.get(itemid, 'creator') -p = db.security.addPermission(name='View', klass='query', check=view_query, - description="User is allowed to view their own and public queries") -db.security.addPermissionToRole('User', p) -p = db.security.addPermission(name='Edit', klass='query', check=edit_query, - description="User is allowed to edit their queries") -db.security.addPermissionToRole('User', p) -p = db.security.addPermission(name='Create', klass='query', - description="User is allowed to create queries") -db.security.addPermissionToRole('User', p) - - -# -# ANONYMOUS USER PERMISSIONS -# -# Let anonymous users access the web interface. Note that almost all -# trackers will need this Permission. The only situation where it's not -# required is in a tracker that uses an HTTP Basic Authenticated front-end. -db.security.addPermissionToRole('Anonymous', 'Web Access') - -# Let anonymous users access the email interface (note that this implies -# that they will be registered automatically, hence they will need the -# "Create" user Permission below) -# This is disabled by default to stop spam from auto-registering users on -# public trackers. -#db.security.addPermissionToRole('Anonymous', 'Email Access') - -# Assign the appropriate permissions to the anonymous user's Anonymous -# Role. Choices here are: -# - Allow anonymous users to register -db.security.addPermissionToRole('Anonymous', 'Create', 'user') - -# Allow anonymous users access to view issues (and the related, linked -# information) -for cl in 'issue', 'file', 'msg', 'keyword', 'priority', 'status': - db.security.addPermissionToRole('Anonymous', 'View', cl) - -# [OPTIONAL] -# Allow anonymous users access to create or edit "issue" items (and the -# related file and message items) -#for cl in 'issue', 'file', 'msg': -# db.security.addPermissionToRole('Anonymous', 'Create', cl) -# db.security.addPermissionToRole('Anonymous', 'Edit', cl) - - -# vim: set filetype=python sts=4 sw=4 et si : diff --git a/templates/minimal/.cvsignore b/templates/minimal/.cvsignore deleted file mode 100644 index d90d51d..0000000 --- a/templates/minimal/.cvsignore +++ /dev/null @@ -1,4 +0,0 @@ -*.pyc -*.pyo -htmlbase.py -*.cover diff --git a/templates/minimal/TEMPLATE-INFO.txt b/templates/minimal/TEMPLATE-INFO.txt deleted file mode 100644 index 0cb35b5..0000000 --- a/templates/minimal/TEMPLATE-INFO.txt +++ /dev/null @@ -1,8 +0,0 @@ -Name: minimal -Description: This is an empty tracker - it must be customised for it to be - useful! It only defines the bare minimum of information - the - user database and the two default users (admin and anonymous). - The rest is entirely up to you! Not recommended for first-time - Roundup users (it's easier to tweak the Classic tracker). -Intended-For: Roundup experts who need a clean slate to start with. - diff --git a/templates/minimal/detectors/.cvsignore b/templates/minimal/detectors/.cvsignore deleted file mode 100644 index 4162d5e..0000000 --- a/templates/minimal/detectors/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -*.pyc -*.pyo -*.cover diff --git a/templates/minimal/detectors/userauditor.py b/templates/minimal/detectors/userauditor.py deleted file mode 100644 index dd7fcc4..0000000 --- a/templates/minimal/detectors/userauditor.py +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright (c) 2003 Richard Jones (richard@mechanicalcat.net) -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -# -#$Id: userauditor.py,v 1.8 2007-09-12 21:11:14 jpend Exp $ - -import re - -# regular expression thanks to: http://www.regular-expressions.info/email.html -# this is the "99.99% solution for syntax only". -email_regexp = (r"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*", r"(localhost|(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9]))") -email_rfc = re.compile('^' + email_regexp[0] + '@' + email_regexp[1] + '$', re.IGNORECASE) -email_local = re.compile('^' + email_regexp[0] + '$', re.IGNORECASE) - -def valid_address(address): - ''' If we see an @-symbol in the address then check against the full - RFC syntax. Otherwise it is a local-only address so only check - the local part of the RFC syntax. - ''' - if '@' in address: - return email_rfc.match(address) - else: - return email_local.match(address) - -def get_addresses(user): - ''' iterate over all known addresses in a newvalues dict - this takes of the address/alterate_addresses handling - ''' - if user.has_key('address'): - yield user['address'] - if user.get('alternate_addresses', None): - for address in user['alternate_addresses'].split('\n'): - yield address - -def audit_user_fields(db, cl, nodeid, newvalues): - ''' Make sure user properties are valid. - - - email address is syntactically valid - - email address is unique - - roles specified exist - - timezone is valid - ''' - - for address in get_addresses(newvalues): - if not valid_address(address): - raise ValueError, 'Email address syntax is invalid' - - check_main = db.user.stringFind(address=address) - # make sure none of the alts are owned by anyone other than us (x!=nodeid) - check_alts = [x for x in db.user.filter(None, {'alternate_addresses' : address}) if x != nodeid] - if check_main or check_alts: - raise ValueError, 'Email address %s already in use' % address - - for rolename in [r.lower().strip() for r in newvalues.get('roles', '').split(',')]: - if rolename and not db.security.role.has_key(rolename): - raise ValueError, 'Role "%s" does not exist'%rolename - - tz = newvalues.get('timezone', None) - if tz: - # if they set a new timezone validate the timezone by attempting to - # use it before we store it to the db. - import roundup.date - import datetime - try: - TZ = roundup.date.get_timezone(tz) - dt = datetime.datetime.now() - local = TZ.localize(dt).utctimetuple() - except IOError: - raise ValueError, 'Timezone "%s" does not exist' % tz - except ValueError: - raise ValueError, 'Timezone "%s" exceeds valid range [-23...23]' % tz - -def init(db): - # fire before changes are made - db.user.audit('set', audit_user_fields) - db.user.audit('create', audit_user_fields) - -# vim: sts=4 sw=4 et si diff --git a/templates/minimal/extensions/README.txt b/templates/minimal/extensions/README.txt deleted file mode 100644 index ff4dff3..0000000 --- a/templates/minimal/extensions/README.txt +++ /dev/null @@ -1,6 +0,0 @@ -This directory is for tracker extensions: - -- CGI Actions -- Templating functions - -See the customisation doc for more information. diff --git a/templates/minimal/html/_generic.404.html b/templates/minimal/html/_generic.404.html deleted file mode 100644 index 71c9e0e..0000000 --- a/templates/minimal/html/_generic.404.html +++ /dev/null @@ -1,9 +0,0 @@ - - -Item Not Found - - - -There is no with id - - diff --git a/templates/minimal/html/_generic.calendar.html b/templates/minimal/html/_generic.calendar.html deleted file mode 100644 index dbc3b57..0000000 --- a/templates/minimal/html/_generic.calendar.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - diff --git a/templates/minimal/html/_generic.collision.html b/templates/minimal/html/_generic.collision.html deleted file mode 100644 index 2a2768a..0000000 --- a/templates/minimal/html/_generic.collision.html +++ /dev/null @@ -1,16 +0,0 @@ - -<span tal:replace="python:context._classname.capitalize()" - i18n:name="class" /> Edit Collision - <span i18n:name="tracker" - tal:replace="config/TRACKER_NAME" /> - Edit Collision - - - - diff --git a/templates/minimal/html/_generic.help.html b/templates/minimal/html/_generic.help.html deleted file mode 100644 index 069c0a6..0000000 --- a/templates/minimal/html/_generic.help.html +++ /dev/null @@ -1,98 +0,0 @@ - - - - - - - <tal:x i18n:name="property" - tal:content="property" i18n:translate="" /> help - <span i18n:name="tracker" - tal:replace="config/TRACKER_NAME" /> - - - - - -
- -
- - - - -
- - - - - - -
- - - - - - - - - - - - - - - - -
 x
- - - -
 x
- -
- - diff --git a/templates/minimal/html/_generic.index.html b/templates/minimal/html/_generic.index.html deleted file mode 100644 index 81918ef..0000000 --- a/templates/minimal/html/_generic.index.html +++ /dev/null @@ -1,70 +0,0 @@ - - - -<span tal:replace="python:context._classname.capitalize()" - i18n:name="class" /> editing - <span i18n:name="tracker" - tal:replace="config/TRACKER_NAME" /> - editing - - - -You are not allowed to view this page. - -Please login with your username and password. - - - -

- You may edit the contents of the - - 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 (""). -

- -

- Multilink properties have their multiple values colon (":") separated - (... ,"one:two:three", ...) -

- -

- Remove entries by deleting their line. Add new entries by appending - them to the table - put an X in the id column. -

-
-
- -
- - -
-
- - - - - - - - - - -
 
 
- - - -
diff --git a/templates/minimal/html/_generic.item.html b/templates/minimal/html/_generic.item.html deleted file mode 100644 index ac60acb..0000000 --- a/templates/minimal/html/_generic.item.html +++ /dev/null @@ -1,65 +0,0 @@ - -<span tal:replace="python:context._classname.capitalize()" - i18n:name="class" /> editing - <span i18n:name="tracker" - tal:replace="config/TRACKER_NAME" /> - editing - - - -You are not allowed to view this page. - -Please login with your username and password. - -
- - - - - - - - - - - - - - - -
  - submit button will go here -
- -
- - - - - - - - - -
- - - - - - - - - diff --git a/templates/minimal/html/help_controls.js b/templates/minimal/html/help_controls.js deleted file mode 100644 index d3b5529..0000000 --- a/templates/minimal/html/help_controls.js +++ /dev/null @@ -1,111 +0,0 @@ -// initial values for either Nosy, Superseder, Keyword and Waiting On, -// depending on which has called -original_field = form[field].value; - -// Some browsers (ok, IE) don't define the "undefined" variable. -undefined = document.geez_IE_is_really_friggin_annoying; - -function trim(value) { - var temp = value; - var obj = /^(\s*)([\W\w]*)(\b\s*$)/; - if (obj.test(temp)) { temp = temp.replace(obj, '$2'); } - var obj = / /g; - while (temp.match(obj)) { temp = temp.replace(obj, " "); } - return temp; -} - -function determineList() { - // generate a comma-separated list of the checked items - var list = new String(''); - for (box=0; box < document.frm_help.check.length; box++) { - if (document.frm_help.check[box].checked) { - if (list.length == 0) { - separator = ''; - } - else { - separator = ','; - } - // we used to use an Array and push / join, but IE5.0 sux - list = list + separator + document.frm_help.check[box].value; - } - } - return list; -} - -function updateList() { - // write back to opener window - if (document.frm_help.check==undefined) { return; } - form[field].value = determineList(); -} - -function updatePreview() { - // update the preview box - if (document.frm_help.check==undefined) { return; } - writePreview(determineList()); -} - -function clearList() { - // uncheck all checkboxes - if (document.frm_help.check==undefined) { return; } - for (box=0; box < document.frm_help.check.length; box++) { - document.frm_help.check[box].checked = false; - } -} - -function reviseList(vals) { - // update the checkboxes based on the preview field - if (document.frm_help.check==undefined) { return; } - var to_check; - var list = vals.split(","); - if (document.frm_help.check.length==undefined) { - check = document.frm_help.check; - to_check = false; - for (val in list) { - if (check.value==trim(list[val])) { - to_check = true; - break; - } - } - check.checked = to_check; - } else { - for (box=0; box < document.frm_help.check.length; box++) { - check = document.frm_help.check[box]; - to_check = false; - for (val in list) { - if (check.value==trim(list[val])) { - to_check = true; - break; - } - } - check.checked = to_check; - } - } -} - -function resetList() { - // reset preview and check boxes to initial values - if (document.frm_help.check==undefined) { return; } - writePreview(original_field); - reviseList(original_field); -} - -function writePreview(val) { - // writes a value to the text_preview - document.frm_help.text_preview.value = val; -} - -function focusField(name) { - for(i=0; i < document.forms.length; ++i) { - var obj = document.forms[i].elements[name]; - if (obj && obj.focus) {obj.focus();} - } -} - -function selectField(name) { - for(i=0; i < document.forms.length; ++i) { - var obj = document.forms[i].elements[name]; - if (obj && obj.focus){obj.focus();} - if (obj && obj.select){obj.select();} - } -} - diff --git a/templates/minimal/html/home.classlist.html b/templates/minimal/html/home.classlist.html deleted file mode 100644 index 930306b..0000000 --- a/templates/minimal/html/home.classlist.html +++ /dev/null @@ -1,25 +0,0 @@ - -List of classes - <span - i18n:name="tracker" tal:replace="config/TRACKER_NAME" /> -List of classes - - - - - - - - - - - - - -
- classname -
nametype
- - -
diff --git a/templates/minimal/html/home.html b/templates/minimal/html/home.html deleted file mode 100644 index c933c59..0000000 --- a/templates/minimal/html/home.html +++ /dev/null @@ -1,25 +0,0 @@ - -Tracker home - <span - i18n:name="tracker" tal:replace="config/TRACKER_NAME" /> -Tracker home - - - - - -

-Please select from one of the menu options on the left. -

-

-Please log in or register. -

-
- - -
diff --git a/templates/minimal/html/page.html b/templates/minimal/html/page.html deleted file mode 100644 index dbbbb5e..0000000 --- a/templates/minimal/html/page.html +++ /dev/null @@ -1,334 +0,0 @@ - - - -title goes here - - - - - - - - - - - - - - - - - - - - - - - -
  -
-

body title

-
- -
-

-

- - clear this message -

-
Page content goes here
- -
-
- - - -
- - - - - - - - - - - - - - - - (cal) - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    -
  • - -
  • -
  • - - -
  • -
- - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/templates/minimal/html/style.css b/templates/minimal/html/style.css deleted file mode 100644 index f7d7eb4..0000000 --- a/templates/minimal/html/style.css +++ /dev/null @@ -1,423 +0,0 @@ -/* main page styles */ -body.body { - font-family: sans-serif, Arial, Helvetica; - background-color: white; - color: #333; - margin: 0; -} -a[href]:hover { - color:blue; - text-decoration: underline; -} -a[href], a[href]:link { - color:blue; - text-decoration: none; -} - -table.body { - border: 0; - padding: 0; - border-spacing: 0; - border-collapse: separate; -} - -td.page-header-left { - padding: 5px; - border-bottom: 1px solid #444; -} -td.sidebar { - padding: 1px 0 0 1px; - white-space: nowrap; -} - -/* don't display the sidebar when printing */ -@media print { - td.page-header-left { - display: none; - } - td.sidebar { - display: none; - } - .index-controls { - display: none; - } - #searchbox { - display: none; - } -} - -td.page-header-top { - padding: 5px; - border-bottom: 1px solid #444; -} -#searchbox { - float: right; -} - -div#body-title { - float: left; -} - - -div#searchbox { - float: right; - padding-top: 1em; -} - -div#searchbox input#search-text { - width: 10em; -} - -form { - margin: 0; -} - -textarea { - font-family: monospace; -} - -td.sidebar p.classblock { - padding: 2px 5px 2px 5px; - margin: 1px; - border: 1px solid #444; - background-color: #eee; -} - -td.sidebar p.userblock { - padding: 2px 5px 2px 5px; - margin: 1px 1px 1px 1px; - border: 1px solid #444; - background-color: #eef; -} - -.form-small { - padding: 0; - font-size: 75%; -} - - -td.content { - padding: 1px 5px 1px 5px; - vertical-align: top; - width: 100%; -} - -td.date, th.date { - white-space: nowrap; -} - -p.ok-message { - background-color: #22bb22; - padding: 5px; - color: white; - font-weight: bold; -} -p.error-message { - background-color: #bb2222; - padding: 5px; - color: white; - font-weight: bold; -} -p.error-message a[href] { - color: white; - text-decoration: underline; -} - - -/* style for search forms */ -ul.search-checkboxes { - display: inline; - padding: none; - list-style: none; -} -ul.search-checkboxes > li { - display: inline; - padding-right: .5em; -} - - -/* style for forms */ -table.form { - padding: 2px; - border-spacing: 0; - border-collapse: separate; -} - -table.form th { - color: #338; - text-align: right; - vertical-align: top; - font-weight: normal; - white-space: nowrap; -} - -table.form th.header { - font-weight: bold; - background-color: #eef; - text-align: left; -} - -table.form th.required { - font-weight: bold; -} - -table.form td { - color: #333; - empty-cells: show; - vertical-align: top; -} - -table.form td.optional { - font-weight: bold; - font-style: italic; -} - -table.form td.html { - color: #777; -} - -/* style for lists */ -table.list { - border-spacing: 0; - border-collapse: separate; - width: 100%; -} - -table.list th { - padding: 0 4px 0 4px; - color: #404070; - background-color: #eef; - border: 1px solid white; - vertical-align: top; - empty-cells: show; -} -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 4px 0 4px; - border: 1px solid white; - color: #404070; - background-color: #efefef; - vertical-align: top; - empty-cells: show; -} - -table.list tr.navigation th { - width: 33%; - border-style: hidden; - text-align: center; -} -table.list tr.navigation td { - border: none -} -table.list tr.navigation th:first-child { - text-align: left; -} -table.list tr.navigation th:last-child { - text-align: right; -} - - -/* style for message displays */ -table.messages { - border-spacing: 0; - 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; - border-bottom: 1px solid #afafaf; -} - -table.messages td { - font-family: monospace; - background-color: #efefef; - border-bottom: 1px solid #afafaf; - color: black; - empty-cells: show; - border-right: 1px solid #afafaf; - vertical-align: top; - padding: 2px 5px 2px 5px; -} - -table.messages td:first-child { - border-left: 1px solid #afafaf; - border-right: 1px solid #afafaf; -} - -/* style for file displays */ -table.files { - border-spacing: 0; - 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: 0; - 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: 0; - 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 { /* the table-layout: fixed; */ - table-layout: fixed; /* compromises quality for speed */ - overflow: hidden; - font-size: .9em; - padding-bottom: 3em; -} - -table.classhelp th { - font-weight: normal; - text-align: left; - color: #444; - background-color: #efefef; - border-bottom: 1px solid #afafaf; - border-top: 1px solid #afafaf; - text-transform: uppercase; - vertical-align: middle; - line-height:1.5em; -} - -table.classhelp td { - vertical-align: middle; - padding-right: .2em; - border-bottom: 1px solid #efefef; - text-align: left; - empty-cells: show; - white-space: nowrap; - vertical-align: middle; -} - -table.classhelp tr:hover { - background-color: #eee; -} - -label.classhelp-label { - cursor: pointer; -} - -#classhelp-controls { - position: fixed; - display: block; - top: auto; - right: 0; - bottom: 0; - left: 0; - padding: .5em; - border-top: 2px solid #444; - background-color: #eee; -} - -#classhelp-controls input.apply { - width: 7em; - font-weight: bold; - margin-right: 2em; - margin-left: 2em; -} - -#classhelp-controls input.preview { - margin-right: 3em; - margin-left: 1em; -} - -/* style for "other" displays */ -table.otherinfo { - border-spacing: 0; - 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/templates/minimal/html/user.index.html b/templates/minimal/html/user.index.html deleted file mode 100644 index f0a84b8..0000000 --- a/templates/minimal/html/user.index.html +++ /dev/null @@ -1,35 +0,0 @@ - - -User listing - <span - i18n:name="tracker" tal:replace="config/TRACKER_NAME" /> -User listing - - -You are not allowed to view this page. - -Please login with your username and password. - - - - - - - - - - - - -
UsernameEmail address
- username - address
- - -
diff --git a/templates/minimal/html/user.item.html b/templates/minimal/html/user.item.html deleted file mode 100644 index bafccd2..0000000 --- a/templates/minimal/html/user.item.html +++ /dev/null @@ -1,169 +0,0 @@ - - - -<tal:if condition="context/id" i18n:translate="" - >User <tal:x content="context/id" i18n:name="id" - />: <tal:x content="context/username" i18n:name="title" - /> - <tal:x content="config/TRACKER_NAME" i18n:name="tracker" -/></tal:if> -<tal:if condition="not:context/id" i18n:translate="" - >New User - <span tal:replace="config/TRACKER_NAME" i18n:name="tracker" -/></tal:if> - - - - - - - New User - New User Editing - User - User Editing - - - - -

- You are not allowed to view this page.

- -

- Please login with your username and password.

- -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Name
Login Name
Login Password
Confirm Password
- - - - - - - (to give the user more than one role, - enter a comma,separated,list) -
Phone
Organisation
Timezone - (this is a numeric hour offset, the default is - ) -
E-mail address - calvin@the-z.org - - - -   -
- -
-   - - - - -
-
- - - - - - - - -
Note: highlighted fields are required.
-
- - - -
- - - -
diff --git a/templates/minimal/html/user.register.html b/templates/minimal/html/user.register.html deleted file mode 100644 index 7e7a5d3..0000000 --- a/templates/minimal/html/user.register.html +++ /dev/null @@ -1,73 +0,0 @@ - - -Registering with <span i18n:name="tracker" - tal:replace="db/config/TRACKER_NAME" /> -Registering with - - - - -You are not allowed to view this page. - -Please login with your username and password. - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Login Nameusername
Login Passwordpassword
Confirm Passwordpassword
Rolesroles - -
E-mail addressaddress
Alternate E-mail addresses
One address per line
alternate_addresses
  - - -
-
- -
- -
- - - -
diff --git a/templates/minimal/html/user.rego_progress.html b/templates/minimal/html/user.rego_progress.html deleted file mode 100644 index 4d6bfe4..0000000 --- a/templates/minimal/html/user.rego_progress.html +++ /dev/null @@ -1,16 +0,0 @@ - - -Registration in progress - <span i18n:name="tracker" - tal:replace="config/TRACKER_NAME" /> -Registration in progress... - - -

You will shortly receive an email -to confirm your registration. To complete the registration process, -visit the link indicated in the email. -

- - -
diff --git a/templates/minimal/initial_data.py b/templates/minimal/initial_data.py deleted file mode 100644 index 28bfefe..0000000 --- a/templates/minimal/initial_data.py +++ /dev/null @@ -1,14 +0,0 @@ -# -# TRACKER DATABASE INITIALIZATION -# - -# create the two default users -user = db.getclass('user') -user.create(username="admin", password=adminpw, - address=admin_email, roles='Admin') -user.create(username="anonymous", roles='Anonymous') - -# add any additional database creation steps here - but only if you -# haven't initialised the database with the admin "initialise" command - -# vim: set et sts=4 sw=4 : diff --git a/templates/minimal/schema.py b/templates/minimal/schema.py deleted file mode 100644 index 909c9b1..0000000 --- a/templates/minimal/schema.py +++ /dev/null @@ -1,65 +0,0 @@ -# -# TRACKER SCHEMA -# - -# Class automatically gets these properties: -# creation = Date() -# activity = Date() -# creator = Link('user') -# actor = Link('user') - -# 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") -# -# TRACKER SECURITY SETTINGS -# -# See the configuration and customisation document for information -# about security setup. - -# -# REGULAR USERS -# -# Give the regular users access to the web and email interface -db.security.addPermissionToRole('User', 'Web Access') -db.security.addPermissionToRole('User', 'Email Access') - -# May users view other user information? -# Comment these lines out if you don't want them to -db.security.addPermissionToRole('User', 'View', 'user') - -# Users should be able to edit their own details -- this permission is -# limited to only the situation where the Viewed or Edited item is their own. -def own_record(db, userid, itemid): - '''Determine whether the userid matches the item being accessed.''' - return userid == itemid -p = db.security.addPermission(name='View', klass='user', check=own_record, - description="User is allowed to view their own user details") -db.security.addPermissionToRole('User', p) -p = db.security.addPermission(name='Edit', klass='user', check=own_record, - description="User is allowed to edit their own user details") -db.security.addPermissionToRole('User', p) - -# -# ANONYMOUS USER PERMISSIONS -# -# Let anonymous users access the web interface. Note that almost all -# trackers will need this Permission. The only situation where it's not -# required is in a tracker that uses an HTTP Basic Authenticated front-end. -db.security.addPermissionToRole('Anonymous', 'Web Access') - -# Let anonymous users access the email interface (note that this implies -# that they will be registered automatically, hence they will need the -# "Create" user Permission below) -db.security.addPermissionToRole('Anonymous', 'Email Access') - -# Assign the appropriate permissions to the anonymous user's -# Anonymous Role. Choices here are: -# - Allow anonymous users to register -db.security.addPermissionToRole('Anonymous', 'Create', 'user') - -# vim: set et sts=4 sw=4 :