Code

merge from maint branch
[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.
8 .. contents::
10 Migrating from 0.6 to 0.7
11 =========================
13 0.7.0 Getting the current user id
14 ---------------------------------
16 Removed Database.curuserid attribute. Any code referencing this attribute should
17 be replaced with a call to Database.getuid().
21 Migrating from 0.6.x to 0.6.3
22 =============================
24 0.6.3 Configuration
25 -------------------
27 You will need to copy the file::
29   templates/classic/detectors/__init__.py
31 to your tracker's ``detectors`` directory, replacing the one already there.
32 This fixes a couple of bugs in that file.
36 Migrating from 0.5 to 0.6
37 =========================
40 0.6.0 Configuration
41 -------------------
43 Introduced EMAIL_FROM_TAG config variable. This value is inserted into
44 the From: line of nosy email. If the sending user is "Foo Bar", the
45 From: line is usually::
47      "Foo Bar" <issue_tracker@tracker.example>
49 the EMAIL_FROM_TAG goes inside the "Foo Bar" quotes like so::
51      "Foo Bar EMAIL_FROM_TAG" <issue_tracker@tracker.example>
53 I've altered the mechanism in the detectors __init__.py module so that it
54 doesn't cross-import detectors from other trackers (if you run more than one
55 in a single roundup-server). This change means that you'll need to copy the
56 __init__.py from roundup/templates/classic/detectors/__init__.py to your
57 <tracker home>/detectors/__init__.py. Don't worry, the "classic" __init__ is a
58 one-size-fits-all, so it'll work even if you've added/removed detectors.
60 0.6.0 Templating changes
61 ------------------------
63 The ``user.item`` template (in the tracker home "templates" directory)
64 needs to have the following hidden variable added to its form (between the
65 ``<form...>`` and ``</form>`` tags::
67   <input type="hidden" name=":template" value="item">
70 0.6.0 Form handling changes
71 ---------------------------
73 Roundup's form handling capabilities have been significantly expanded. This
74 should not affect users of 0.5 installations - but if you find you're
75 getting errors from form submissions, please ask for help on the Roundup
76 users mailing list:
78   http://lists.sourceforge.net/lists/listinfo/roundup-users
80 See the customisation doc section on `Form Values`__ for documentation of the
81 new form variables possible.
83 __ customizing.html#form-values
86 0.6.0 Multilingual character set support
87 ----------------------------------------
89 Added internationalization support. This is done via encoding all data
90 stored in roundup database to utf-8 (unicode encoding). To support utf-8 in
91 web interface you should add the folowing line to your tracker's html/page
92 and html/_generic.help files inside <head> tag::
93   
94     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
96 Since latin characters in utf-8 have the same codes as in ASCII table, this
97 modification is optional for users who use only plain latin characters. 
99 After this modification, you will be able to see and enter any world
100 character via web interface. Data received via mail interface also converted
101 to utf-8, however only new messages will be converted. If your roundup
102 database contains some of non-ASCII characters in one of 8-bit encoding,
103 they will not be visible in new unicode environment. Some of such data (e.g.
104 user names, keywords, etc)  can be edited by administrator, the others
105 (e.g. messages' contents) is not editable via web interface. Currently there
106 is no tool for converting such data, the only solution is to close
107 appropriate old issues and create new ones with the same content.
110 0.6.0 User timezone support
111 ---------------------------
113 From version 0.6.0 roundup supports displaying of Date data in user' local
114 timezone if he/she has provided timezone information. To make it possible
115 some modification to tracker's schema and HTML templates are required.
116 First you must add string property 'timezone' to user class in dbinit.py
117 like this::
118   
119     user = Class(db, "user", 
120                     username=String(),   password=Password(),
121                     address=String(),    realname=String(), 
122                     phone=String(),      organisation=String(),
123                     alternate_addresses=String(),
124                     queries=Multilink('query'), roles=String(),
125                     timezone=String())
126   
127 And second - html interface. Add following lines to
128 $TRACKER_HOME/html/user.item template::
129   
130      <tr>
131       <th>Timezone</th>
132       <td tal:content="structure context/timezone/field">timezone</td>
133      </tr>
135 After that all users should be able to provide their timezone information.
136 Timezone should be a positive or negative integer - offset from GMT.
138 After providing timezone, roundup will show all dates values, found in web
139 and mail interfaces in local time. It will also accept any Date info in
140 local time, convert and store it in GMT.
143 0.6.0 Search page structure
144 ---------------------------
146 In order to accomodate query editing the search page has been restructured. If
147 you want to provide your users with query editing, you should update your
148 search page using the macros detailed in the customisation doc section
149 `Searching on categories`__.
151 __ customizing.html#searching-on-categories
153 Also, the url field in the query class no longer starts with a '?'. You'll need
154 to remove this question mark from the url field to support queries.
157 0.6.0 Notes for metakit backend users
158 -------------------------------------
160 Roundup 0.6.0 introduced searching on ranges of dates and intervals. To
161 support it, some modifications to interval storing routine were made. So if
162 your tracker uses metakit backend and your db schema contains intervals
163 property, searches on that property will not be accurate for db items that
164 was stored before roundup' upgrade. However all new records should be
165 searchable on intervals.
167 It is possible to convert your database to new format: you can export and
168 import back all your data (consult "Migrating backends" in "Maintenance"
169 documentation). After this operation all your interval properties should
170 become searchable.
172 Users of backends others than metakit should not worry about this issue.
175 Migrating from 0.4.x to 0.5.0
176 =============================
178 This has been a fairly major revision of Roundup:
180 1. Brand new, much more powerful, flexible, tasty and nutritious templating.
181    Unfortunately, this means all your current templates are useless. Hopefully
182    the new documentation and examples will be enough to help you make the
183    transition. Please don't hesitate to ask on roundup-users for help (or
184    complete conversions if you're completely stuck)!
185 2. The database backed got a lot more flexible, allowing Metakit and SQL
186    databases! The only decent SQL database implemented at present is sqlite,
187    but others shouldn't be a whole lot more work.
188 3. A brand new, highly flexible and much more robust security system including
189    a system of Permissions, Roles and Role assignments to users. You may now
190    define your own Permissions that may be checked in CGI transactions.
191 4. Journalling has been made less storage-hungry, so has been turned on
192    by default *except* for author, recipient and nosy link/unlink events. You
193    are advised to turn it off in your trackers too.
194 5. We've changed the terminology from "instance" to "tracker", to ease the
195    learning curve/impact for new users.
196 6. Because of the above changes, the tracker configuration has seen some
197    major changes. See below for the details.
199 Please, **back up your database** before you start the migration process. This
200 is as simple as copying the "db" directory and all its contents from your
201 tracker to somewhere safe.
204 0.5.0 Configuration
205 -------------------
207 First up, rename your ``instance_config.py`` file to just ``config.py``.
209 Then edit your tracker's ``__init__.py`` module. It'll currently look
210 like this::
212  from instance_config import *
213  try:
214      from dbinit import *
215  except ImportError:
216      pass # in installdir (probably :)
217  from interfaces import *
219 and it needs to be::
221  import config
222  from dbinit import open, init
223  from interfaces import Client, MailGW
225 Due to the new templating having a top-level ``page`` that defines links for
226 searching, indexes, adding items etc, the following variables are no longer
227 used:
229 - HEADER_INDEX_LINKS
230 - HEADER_ADD_LINKS
231 - HEADER_SEARCH_LINKS
232 - SEARCH_FILTERS
233 - DEFAULT_INDEX
234 - UNASSIGNED_INDEX
235 - USER_INDEX
236 - ISSUE_FILTER
238 The new security implementation will require additions to the dbinit module,
239 but also removes the need for the following tracker config variables:
241 - ANONYMOUS_ACCESS
242 - ANONYMOUS_REGISTER
244 but requires two new variables which define the Roles assigned to users who
245 register through the web and e-mail interfaces:
247 - NEW_WEB_USER_ROLES
248 - NEW_EMAIL_USER_ROLES
250 in both cases, 'User' is a good initial setting. To emulate
251 ``ANONYMOUS_ACCESS='deny'``, remove all "View" Permissions from the
252 "Anonymous" Role. To emulate ``ANONYMOUS_REGISTER='deny'``, remove the "Web
253 Registration" and/or the "Email Registration" Permission from the "Anonymous"
254 Role. See the section on customising security in the `customisation
255 documentation`_ for more information.
257 Finally, the following config variables have been renamed to make more sense:
259 - INSTANCE_HOME -> TRACKER_HOME
260 - INSTANCE_NAME -> TRACKER_NAME
261 - ISSUE_TRACKER_WEB -> TRACKER_WEB
262 - ISSUE_TRACKER_EMAIL -> TRACKER_EMAIL
265 0.5.0 Schema Specification
266 --------------------------
268 0.5.0 Database backend changes
269 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
271 Your select_db module in your tracker has changed a fair bit. Where it used
272 to contain::
274  # WARNING: DO NOT EDIT THIS FILE!!!
275  from roundup.backends.back_anydbm import Database
277 it must now contain::
279  # WARNING: DO NOT EDIT THIS FILE!!!
280  from roundup.backends.back_anydbm import Database, Class, FileClass, IssueClass
282 Yes, I realise the irony of the "DO NOT EDIT THIS FILE" statement :)
283 Note the addition of the Class, FileClass, IssueClass imports. These are very
284 important, as they're going to make the next change work too. You now need to
285 modify the top of the dbinit module in your tracker from::
287  import instance_config
288  from roundup import roundupdb
289  from select_db import Database
291  from roundup.roundupdb import Class, FileClass
293  class Database(roundupdb.Database, select_db.Database):
294      ''' Creates a hybrid database from:
295           . the selected database back-end from select_db
296           . the roundup extensions from roundupdb
297      '''
298      pass
300  class IssueClass(roundupdb.IssueClass):
301      ''' issues need the email information
302      '''
303      pass
305 to::
307  import config
308  from select_db import Database, Class, FileClass, IssueClass
310 Yes, remove the Database and IssueClass definitions and those other imports.
311 They're not needed any more!
313 Look for places in dbinit.py where ``instance_config`` is used too, and
314 rename them ``config``.
317 0.5.0 Journalling changes
318 ~~~~~~~~~~~~~~~~~~~~~~~~~
320 Journalling has been optimised for storage. Journalling of links has been
321 turned back on by default. If your tracker has a large user base, you may wish
322 to turn off journalling of nosy list, message author and message recipient
323 link and unlink events. You do this by adding ``do_journal='no'`` to the Class
324 initialisation in your dbinit. For example, your *msg* class initialisation
325 probably looks like this::
327     msg = FileClass(db, "msg",
328                     author=Link("user"), recipients=Multilink("user"),
329                     date=Date(),         summary=String(),
330                     files=Multilink("file"),
331                     messageid=String(),  inreplyto=String())
333 to turn off journalling of author and recipient link events, add
334 ``do_journal='no'`` to the ``author=Link("user")`` part of the statement,
335 like so::
337     msg = FileClass(db, "msg",
338                     author=Link("user", do_journal='no'),
339                     recipients=Multilink("user", do_journal='no'),
340                     date=Date(),         summary=String(),
341                     files=Multilink("file"),
342                     messageid=String(),  inreplyto=String())
344 Nosy list link event journalling is actually turned off by default now. If you
345 want to turn it on, change to your issue class' nosy list, change its
346 definition from::
348     issue = IssueClass(db, "issue",
349                     assignedto=Link("user"), topic=Multilink("keyword"),
350                     priority=Link("priority"), status=Link("status"))
352 to::
354     issue = IssueClass(db, "issue", nosy=Multilink("user", do_journal='yes'),
355                     assignedto=Link("user"), topic=Multilink("keyword"),
356                     priority=Link("priority"), status=Link("status"))
358 noting that your definition of the nosy Multilink will override the normal one.
361 0.5.0 User schema changes
362 ~~~~~~~~~~~~~~~~~~~~~~~~~
364 Users have two more properties, "queries" and "roles". You'll have something
365 like this in your dbinit module now::
367     user = Class(db, "user",
368                     username=String(),   password=Password(),
369                     address=String(),    realname=String(),
370                     phone=String(),      organisation=String(),
371                     alternate_addresses=String())
372     user.setkey("username")
374 and you'll need to add the new properties and the new "query" class to it
375 like so::
377     query = Class(db, "query",
378                     klass=String(),     name=String(),
379                     url=String())
380     query.setkey("name")
382     # Note: roles is a comma-separated string of Role names
383     user = Class(db, "user",
384                     username=String(),   password=Password(),
385                     address=String(),    realname=String(),
386                     phone=String(),      organisation=String(),
387                     alternate_addresses=String(),
388                     queries=Multilink('query'), roles=String())
389     user.setkey("username")
391 The "queries" property is used to store off the user's favourite database
392 queries. The "roles" property is explained below in `0.5.0 Security
393 Settings`_.
396 0.5.0 Security Settings
397 ~~~~~~~~~~~~~~~~~~~~~~~
399 See the `security documentation`_ for an explanation of how the new security
400 system works. In a nutshell though, the security is handled as a four step
401 process:
403 1. Permissions are defined as having a name and optionally a hyperdb class
404    they're specific to,
405 2. Roles are defined that have one or more Permissions,
406 3. Users are assigned Roles in their "roles" property, and finally
407 4. Roundup checks that users have appropriate Permissions at appropriate times
408    (like editing issues).
410 Your tracker dbinit module's *open* function now has to define any
411 Permissions that are specific to your tracker, and also the assignment
412 of Permissions to Roles. At the moment, your open function
413 ends with::
415     import detectors
416     detectors.init(db)
418     return db
420 and what we need to do is insert some commands that will set up the security
421 parameters. Right above the ``import detectors`` line, you'll want to insert
422 these lines::
424     #
425     # SECURITY SETTINGS
426     #
427     # new permissions for this schema
428     for cl in 'issue', 'file', 'msg', 'user':
429         db.security.addPermission(name="Edit", klass=cl,
430             description="User is allowed to edit "+cl)
431         db.security.addPermission(name="View", klass=cl,
432             description="User is allowed to access "+cl)
434     # Assign the access and edit permissions for issue, file and message
435     # to regular users now
436     for cl in 'issue', 'file', 'msg':
437         p = db.security.getPermission('View', cl)
438         db.security.addPermissionToRole('User', p)
439         p = db.security.getPermission('Edit', cl)
440         db.security.addPermissionToRole('User', p)
441     # and give the regular users access to the web and email interface
442     p = db.security.getPermission('Web Access')
443     db.security.addPermissionToRole('User', p)
444     p = db.security.getPermission('Email Access')
445     db.security.addPermissionToRole('User', p)
447     # May users view other user information? Comment these lines out
448     # if you don't want them to
449     p = db.security.getPermission('View', 'user')
450     db.security.addPermissionToRole('User', p)
452     # Assign the appropriate permissions to the anonymous user's Anonymous
453     # Role. Choices here are:
454     # - Allow anonymous users to register through the web
455     p = db.security.getPermission('Web Registration')
456     db.security.addPermissionToRole('Anonymous', p)
457     # - Allow anonymous (new) users to register through the email gateway
458     p = db.security.getPermission('Email Registration')
459     db.security.addPermissionToRole('Anonymous', p)
460     # - Allow anonymous users access to the "issue" class of data
461     #   Note: this also grants access to related information like files,
462     #         messages, statuses etc that are linked to issues
463     #p = db.security.getPermission('View', 'issue')
464     #db.security.addPermissionToRole('Anonymous', p)
465     # - Allow anonymous users access to edit the "issue" class of data
466     #   Note: this also grants access to create related information like
467     #         files and messages etc that are linked to issues
468     #p = db.security.getPermission('Edit', 'issue')
469     #db.security.addPermissionToRole('Anonymous', p)
471     # oh, g'wan, let anonymous access the web interface too
472     p = db.security.getPermission('Web Access')
473     db.security.addPermissionToRole('Anonymous', p)
475 Note in the comments there the places where you might change the permissions
476 to restrict users or grant users more access. If you've created additional
477 classes that users should be able to edit and view, then you should add them
478 to the "new permissions for this schema" section at the start of the security
479 block. Then add them to the "Assign the access and edit permissions" section
480 too, so people actually have the new Permission you've created.
482 One final change is needed that finishes off the security system's
483 initialisation. We need to add a call to ``db.post_init()`` at the end of the
484 dbinit open() function. Add it like this::
486     import detectors
487     detectors.init(db)
489     # schema is set up - run any post-initialisation
490     db.post_init()
491     return db
493 You may verify the setup of Permissions and Roles using the new
494 "``roundup-admin security``" command.
497 0.5.0 User changes
498 ~~~~~~~~~~~~~~~~~~
500 To support all those schema changes, you'll need to massage your user database
501 a little too, to:
503 1. make sure there's an "anonymous" user - this user is mandatory now and is
504    the one that unknown users are logged in as.
505 2. make sure all users have at least one Role.
507 If you don't have the "anonymous" user, create it now with the command::
509   roundup-admin create user username=anonymous roles=Anonymous
511 making sure the capitalisation is the same as above. Once you've done that,
512 you'll need to set the roles property on all users to a reasonable default.
513 The admin user should get "Admin", the anonymous user "Anonymous"
514 and all other users "User". The ``fixroles.py`` script in the tools directory
515 will do this. Run it like so (where python is your python 2+ binary)::
517   python tools/fixroles.py -i <tracker home> fixroles
521 0.5.0 CGI interface changes
522 ---------------------------
524 The CGI interface code was completely reorganised and largely rewritten. The
525 end result is that this section of your tracker interfaces module will need
526 changing from::
528  from roundup import cgi_client, mailgw
529  from roundup.i18n import _
530  
531  class Client(cgi_client.Client):
532      ''' derives basic CGI implementation from the standard module,
533          with any specific extensions
534      '''
535      pass
537 to::
539  from roundup import mailgw
540  from roundup.cgi import client
541  
542  class Client(client.Client): 
543      ''' derives basic CGI implementation from the standard module,
544          with any specific extensions
545      '''
546      pass
548 You will also need to install the new version of roundup.cgi from the source
549 cgi-bin directory if you're using it.
552 0.5.0 HTML templating
553 ---------------------
555 You'll want to make a backup of your current tracker html directory. You
556 should then copy the html directory from the Roundup source "classic" template
557 and modify it according to your local schema changes.
559 If you need help with the new templating system, please ask questions on the
560 roundup-users mailing list (available through the roundup project page on
561 sourceforge, http://roundup.sf.net/)
564 0.5.0 Detectors
565 ---------------
567 The nosy reactor has been updated to handle the tracker not having an
568 "assignedto" property on issues. You may want to copy it into your tracker's
569 detectors directory. Chances are you've already fixed it though :)
572 Migrating from 0.4.1 to 0.4.2
573 =============================
575 0.4.2 Configuration
576 -------------------
577 The USER_INDEX definition introduced in 0.4.1 was too restrictive in its
578 allowing replacement of 'assignedto' with the user's userid. Users must change
579 the None value of 'assignedto' to 'CURRENT USER' (the string, in quotes) for
580 the replacement behaviour to occur now.
582 The new configuration variables are:
584 - EMAIL_KEEP_QUOTED_TEXT 
585 - EMAIL_LEAVE_BODY_UNCHANGED
586 - ADD_RECIPIENTS_TO_NOSY
588 See the sample configuration files in::
590  <roundup source>/roundup/templates/classic/instance_config.py
592 and::
594  <roundup source>/roundup/templates/extended/instance_config.py
596 and the `customisation documentation`_ for information on how they're used.
599 0.4.2 Changes to detectors
600 --------------------------
601 You will need to copy the detectors from the distribution into your instance
602 home "detectors" directory. If you used the classic schema, the detectors
603 are in::
605  <roundup source>/roundup/templates/classic/detectors/
607 If you used the extended schema, the detectors are in::
609  <roundup source>/roundup/templates/extended/detectors/
611 The change means that schema-specific code has been removed from the
612 mail gateway and cgi interface and made into auditors:
614 - nosyreactor.py has now got an updatenosy auditor which updates the nosy
615   list with author, recipient and assignedto information.
616 - statusauditor.py makes the unread or resolved -> chatting changes and
617   presets the status of an issue to unread.
619 There's also a bug or two fixed in the nosyreactor code.
621 0.4.2 HTML templating changes
622 -----------------------------
623 The link() htmltemplate function now has a "showid" option for links and
624 multilinks. When true, it only displays the linked item id as the anchor
625 text. The link value is displayed as a tooltip using the title anchor
626 attribute. To use in eg. the superseder field, have something like this::
628    <td>
629     <display call="field('superseder', showid=1)">
630     <display call="classhelp('issue', 'id,title', label='list', width=500)">
631     <property name="superseder">
632      <br>View: <display call="link('superseder', showid=1)">
633     </property>
634    </td>
636 The stylesheets have been cleaned up too. You may want to use the newer
637 versions in::
639  <roundup source>/roundup/templates/<template>/html/default.css
643 Migrating from 0.4.0 to 0.4.1
644 =============================
646 0.4.1 Files storage
647 -------------------
649 Messages and files from newly created issues will be put into subdierectories
650 in thousands e.g. msg123 will be put into files/msg/0/msg123, file2003
651 will go into files/file/2/file2003. Previous messages are still found, but
652 could be put into this structure.
654 0.4.1 Configuration
655 -------------------
657 To allow more fine-grained access control, the variable used to check
658 permission to auto-register users in the mail gateway is now called
659 ANONYMOUS_REGISTER_MAIL rather than overloading ANONYMOUS_REGISTER. If the
660 variable doesn't exist, then ANONYMOUS_REGISTER is tested as before.
662 Configuring the links in the web header is now easier too. The following
663 variables have been added to the classic instance_config.py::
665   HEADER_INDEX_LINKS   - defines the "index" links to be made available
666   HEADER_ADD_LINKS     - defines the "add" links
667   DEFAULT_INDEX        - specifies the index view for DEFAULT
668   UNASSIGNED_INDEX     - specifies the index view for UNASSIGNED
669   USER_INDEX           - specifies the index view for USER
671 See the <roundup source>/roundup/templates/classic/instance_config.py for more
672 information - including how the variables are to be set up. Most users will
673 just be able to copy the variables from the source to their instance home. If
674 you've modified the header by changing the source of the interfaces.py file in
675 the instance home, you'll need to remove that customisation and move it into
676 the appropriate variables in instance_config.py.
678 The extended schema has similar variables added too - see the source for more
679 info.
681 0.4.1 Alternate E-Mail Addresses
682 --------------------------------
684 If you add the property "alternate_addresses" to your user class, your users
685 will be able to register alternate email addresses that they may use to
686 communicate with roundup as. All email from roundup will continue to be sent
687 to their primary address.
689 If you have not edited the dbinit.py file in your instance home directory,
690 you may simply copy the new dbinit.py file from the core code. If you used
691 the classic schema, the interfaces file is in::
693  <roundup source>/roundup/templates/classic/dbinit.py
695 If you used the extended schema, the file is in::
697  <roundup source>/roundup/templates/extended/dbinit.py 
699 If you have modified your dbinit.py file, you need to edit the dbinit.py
700 file in your instance home directory. Find the lines which define the user
701 class::
703     user = Class(db, "msg",
704                     username=String(),   password=Password(),
705                     address=String(),    realname=String(), 
706                     phone=String(),      organisation=String(),
707                     alternate_addresses=String())
709 You will also want to add the property to the user's details page. The
710 template for this is the "user.item" file in your instance home "html"
711 directory. Similar to above, you may copy the file from the roundup source if
712 you haven't modified it. Otherwise, add the following to the template::
714    <display call="multiline('alternate_addresses')">
716 with appropriate labelling etc. See the standard template for an idea.
720 Migrating from 0.3.x to 0.4.0
721 =============================
723 0.4.0 Message-ID and In-Reply-To addition
724 -----------------------------------------
725 0.4.0 adds the tracking of messages by message-id and allows threading
726 using in-reply-to. Most e-mail clients support threading using this
727 feature, and we hope to add support for it to the web gateway. If you
728 have not edited the dbinit.py file in your instance home directory, you may
729 simply copy the new dbinit.py file from the core code. If you used the
730 classic schema, the interfaces file is in::
732  <roundup source>/roundup/templates/classic/dbinit.py
734 If you used the extended schema, the file is in::
736  <roundup source>/roundup/templates/extended/dbinit.py 
738 If you have modified your dbinit.py file, you need to edit the dbinit.py
739 file in your instance home directory. Find the lines which define the msg
740 class::
742     msg = FileClass(db, "msg",
743                     author=Link("user"), recipients=Multilink("user"),
744                     date=Date(),         summary=String(),
745                     files=Multilink("file"))
747 and add the messageid and inreplyto properties like so::
749     msg = FileClass(db, "msg",
750                     author=Link("user"), recipients=Multilink("user"),
751                     date=Date(),         summary=String(),
752                     files=Multilink("file"),
753                     messageid=String(),  inreplyto=String())
755 Also, configuration is being cleaned up. This means that your dbinit.py will
756 also need to be changed in the open function. If you haven't changed your
757 dbinit.py, the above copy will be enough. If you have, you'll need to change
758 the line (round line 50)::
760     db = Database(instance_config.DATABASE, name)
762 to::
764     db = Database(instance_config, name)
767 0.4.0 Configuration
768 --------------------
769 ``TRACKER_NAME`` and ``EMAIL_SIGNATURE_POSITION`` have been added to the
770 instance_config.py. The simplest solution is to copy the default values
771 from template in the core source.
773 The mail gateway now checks ``ANONYMOUS_REGISTER`` to see if unknown users
774 are to be automatically registered with the tracker. If it is set to "deny"
775 then unknown users will not have access. If it is set to "allow" they will be
776 automatically registered with the tracker.
779 0.4.0 CGI script roundup.cgi
780 ----------------------------
781 The CGI script has been updated with some features and a bugfix, so you should
782 copy it from the roundup cgi-bin source directory again. Make sure you update
783 the ROUNDUP_INSTANCE_HOMES after the copy.
786 0.4.0 Nosy reactor
787 ------------------
788 The nosy reactor has also changed - copy the nosyreactor.py file from the core
789 source::
791    <roundup source>/roundup/templates/<template>/detectors/nosyreactor.py
793 to your instance home "detectors" directory.
796 0.4.0 HTML templating
797 ---------------------
798 The field() function was incorrectly implemented - links and multilinks now
799 display as text fields when rendered using field(). To display a menu (drop-
800 down or select box) you need to use the menu() function.
804 Migrating from 0.2.x to 0.3.x
805 =============================
807 0.3.x Cookie Authentication changes
808 -----------------------------------
809 0.3.0 introduces cookie authentication - you will need to copy the
810 interfaces.py file from the roundup source to your instance home to enable
811 authentication. If you used the classic schema, the interfaces file is in::
813  <roundup source>/roundup/templates/classic/interfaces.py
815 If you used the extended schema, the file is in::
817  <roundup source>/roundup/templates/extended/interfaces.py
819 If you have modified your interfaces.Client class, you will need to take
820 note of the login/logout functionality provided in roundup.cgi_client.Client
821 (classic schema) or roundup.cgi_client.ExtendedClient (extended schema) and
822 modify your instance code apropriately.
825 0.3.x Password encoding
826 -----------------------
827 This release also introduces encoding of passwords in the database. If you
828 have not edited the dbinit.py file in your instance home directory, you may
829 simply copy the new dbinit.py file from the core code. If you used the
830 classic schema, the interfaces file is in::
832  <roundup source>/roundup/templates/classic/dbinit.py
834 If you used the extended schema, the file is in::
836  <roundup source>/roundup/templates/extended/dbinit.py
839 If you have modified your dbinit.py file, you may use encoded passwords:
841 1. Edit the dbinit.py file in your instance home directory
842    a. At the first code line of the open() function::
844        from roundup.hyperdb import String, Date, Link, Multilink
846       alter to include Password, as so::
848        from roundup.hyperdb import String, Password, Date, Link, Multilink
850    b. Where the password property is defined (around line 66)::
852        user = Class(db, "user", 
853                        username=String(),   password=String(),
854                        address=String(),    realname=String(), 
855                        phone=String(),      organisation=String())
856        user.setkey("username")
858       alter the "password=String()" to "password=Password()"::
860        user = Class(db, "user", 
861                        username=String(),   password=Password(),
862                        address=String(),    realname=String(), 
863                        phone=String(),      organisation=String())
864        user.setkey("username")
866 2. Any existing passwords in the database will remain cleartext until they
867    are edited. It is recommended that at a minimum the admin password be
868    changed immediately::
870       roundup-admin -i <instance home> set user1 password=<new password>
873 0.3.x Configuration
874 -------------------
875 FILTER_POSITION, ANONYMOUS_ACCESS, ANONYMOUS_REGISTER have been added to
876 the instance_config.py. Simplest solution is to copy the default values from
877 template in the core source.
879 MESSAGES_TO_AUTHOR has been added to the IssueClass in dbinit.py. Set to 'yes'
880 to send nosy messages to the author. Default behaviour is to not send nosy
881 messages to the author. You will need to add MESSAGES_TO_AUTHOR to your
882 dbinit.py in your instance home.
885 0.3.x CGI script roundup.cgi
886 ----------------------------
887 There have been some structural changes to the roundup.cgi script - you will
888 need to install it again from the cgi-bin directory of the source
889 distribution. Make sure you update the ROUNDUP_INSTANCE_HOMES after the
890 copy.
893 .. _`customisation documentation`: customizing.html
894 .. _`security documentation`: security.html