Code

Update customization examples too, expand upgrade notice a bit.
[roundup.git] / doc / upgrading.txt
1 ======================================
2 Upgrading to newer versions of Roundup
3 ======================================
5 Please read each section carefully and edit your tracker home files
6 accordingly. Note that there is information about upgrade procedures in the
7 `administration guide`_.
9 .. contents::
11 Migrating from 0.6 to 0.7
12 =========================
14 0.7.0 Extending the cgi interface
15 ---------------------------------
17 Before 0.7.0 adding or extending web actions was done by overriding or adding
18 methods on the Client class. Though this approach still works to provide
19 backwards compatibility, it is recommended you upgrade to the new approach, as
20 described in the `Defining new web actions`__ section of the customization
21 documentation. You might also want to take a look at the `Using an external
22 password validation source`__ example.
24 __ customizing.html#defining-new-web-actions
25 __ customizing.html#using-an-external-password-validation-source
27 0.7.0 Getting the current user id
28 ---------------------------------
30 Removed Database.curuserid attribute. Any code referencing this attribute
31 should be replaced with a call to Database.getuid().
34 0.7.0 ZRoundup changes
35 ----------------------
37 The templates in your tracker's html directory will need updating if you
38 wish to use ZRoundup. If you've not modified those files (or some of them),
39 you may just copy the new versions from the Roundup source in the
40 templates/classic/html directory.
42 If you have modified the html files, then you'll need to manually edit them
43 to change all occurances of special form variables from using the colon ":"
44 special character to the at "@" special character. That is, variables such
45 as::
47   :action :required :template :remove:messages ...
49 should become:
51   @action @required @template @remove@messages ...
53 Note that ``tal:`` statements are unaffected. So are TAL expression type
54 prefixes such as ``python:`` and ``string:``. Please ask on the
55 roundup-users mailing list for help if you're unsure.
58 Migrating from 0.6.x to 0.6.3
59 =============================
61 0.6.3 Configuration
62 -------------------
64 You will need to copy the file::
66   templates/classic/detectors/__init__.py
68 to your tracker's ``detectors`` directory, replacing the one already there.
69 This fixes a couple of bugs in that file.
73 Migrating from 0.5 to 0.6
74 =========================
77 0.6.0 Configuration
78 -------------------
80 Introduced EMAIL_FROM_TAG config variable. This value is inserted into
81 the From: line of nosy email. If the sending user is "Foo Bar", the
82 From: line is usually::
84      "Foo Bar" <issue_tracker@tracker.example>
86 the EMAIL_FROM_TAG goes inside the "Foo Bar" quotes like so::
88      "Foo Bar EMAIL_FROM_TAG" <issue_tracker@tracker.example>
90 I've altered the mechanism in the detectors __init__.py module so that it
91 doesn't cross-import detectors from other trackers (if you run more than one
92 in a single roundup-server). This change means that you'll need to copy the
93 __init__.py from roundup/templates/classic/detectors/__init__.py to your
94 <tracker home>/detectors/__init__.py. Don't worry, the "classic" __init__ is a
95 one-size-fits-all, so it'll work even if you've added/removed detectors.
97 0.6.0 Templating changes
98 ------------------------
100 The ``user.item`` template (in the tracker home "templates" directory)
101 needs to have the following hidden variable added to its form (between the
102 ``<form...>`` and ``</form>`` tags::
104   <input type="hidden" name=":template" value="item">
107 0.6.0 Form handling changes
108 ---------------------------
110 Roundup's form handling capabilities have been significantly expanded. This
111 should not affect users of 0.5 installations - but if you find you're
112 getting errors from form submissions, please ask for help on the Roundup
113 users mailing list:
115   http://lists.sourceforge.net/lists/listinfo/roundup-users
117 See the customisation doc section on `Form Values`__ for documentation of the
118 new form variables possible.
120 __ customizing.html#form-values
123 0.6.0 Multilingual character set support
124 ----------------------------------------
126 Added internationalization support. This is done via encoding all data
127 stored in roundup database to utf-8 (unicode encoding). To support utf-8 in
128 web interface you should add the folowing line to your tracker's html/page
129 and html/_generic.help files inside <head> tag::
130   
131     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
133 Since latin characters in utf-8 have the same codes as in ASCII table, this
134 modification is optional for users who use only plain latin characters. 
136 After this modification, you will be able to see and enter any world
137 character via web interface. Data received via mail interface also converted
138 to utf-8, however only new messages will be converted. If your roundup
139 database contains some of non-ASCII characters in one of 8-bit encoding,
140 they will not be visible in new unicode environment. Some of such data (e.g.
141 user names, keywords, etc)  can be edited by administrator, the others
142 (e.g. messages' contents) is not editable via web interface. Currently there
143 is no tool for converting such data, the only solution is to close
144 appropriate old issues and create new ones with the same content.
147 0.6.0 User timezone support
148 ---------------------------
150 From version 0.6.0 roundup supports displaying of Date data in user' local
151 timezone if he/she has provided timezone information. To make it possible
152 some modification to tracker's schema and HTML templates are required.
153 First you must add string property 'timezone' to user class in dbinit.py
154 like this::
155   
156     user = Class(db, "user", 
157                     username=String(),   password=Password(),
158                     address=String(),    realname=String(), 
159                     phone=String(),      organisation=String(),
160                     alternate_addresses=String(),
161                     queries=Multilink('query'), roles=String(),
162                     timezone=String())
163   
164 And second - html interface. Add following lines to
165 $TRACKER_HOME/html/user.item template::
166   
167      <tr>
168       <th>Timezone</th>
169       <td tal:content="structure context/timezone/field">timezone</td>
170      </tr>
172 After that all users should be able to provide their timezone information.
173 Timezone should be a positive or negative integer - offset from GMT.
175 After providing timezone, roundup will show all dates values, found in web
176 and mail interfaces in local time. It will also accept any Date info in
177 local time, convert and store it in GMT.
180 0.6.0 Search page structure
181 ---------------------------
183 In order to accomodate query editing the search page has been restructured. If
184 you want to provide your users with query editing, you should update your
185 search page using the macros detailed in the customisation doc section
186 `Searching on categories`__.
188 __ customizing.html#searching-on-categories
190 Also, the url field in the query class no longer starts with a '?'. You'll need
191 to remove this question mark from the url field to support queries. There's
192 a script in the "tools" directory called ``migrate-queries.py`` that should
193 automatically change any existing queries for you. As always, make a backup
194 of your database before running such a script.
197 0.6.0 Notes for metakit backend users
198 -------------------------------------
200 Roundup 0.6.0 introduced searching on ranges of dates and intervals. To
201 support it, some modifications to interval storing routine were made. So if
202 your tracker uses metakit backend and your db schema contains intervals
203 property, searches on that property will not be accurate for db items that
204 was stored before roundup' upgrade. However all new records should be
205 searchable on intervals.
207 It is possible to convert your database to new format: you can export and
208 import back all your data (consult "Migrating backends" in "Maintenance"
209 documentation). After this operation all your interval properties should
210 become searchable.
212 Users of backends others than metakit should not worry about this issue.
215 Migrating from 0.4.x to 0.5.0
216 =============================
218 This has been a fairly major revision of Roundup:
220 1. Brand new, much more powerful, flexible, tasty and nutritious templating.
221    Unfortunately, this means all your current templates are useless. Hopefully
222    the new documentation and examples will be enough to help you make the
223    transition. Please don't hesitate to ask on roundup-users for help (or
224    complete conversions if you're completely stuck)!
225 2. The database backed got a lot more flexible, allowing Metakit and SQL
226    databases! The only decent SQL database implemented at present is sqlite,
227    but others shouldn't be a whole lot more work.
228 3. A brand new, highly flexible and much more robust security system including
229    a system of Permissions, Roles and Role assignments to users. You may now
230    define your own Permissions that may be checked in CGI transactions.
231 4. Journalling has been made less storage-hungry, so has been turned on
232    by default *except* for author, recipient and nosy link/unlink events. You
233    are advised to turn it off in your trackers too.
234 5. We've changed the terminology from "instance" to "tracker", to ease the
235    learning curve/impact for new users.
236 6. Because of the above changes, the tracker configuration has seen some
237    major changes. See below for the details.
239 Please, **back up your database** before you start the migration process. This
240 is as simple as copying the "db" directory and all its contents from your
241 tracker to somewhere safe.
244 0.5.0 Configuration
245 -------------------
247 First up, rename your ``instance_config.py`` file to just ``config.py``.
249 Then edit your tracker's ``__init__.py`` module. It'll currently look
250 like this::
252  from instance_config import *
253  try:
254      from dbinit import *
255  except ImportError:
256      pass # in installdir (probably :)
257  from interfaces import *
259 and it needs to be::
261  import config
262  from dbinit import open, init
263  from interfaces import Client, MailGW
265 Due to the new templating having a top-level ``page`` that defines links for
266 searching, indexes, adding items etc, the following variables are no longer
267 used:
269 - HEADER_INDEX_LINKS
270 - HEADER_ADD_LINKS
271 - HEADER_SEARCH_LINKS
272 - SEARCH_FILTERS
273 - DEFAULT_INDEX
274 - UNASSIGNED_INDEX
275 - USER_INDEX
276 - ISSUE_FILTER
278 The new security implementation will require additions to the dbinit module,
279 but also removes the need for the following tracker config variables:
281 - ANONYMOUS_ACCESS
282 - ANONYMOUS_REGISTER
284 but requires two new variables which define the Roles assigned to users who
285 register through the web and e-mail interfaces:
287 - NEW_WEB_USER_ROLES
288 - NEW_EMAIL_USER_ROLES
290 in both cases, 'User' is a good initial setting. To emulate
291 ``ANONYMOUS_ACCESS='deny'``, remove all "View" Permissions from the
292 "Anonymous" Role. To emulate ``ANONYMOUS_REGISTER='deny'``, remove the "Web
293 Registration" and/or the "Email Registration" Permission from the "Anonymous"
294 Role. See the section on customising security in the `customisation
295 documentation`_ for more information.
297 Finally, the following config variables have been renamed to make more sense:
299 - INSTANCE_HOME -> TRACKER_HOME
300 - INSTANCE_NAME -> TRACKER_NAME
301 - ISSUE_TRACKER_WEB -> TRACKER_WEB
302 - ISSUE_TRACKER_EMAIL -> TRACKER_EMAIL
305 0.5.0 Schema Specification
306 --------------------------
308 0.5.0 Database backend changes
309 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
311 Your select_db module in your tracker has changed a fair bit. Where it used
312 to contain::
314  # WARNING: DO NOT EDIT THIS FILE!!!
315  from roundup.backends.back_anydbm import Database
317 it must now contain::
319  # WARNING: DO NOT EDIT THIS FILE!!!
320  from roundup.backends.back_anydbm import Database, Class, FileClass, IssueClass
322 Yes, I realise the irony of the "DO NOT EDIT THIS FILE" statement :)
323 Note the addition of the Class, FileClass, IssueClass imports. These are very
324 important, as they're going to make the next change work too. You now need to
325 modify the top of the dbinit module in your tracker from::
327  import instance_config
328  from roundup import roundupdb
329  from select_db import Database
331  from roundup.roundupdb import Class, FileClass
333  class Database(roundupdb.Database, select_db.Database):
334      ''' Creates a hybrid database from:
335           . the selected database back-end from select_db
336           . the roundup extensions from roundupdb
337      '''
338      pass
340  class IssueClass(roundupdb.IssueClass):
341      ''' issues need the email information
342      '''
343      pass
345 to::
347  import config
348  from select_db import Database, Class, FileClass, IssueClass
350 Yes, remove the Database and IssueClass definitions and those other imports.
351 They're not needed any more!
353 Look for places in dbinit.py where ``instance_config`` is used too, and
354 rename them ``config``.
357 0.5.0 Journalling changes
358 ~~~~~~~~~~~~~~~~~~~~~~~~~
360 Journalling has been optimised for storage. Journalling of links has been
361 turned back on by default. If your tracker has a large user base, you may wish
362 to turn off journalling of nosy list, message author and message recipient
363 link and unlink events. You do this by adding ``do_journal='no'`` to the Class
364 initialisation in your dbinit. For example, your *msg* class initialisation
365 probably looks like this::
367     msg = FileClass(db, "msg",
368                     author=Link("user"), recipients=Multilink("user"),
369                     date=Date(),         summary=String(),
370                     files=Multilink("file"),
371                     messageid=String(),  inreplyto=String())
373 to turn off journalling of author and recipient link events, add
374 ``do_journal='no'`` to the ``author=Link("user")`` part of the statement,
375 like so::
377     msg = FileClass(db, "msg",
378                     author=Link("user", do_journal='no'),
379                     recipients=Multilink("user", do_journal='no'),
380                     date=Date(),         summary=String(),
381                     files=Multilink("file"),
382                     messageid=String(),  inreplyto=String())
384 Nosy list link event journalling is actually turned off by default now. If you
385 want to turn it on, change to your issue class' nosy list, change its
386 definition from::
388     issue = IssueClass(db, "issue",
389                     assignedto=Link("user"), topic=Multilink("keyword"),
390                     priority=Link("priority"), status=Link("status"))
392 to::
394     issue = IssueClass(db, "issue", nosy=Multilink("user", do_journal='yes'),
395                     assignedto=Link("user"), topic=Multilink("keyword"),
396                     priority=Link("priority"), status=Link("status"))
398 noting that your definition of the nosy Multilink will override the normal one.
401 0.5.0 User schema changes
402 ~~~~~~~~~~~~~~~~~~~~~~~~~
404 Users have two more properties, "queries" and "roles". You'll have something
405 like this in your dbinit module now::
407     user = Class(db, "user",
408                     username=String(),   password=Password(),
409                     address=String(),    realname=String(),
410                     phone=String(),      organisation=String(),
411                     alternate_addresses=String())
412     user.setkey("username")
414 and you'll need to add the new properties and the new "query" class to it
415 like so::
417     query = Class(db, "query",
418                     klass=String(),     name=String(),
419                     url=String())
420     query.setkey("name")
422     # Note: roles is a comma-separated string of Role names
423     user = Class(db, "user",
424                     username=String(),   password=Password(),
425                     address=String(),    realname=String(),
426                     phone=String(),      organisation=String(),
427                     alternate_addresses=String(),
428                     queries=Multilink('query'), roles=String())
429     user.setkey("username")
431 The "queries" property is used to store off the user's favourite database
432 queries. The "roles" property is explained below in `0.5.0 Security
433 Settings`_.
436 0.5.0 Security Settings
437 ~~~~~~~~~~~~~~~~~~~~~~~
439 See the `security documentation`_ for an explanation of how the new security
440 system works. In a nutshell though, the security is handled as a four step
441 process:
443 1. Permissions are defined as having a name and optionally a hyperdb class
444    they're specific to,
445 2. Roles are defined that have one or more Permissions,
446 3. Users are assigned Roles in their "roles" property, and finally
447 4. Roundup checks that users have appropriate Permissions at appropriate times
448    (like editing issues).
450 Your tracker dbinit module's *open* function now has to define any
451 Permissions that are specific to your tracker, and also the assignment
452 of Permissions to Roles. At the moment, your open function
453 ends with::
455     import detectors
456     detectors.init(db)
458     return db
460 and what we need to do is insert some commands that will set up the security
461 parameters. Right above the ``import detectors`` line, you'll want to insert
462 these lines::
464     #
465     # SECURITY SETTINGS
466     #
467     # new permissions for this schema
468     for cl in 'issue', 'file', 'msg', 'user':
469         db.security.addPermission(name="Edit", klass=cl,
470             description="User is allowed to edit "+cl)
471         db.security.addPermission(name="View", klass=cl,
472             description="User is allowed to access "+cl)
474     # Assign the access and edit permissions for issue, file and message
475     # to regular users now
476     for cl in 'issue', 'file', 'msg':
477         p = db.security.getPermission('View', cl)
478         db.security.addPermissionToRole('User', p)
479         p = db.security.getPermission('Edit', cl)
480         db.security.addPermissionToRole('User', p)
481     # and give the regular users access to the web and email interface
482     p = db.security.getPermission('Web Access')
483     db.security.addPermissionToRole('User', p)
484     p = db.security.getPermission('Email Access')
485     db.security.addPermissionToRole('User', p)
487     # May users view other user information? Comment these lines out
488     # if you don't want them to
489     p = db.security.getPermission('View', 'user')
490     db.security.addPermissionToRole('User', p)
492     # Assign the appropriate permissions to the anonymous user's Anonymous
493     # Role. Choices here are:
494     # - Allow anonymous users to register through the web
495     p = db.security.getPermission('Web Registration')
496     db.security.addPermissionToRole('Anonymous', p)
497     # - Allow anonymous (new) users to register through the email gateway
498     p = db.security.getPermission('Email Registration')
499     db.security.addPermissionToRole('Anonymous', p)
500     # - Allow anonymous users access to the "issue" class of data
501     #   Note: this also grants access to related information like files,
502     #         messages, statuses etc that are linked to issues
503     #p = db.security.getPermission('View', 'issue')
504     #db.security.addPermissionToRole('Anonymous', p)
505     # - Allow anonymous users access to edit the "issue" class of data
506     #   Note: this also grants access to create related information like
507     #         files and messages etc that are linked to issues
508     #p = db.security.getPermission('Edit', 'issue')
509     #db.security.addPermissionToRole('Anonymous', p)
511     # oh, g'wan, let anonymous access the web interface too
512     p = db.security.getPermission('Web Access')
513     db.security.addPermissionToRole('Anonymous', p)
515 Note in the comments there the places where you might change the permissions
516 to restrict users or grant users more access. If you've created additional
517 classes that users should be able to edit and view, then you should add them
518 to the "new permissions for this schema" section at the start of the security
519 block. Then add them to the "Assign the access and edit permissions" section
520 too, so people actually have the new Permission you've created.
522 One final change is needed that finishes off the security system's
523 initialisation. We need to add a call to ``db.post_init()`` at the end of the
524 dbinit open() function. Add it like this::
526     import detectors
527     detectors.init(db)
529     # schema is set up - run any post-initialisation
530     db.post_init()
531     return db
533 You may verify the setup of Permissions and Roles using the new
534 "``roundup-admin security``" command.
537 0.5.0 User changes
538 ~~~~~~~~~~~~~~~~~~
540 To support all those schema changes, you'll need to massage your user database
541 a little too, to:
543 1. make sure there's an "anonymous" user - this user is mandatory now and is
544    the one that unknown users are logged in as.
545 2. make sure all users have at least one Role.
547 If you don't have the "anonymous" user, create it now with the command::
549   roundup-admin create user username=anonymous roles=Anonymous
551 making sure the capitalisation is the same as above. Once you've done that,
552 you'll need to set the roles property on all users to a reasonable default.
553 The admin user should get "Admin", the anonymous user "Anonymous"
554 and all other users "User". The ``fixroles.py`` script in the tools directory
555 will do this. Run it like so (where python is your python 2+ binary)::
557   python tools/fixroles.py -i <tracker home> fixroles
561 0.5.0 CGI interface changes
562 ---------------------------
564 The CGI interface code was completely reorganised and largely rewritten. The
565 end result is that this section of your tracker interfaces module will need
566 changing from::
568  from roundup import cgi_client, mailgw
569  from roundup.i18n import _
570  
571  class Client(cgi_client.Client):
572      ''' derives basic CGI implementation from the standard module,
573          with any specific extensions
574      '''
575      pass
577 to::
579  from roundup import mailgw
580  from roundup.cgi import client
581  
582  class Client(client.Client): 
583      ''' derives basic CGI implementation from the standard module,
584          with any specific extensions
585      '''
586      pass
588 You will also need to install the new version of roundup.cgi from the source
589 cgi-bin directory if you're using it.
592 0.5.0 HTML templating
593 ---------------------
595 You'll want to make a backup of your current tracker html directory. You
596 should then copy the html directory from the Roundup source "classic" template
597 and modify it according to your local schema changes.
599 If you need help with the new templating system, please ask questions on the
600 roundup-users mailing list (available through the roundup project page on
601 sourceforge, http://roundup.sf.net/)
604 0.5.0 Detectors
605 ---------------
607 The nosy reactor has been updated to handle the tracker not having an
608 "assignedto" property on issues. You may want to copy it into your tracker's
609 detectors directory. Chances are you've already fixed it though :)
612 Migrating from 0.4.1 to 0.4.2
613 =============================
615 0.4.2 Configuration
616 -------------------
617 The USER_INDEX definition introduced in 0.4.1 was too restrictive in its
618 allowing replacement of 'assignedto' with the user's userid. Users must change
619 the None value of 'assignedto' to 'CURRENT USER' (the string, in quotes) for
620 the replacement behaviour to occur now.
622 The new configuration variables are:
624 - EMAIL_KEEP_QUOTED_TEXT 
625 - EMAIL_LEAVE_BODY_UNCHANGED
626 - ADD_RECIPIENTS_TO_NOSY
628 See the sample configuration files in::
630  <roundup source>/roundup/templates/classic/instance_config.py
632 and::
634  <roundup source>/roundup/templates/extended/instance_config.py
636 and the `customisation documentation`_ for information on how they're used.
639 0.4.2 Changes to detectors
640 --------------------------
641 You will need to copy the detectors from the distribution into your instance
642 home "detectors" directory. If you used the classic schema, the detectors
643 are in::
645  <roundup source>/roundup/templates/classic/detectors/
647 If you used the extended schema, the detectors are in::
649  <roundup source>/roundup/templates/extended/detectors/
651 The change means that schema-specific code has been removed from the
652 mail gateway and cgi interface and made into auditors:
654 - nosyreactor.py has now got an updatenosy auditor which updates the nosy
655   list with author, recipient and assignedto information.
656 - statusauditor.py makes the unread or resolved -> chatting changes and
657   presets the status of an issue to unread.
659 There's also a bug or two fixed in the nosyreactor code.
661 0.4.2 HTML templating changes
662 -----------------------------
663 The link() htmltemplate function now has a "showid" option for links and
664 multilinks. When true, it only displays the linked item id as the anchor
665 text. The link value is displayed as a tooltip using the title anchor
666 attribute. To use in eg. the superseder field, have something like this::
668    <td>
669     <display call="field('superseder', showid=1)">
670     <display call="classhelp('issue', 'id,title', label='list', width=500)">
671     <property name="superseder">
672      <br>View: <display call="link('superseder', showid=1)">
673     </property>
674    </td>
676 The stylesheets have been cleaned up too. You may want to use the newer
677 versions in::
679  <roundup source>/roundup/templates/<template>/html/default.css
683 Migrating from 0.4.0 to 0.4.1
684 =============================
686 0.4.1 Files storage
687 -------------------
689 Messages and files from newly created issues will be put into subdierectories
690 in thousands e.g. msg123 will be put into files/msg/0/msg123, file2003
691 will go into files/file/2/file2003. Previous messages are still found, but
692 could be put into this structure.
694 0.4.1 Configuration
695 -------------------
697 To allow more fine-grained access control, the variable used to check
698 permission to auto-register users in the mail gateway is now called
699 ANONYMOUS_REGISTER_MAIL rather than overloading ANONYMOUS_REGISTER. If the
700 variable doesn't exist, then ANONYMOUS_REGISTER is tested as before.
702 Configuring the links in the web header is now easier too. The following
703 variables have been added to the classic instance_config.py::
705   HEADER_INDEX_LINKS   - defines the "index" links to be made available
706   HEADER_ADD_LINKS     - defines the "add" links
707   DEFAULT_INDEX        - specifies the index view for DEFAULT
708   UNASSIGNED_INDEX     - specifies the index view for UNASSIGNED
709   USER_INDEX           - specifies the index view for USER
711 See the <roundup source>/roundup/templates/classic/instance_config.py for more
712 information - including how the variables are to be set up. Most users will
713 just be able to copy the variables from the source to their instance home. If
714 you've modified the header by changing the source of the interfaces.py file in
715 the instance home, you'll need to remove that customisation and move it into
716 the appropriate variables in instance_config.py.
718 The extended schema has similar variables added too - see the source for more
719 info.
721 0.4.1 Alternate E-Mail Addresses
722 --------------------------------
724 If you add the property "alternate_addresses" to your user class, your users
725 will be able to register alternate email addresses that they may use to
726 communicate with roundup as. All email from roundup will continue to be sent
727 to their primary address.
729 If you have not edited the dbinit.py file in your instance home directory,
730 you may simply copy the new dbinit.py file from the core code. If you used
731 the classic schema, the interfaces file is in::
733  <roundup source>/roundup/templates/classic/dbinit.py
735 If you used the extended schema, the file is in::
737  <roundup source>/roundup/templates/extended/dbinit.py 
739 If you have modified your dbinit.py file, you need to edit the dbinit.py
740 file in your instance home directory. Find the lines which define the user
741 class::
743     user = Class(db, "msg",
744                     username=String(),   password=Password(),
745                     address=String(),    realname=String(), 
746                     phone=String(),      organisation=String(),
747                     alternate_addresses=String())
749 You will also want to add the property to the user's details page. The
750 template for this is the "user.item" file in your instance home "html"
751 directory. Similar to above, you may copy the file from the roundup source if
752 you haven't modified it. Otherwise, add the following to the template::
754    <display call="multiline('alternate_addresses')">
756 with appropriate labelling etc. See the standard template for an idea.
760 Migrating from 0.3.x to 0.4.0
761 =============================
763 0.4.0 Message-ID and In-Reply-To addition
764 -----------------------------------------
765 0.4.0 adds the tracking of messages by message-id and allows threading
766 using in-reply-to. Most e-mail clients support threading using this
767 feature, and we hope to add support for it to the web gateway. If you
768 have not edited the dbinit.py file in your instance home directory, you may
769 simply copy the new dbinit.py file from the core code. If you used the
770 classic schema, the interfaces file is in::
772  <roundup source>/roundup/templates/classic/dbinit.py
774 If you used the extended schema, the file is in::
776  <roundup source>/roundup/templates/extended/dbinit.py 
778 If you have modified your dbinit.py file, you need to edit the dbinit.py
779 file in your instance home directory. Find the lines which define the msg
780 class::
782     msg = FileClass(db, "msg",
783                     author=Link("user"), recipients=Multilink("user"),
784                     date=Date(),         summary=String(),
785                     files=Multilink("file"))
787 and add the messageid and inreplyto properties like so::
789     msg = FileClass(db, "msg",
790                     author=Link("user"), recipients=Multilink("user"),
791                     date=Date(),         summary=String(),
792                     files=Multilink("file"),
793                     messageid=String(),  inreplyto=String())
795 Also, configuration is being cleaned up. This means that your dbinit.py will
796 also need to be changed in the open function. If you haven't changed your
797 dbinit.py, the above copy will be enough. If you have, you'll need to change
798 the line (round line 50)::
800     db = Database(instance_config.DATABASE, name)
802 to::
804     db = Database(instance_config, name)
807 0.4.0 Configuration
808 --------------------
809 ``TRACKER_NAME`` and ``EMAIL_SIGNATURE_POSITION`` have been added to the
810 instance_config.py. The simplest solution is to copy the default values
811 from template in the core source.
813 The mail gateway now checks ``ANONYMOUS_REGISTER`` to see if unknown users
814 are to be automatically registered with the tracker. If it is set to "deny"
815 then unknown users will not have access. If it is set to "allow" they will be
816 automatically registered with the tracker.
819 0.4.0 CGI script roundup.cgi
820 ----------------------------
821 The CGI script has been updated with some features and a bugfix, so you should
822 copy it from the roundup cgi-bin source directory again. Make sure you update
823 the ROUNDUP_INSTANCE_HOMES after the copy.
826 0.4.0 Nosy reactor
827 ------------------
828 The nosy reactor has also changed - copy the nosyreactor.py file from the core
829 source::
831    <roundup source>/roundup/templates/<template>/detectors/nosyreactor.py
833 to your instance home "detectors" directory.
836 0.4.0 HTML templating
837 ---------------------
838 The field() function was incorrectly implemented - links and multilinks now
839 display as text fields when rendered using field(). To display a menu (drop-
840 down or select box) you need to use the menu() function.
844 Migrating from 0.2.x to 0.3.x
845 =============================
847 0.3.x Cookie Authentication changes
848 -----------------------------------
849 0.3.0 introduces cookie authentication - you will need to copy the
850 interfaces.py file from the roundup source to your instance home to enable
851 authentication. If you used the classic schema, the interfaces file is in::
853  <roundup source>/roundup/templates/classic/interfaces.py
855 If you used the extended schema, the file is in::
857  <roundup source>/roundup/templates/extended/interfaces.py
859 If you have modified your interfaces.Client class, you will need to take
860 note of the login/logout functionality provided in roundup.cgi_client.Client
861 (classic schema) or roundup.cgi_client.ExtendedClient (extended schema) and
862 modify your instance code apropriately.
865 0.3.x Password encoding
866 -----------------------
867 This release also introduces encoding of passwords in the database. If you
868 have not edited the dbinit.py file in your instance home directory, you may
869 simply copy the new dbinit.py file from the core code. If you used the
870 classic schema, the interfaces file is in::
872  <roundup source>/roundup/templates/classic/dbinit.py
874 If you used the extended schema, the file is in::
876  <roundup source>/roundup/templates/extended/dbinit.py
879 If you have modified your dbinit.py file, you may use encoded passwords:
881 1. Edit the dbinit.py file in your instance home directory
882    a. At the first code line of the open() function::
884        from roundup.hyperdb import String, Date, Link, Multilink
886       alter to include Password, as so::
888        from roundup.hyperdb import String, Password, Date, Link, Multilink
890    b. Where the password property is defined (around line 66)::
892        user = Class(db, "user", 
893                        username=String(),   password=String(),
894                        address=String(),    realname=String(), 
895                        phone=String(),      organisation=String())
896        user.setkey("username")
898       alter the "password=String()" to "password=Password()"::
900        user = Class(db, "user", 
901                        username=String(),   password=Password(),
902                        address=String(),    realname=String(), 
903                        phone=String(),      organisation=String())
904        user.setkey("username")
906 2. Any existing passwords in the database will remain cleartext until they
907    are edited. It is recommended that at a minimum the admin password be
908    changed immediately::
910       roundup-admin -i <instance home> set user1 password=<new password>
913 0.3.x Configuration
914 -------------------
915 FILTER_POSITION, ANONYMOUS_ACCESS, ANONYMOUS_REGISTER have been added to
916 the instance_config.py. Simplest solution is to copy the default values from
917 template in the core source.
919 MESSAGES_TO_AUTHOR has been added to the IssueClass in dbinit.py. Set to 'yes'
920 to send nosy messages to the author. Default behaviour is to not send nosy
921 messages to the author. You will need to add MESSAGES_TO_AUTHOR to your
922 dbinit.py in your instance home.
925 0.3.x CGI script roundup.cgi
926 ----------------------------
927 There have been some structural changes to the roundup.cgi script - you will
928 need to install it again from the cgi-bin directory of the source
929 distribution. Make sure you update the ROUNDUP_INSTANCE_HOMES after the
930 copy.
933 .. _`customisation documentation`: customizing.html
934 .. _`security documentation`: security.html
935 .. _`administration guide`: admin.html