Code

fixed ZRoundup - mostly changes to classic template
[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().
19 0.7 creates indexes when using RDBMS backends. The yet-to-be-written
20 'refreshdb' roundup-admin command will create most indexes, but you 
21 might still need to create an index "create index ids_name_idx on 
22 ids(name)".
24 0.7.0 ZRoundup changes
25 ----------------------
27 The templates in your tracker's html directory will need updating if you
28 wish to use ZRoundup. If you've not modified those files (or some of them),
29 you may just copy the new versions from the Roundup source in the
30 templates/classic/html directory.
32 If you have modified the html files, then you'll need to manually edit them
33 to change all occurances of special form variables from using the colon ":"
34 special character to the at "@" special character. That is, variables such
35 as::
37   :action :required :template :remove:messages ...
39 should become:
41   @action @required @template @remove@messages ...
43 Note that ``tal:`` statements are unaffected. So are TAL expression type
44 prefixes such as ``python:`` and ``string:``. Please ask on the
45 roundup-users mailing list for help if you're unsure.
48 Migrating from 0.6.x to 0.6.3
49 =============================
51 0.6.3 Configuration
52 -------------------
54 You will need to copy the file::
56   templates/classic/detectors/__init__.py
58 to your tracker's ``detectors`` directory, replacing the one already there.
59 This fixes a couple of bugs in that file.
63 Migrating from 0.5 to 0.6
64 =========================
67 0.6.0 Configuration
68 -------------------
70 Introduced EMAIL_FROM_TAG config variable. This value is inserted into
71 the From: line of nosy email. If the sending user is "Foo Bar", the
72 From: line is usually::
74      "Foo Bar" <issue_tracker@tracker.example>
76 the EMAIL_FROM_TAG goes inside the "Foo Bar" quotes like so::
78      "Foo Bar EMAIL_FROM_TAG" <issue_tracker@tracker.example>
80 I've altered the mechanism in the detectors __init__.py module so that it
81 doesn't cross-import detectors from other trackers (if you run more than one
82 in a single roundup-server). This change means that you'll need to copy the
83 __init__.py from roundup/templates/classic/detectors/__init__.py to your
84 <tracker home>/detectors/__init__.py. Don't worry, the "classic" __init__ is a
85 one-size-fits-all, so it'll work even if you've added/removed detectors.
87 0.6.0 Templating changes
88 ------------------------
90 The ``user.item`` template (in the tracker home "templates" directory)
91 needs to have the following hidden variable added to its form (between the
92 ``<form...>`` and ``</form>`` tags::
94   <input type="hidden" name=":template" value="item">
97 0.6.0 Form handling changes
98 ---------------------------
100 Roundup's form handling capabilities have been significantly expanded. This
101 should not affect users of 0.5 installations - but if you find you're
102 getting errors from form submissions, please ask for help on the Roundup
103 users mailing list:
105   http://lists.sourceforge.net/lists/listinfo/roundup-users
107 See the customisation doc section on `Form Values`__ for documentation of the
108 new form variables possible.
110 __ customizing.html#form-values
113 0.6.0 Multilingual character set support
114 ----------------------------------------
116 Added internationalization support. This is done via encoding all data
117 stored in roundup database to utf-8 (unicode encoding). To support utf-8 in
118 web interface you should add the folowing line to your tracker's html/page
119 and html/_generic.help files inside <head> tag::
120   
121     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
123 Since latin characters in utf-8 have the same codes as in ASCII table, this
124 modification is optional for users who use only plain latin characters. 
126 After this modification, you will be able to see and enter any world
127 character via web interface. Data received via mail interface also converted
128 to utf-8, however only new messages will be converted. If your roundup
129 database contains some of non-ASCII characters in one of 8-bit encoding,
130 they will not be visible in new unicode environment. Some of such data (e.g.
131 user names, keywords, etc)  can be edited by administrator, the others
132 (e.g. messages' contents) is not editable via web interface. Currently there
133 is no tool for converting such data, the only solution is to close
134 appropriate old issues and create new ones with the same content.
137 0.6.0 User timezone support
138 ---------------------------
140 From version 0.6.0 roundup supports displaying of Date data in user' local
141 timezone if he/she has provided timezone information. To make it possible
142 some modification to tracker's schema and HTML templates are required.
143 First you must add string property 'timezone' to user class in dbinit.py
144 like this::
145   
146     user = Class(db, "user", 
147                     username=String(),   password=Password(),
148                     address=String(),    realname=String(), 
149                     phone=String(),      organisation=String(),
150                     alternate_addresses=String(),
151                     queries=Multilink('query'), roles=String(),
152                     timezone=String())
153   
154 And second - html interface. Add following lines to
155 $TRACKER_HOME/html/user.item template::
156   
157      <tr>
158       <th>Timezone</th>
159       <td tal:content="structure context/timezone/field">timezone</td>
160      </tr>
162 After that all users should be able to provide their timezone information.
163 Timezone should be a positive or negative integer - offset from GMT.
165 After providing timezone, roundup will show all dates values, found in web
166 and mail interfaces in local time. It will also accept any Date info in
167 local time, convert and store it in GMT.
170 0.6.0 Search page structure
171 ---------------------------
173 In order to accomodate query editing the search page has been restructured. If
174 you want to provide your users with query editing, you should update your
175 search page using the macros detailed in the customisation doc section
176 `Searching on categories`__.
178 __ customizing.html#searching-on-categories
180 Also, the url field in the query class no longer starts with a '?'. You'll need
181 to remove this question mark from the url field to support queries. There's
182 a script in the "tools" directory called ``migrate-queries.py`` that should
183 automatically change any existing queries for you. As always, make a backup
184 of your database before running such a script.
187 0.6.0 Notes for metakit backend users
188 -------------------------------------
190 Roundup 0.6.0 introduced searching on ranges of dates and intervals. To
191 support it, some modifications to interval storing routine were made. So if
192 your tracker uses metakit backend and your db schema contains intervals
193 property, searches on that property will not be accurate for db items that
194 was stored before roundup' upgrade. However all new records should be
195 searchable on intervals.
197 It is possible to convert your database to new format: you can export and
198 import back all your data (consult "Migrating backends" in "Maintenance"
199 documentation). After this operation all your interval properties should
200 become searchable.
202 Users of backends others than metakit should not worry about this issue.
205 Migrating from 0.4.x to 0.5.0
206 =============================
208 This has been a fairly major revision of Roundup:
210 1. Brand new, much more powerful, flexible, tasty and nutritious templating.
211    Unfortunately, this means all your current templates are useless. Hopefully
212    the new documentation and examples will be enough to help you make the
213    transition. Please don't hesitate to ask on roundup-users for help (or
214    complete conversions if you're completely stuck)!
215 2. The database backed got a lot more flexible, allowing Metakit and SQL
216    databases! The only decent SQL database implemented at present is sqlite,
217    but others shouldn't be a whole lot more work.
218 3. A brand new, highly flexible and much more robust security system including
219    a system of Permissions, Roles and Role assignments to users. You may now
220    define your own Permissions that may be checked in CGI transactions.
221 4. Journalling has been made less storage-hungry, so has been turned on
222    by default *except* for author, recipient and nosy link/unlink events. You
223    are advised to turn it off in your trackers too.
224 5. We've changed the terminology from "instance" to "tracker", to ease the
225    learning curve/impact for new users.
226 6. Because of the above changes, the tracker configuration has seen some
227    major changes. See below for the details.
229 Please, **back up your database** before you start the migration process. This
230 is as simple as copying the "db" directory and all its contents from your
231 tracker to somewhere safe.
234 0.5.0 Configuration
235 -------------------
237 First up, rename your ``instance_config.py`` file to just ``config.py``.
239 Then edit your tracker's ``__init__.py`` module. It'll currently look
240 like this::
242  from instance_config import *
243  try:
244      from dbinit import *
245  except ImportError:
246      pass # in installdir (probably :)
247  from interfaces import *
249 and it needs to be::
251  import config
252  from dbinit import open, init
253  from interfaces import Client, MailGW
255 Due to the new templating having a top-level ``page`` that defines links for
256 searching, indexes, adding items etc, the following variables are no longer
257 used:
259 - HEADER_INDEX_LINKS
260 - HEADER_ADD_LINKS
261 - HEADER_SEARCH_LINKS
262 - SEARCH_FILTERS
263 - DEFAULT_INDEX
264 - UNASSIGNED_INDEX
265 - USER_INDEX
266 - ISSUE_FILTER
268 The new security implementation will require additions to the dbinit module,
269 but also removes the need for the following tracker config variables:
271 - ANONYMOUS_ACCESS
272 - ANONYMOUS_REGISTER
274 but requires two new variables which define the Roles assigned to users who
275 register through the web and e-mail interfaces:
277 - NEW_WEB_USER_ROLES
278 - NEW_EMAIL_USER_ROLES
280 in both cases, 'User' is a good initial setting. To emulate
281 ``ANONYMOUS_ACCESS='deny'``, remove all "View" Permissions from the
282 "Anonymous" Role. To emulate ``ANONYMOUS_REGISTER='deny'``, remove the "Web
283 Registration" and/or the "Email Registration" Permission from the "Anonymous"
284 Role. See the section on customising security in the `customisation
285 documentation`_ for more information.
287 Finally, the following config variables have been renamed to make more sense:
289 - INSTANCE_HOME -> TRACKER_HOME
290 - INSTANCE_NAME -> TRACKER_NAME
291 - ISSUE_TRACKER_WEB -> TRACKER_WEB
292 - ISSUE_TRACKER_EMAIL -> TRACKER_EMAIL
295 0.5.0 Schema Specification
296 --------------------------
298 0.5.0 Database backend changes
299 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
301 Your select_db module in your tracker has changed a fair bit. Where it used
302 to contain::
304  # WARNING: DO NOT EDIT THIS FILE!!!
305  from roundup.backends.back_anydbm import Database
307 it must now contain::
309  # WARNING: DO NOT EDIT THIS FILE!!!
310  from roundup.backends.back_anydbm import Database, Class, FileClass, IssueClass
312 Yes, I realise the irony of the "DO NOT EDIT THIS FILE" statement :)
313 Note the addition of the Class, FileClass, IssueClass imports. These are very
314 important, as they're going to make the next change work too. You now need to
315 modify the top of the dbinit module in your tracker from::
317  import instance_config
318  from roundup import roundupdb
319  from select_db import Database
321  from roundup.roundupdb import Class, FileClass
323  class Database(roundupdb.Database, select_db.Database):
324      ''' Creates a hybrid database from:
325           . the selected database back-end from select_db
326           . the roundup extensions from roundupdb
327      '''
328      pass
330  class IssueClass(roundupdb.IssueClass):
331      ''' issues need the email information
332      '''
333      pass
335 to::
337  import config
338  from select_db import Database, Class, FileClass, IssueClass
340 Yes, remove the Database and IssueClass definitions and those other imports.
341 They're not needed any more!
343 Look for places in dbinit.py where ``instance_config`` is used too, and
344 rename them ``config``.
347 0.5.0 Journalling changes
348 ~~~~~~~~~~~~~~~~~~~~~~~~~
350 Journalling has been optimised for storage. Journalling of links has been
351 turned back on by default. If your tracker has a large user base, you may wish
352 to turn off journalling of nosy list, message author and message recipient
353 link and unlink events. You do this by adding ``do_journal='no'`` to the Class
354 initialisation in your dbinit. For example, your *msg* class initialisation
355 probably looks like this::
357     msg = FileClass(db, "msg",
358                     author=Link("user"), recipients=Multilink("user"),
359                     date=Date(),         summary=String(),
360                     files=Multilink("file"),
361                     messageid=String(),  inreplyto=String())
363 to turn off journalling of author and recipient link events, add
364 ``do_journal='no'`` to the ``author=Link("user")`` part of the statement,
365 like so::
367     msg = FileClass(db, "msg",
368                     author=Link("user", do_journal='no'),
369                     recipients=Multilink("user", do_journal='no'),
370                     date=Date(),         summary=String(),
371                     files=Multilink("file"),
372                     messageid=String(),  inreplyto=String())
374 Nosy list link event journalling is actually turned off by default now. If you
375 want to turn it on, change to your issue class' nosy list, change its
376 definition from::
378     issue = IssueClass(db, "issue",
379                     assignedto=Link("user"), topic=Multilink("keyword"),
380                     priority=Link("priority"), status=Link("status"))
382 to::
384     issue = IssueClass(db, "issue", nosy=Multilink("user", do_journal='yes'),
385                     assignedto=Link("user"), topic=Multilink("keyword"),
386                     priority=Link("priority"), status=Link("status"))
388 noting that your definition of the nosy Multilink will override the normal one.
391 0.5.0 User schema changes
392 ~~~~~~~~~~~~~~~~~~~~~~~~~
394 Users have two more properties, "queries" and "roles". You'll have something
395 like this in your dbinit module now::
397     user = Class(db, "user",
398                     username=String(),   password=Password(),
399                     address=String(),    realname=String(),
400                     phone=String(),      organisation=String(),
401                     alternate_addresses=String())
402     user.setkey("username")
404 and you'll need to add the new properties and the new "query" class to it
405 like so::
407     query = Class(db, "query",
408                     klass=String(),     name=String(),
409                     url=String())
410     query.setkey("name")
412     # Note: roles is a comma-separated string of Role names
413     user = Class(db, "user",
414                     username=String(),   password=Password(),
415                     address=String(),    realname=String(),
416                     phone=String(),      organisation=String(),
417                     alternate_addresses=String(),
418                     queries=Multilink('query'), roles=String())
419     user.setkey("username")
421 The "queries" property is used to store off the user's favourite database
422 queries. The "roles" property is explained below in `0.5.0 Security
423 Settings`_.
426 0.5.0 Security Settings
427 ~~~~~~~~~~~~~~~~~~~~~~~
429 See the `security documentation`_ for an explanation of how the new security
430 system works. In a nutshell though, the security is handled as a four step
431 process:
433 1. Permissions are defined as having a name and optionally a hyperdb class
434    they're specific to,
435 2. Roles are defined that have one or more Permissions,
436 3. Users are assigned Roles in their "roles" property, and finally
437 4. Roundup checks that users have appropriate Permissions at appropriate times
438    (like editing issues).
440 Your tracker dbinit module's *open* function now has to define any
441 Permissions that are specific to your tracker, and also the assignment
442 of Permissions to Roles. At the moment, your open function
443 ends with::
445     import detectors
446     detectors.init(db)
448     return db
450 and what we need to do is insert some commands that will set up the security
451 parameters. Right above the ``import detectors`` line, you'll want to insert
452 these lines::
454     #
455     # SECURITY SETTINGS
456     #
457     # new permissions for this schema
458     for cl in 'issue', 'file', 'msg', 'user':
459         db.security.addPermission(name="Edit", klass=cl,
460             description="User is allowed to edit "+cl)
461         db.security.addPermission(name="View", klass=cl,
462             description="User is allowed to access "+cl)
464     # Assign the access and edit permissions for issue, file and message
465     # to regular users now
466     for cl in 'issue', 'file', 'msg':
467         p = db.security.getPermission('View', cl)
468         db.security.addPermissionToRole('User', p)
469         p = db.security.getPermission('Edit', cl)
470         db.security.addPermissionToRole('User', p)
471     # and give the regular users access to the web and email interface
472     p = db.security.getPermission('Web Access')
473     db.security.addPermissionToRole('User', p)
474     p = db.security.getPermission('Email Access')
475     db.security.addPermissionToRole('User', p)
477     # May users view other user information? Comment these lines out
478     # if you don't want them to
479     p = db.security.getPermission('View', 'user')
480     db.security.addPermissionToRole('User', p)
482     # Assign the appropriate permissions to the anonymous user's Anonymous
483     # Role. Choices here are:
484     # - Allow anonymous users to register through the web
485     p = db.security.getPermission('Web Registration')
486     db.security.addPermissionToRole('Anonymous', p)
487     # - Allow anonymous (new) users to register through the email gateway
488     p = db.security.getPermission('Email Registration')
489     db.security.addPermissionToRole('Anonymous', p)
490     # - Allow anonymous users access to the "issue" class of data
491     #   Note: this also grants access to related information like files,
492     #         messages, statuses etc that are linked to issues
493     #p = db.security.getPermission('View', 'issue')
494     #db.security.addPermissionToRole('Anonymous', p)
495     # - Allow anonymous users access to edit the "issue" class of data
496     #   Note: this also grants access to create related information like
497     #         files and messages etc that are linked to issues
498     #p = db.security.getPermission('Edit', 'issue')
499     #db.security.addPermissionToRole('Anonymous', p)
501     # oh, g'wan, let anonymous access the web interface too
502     p = db.security.getPermission('Web Access')
503     db.security.addPermissionToRole('Anonymous', p)
505 Note in the comments there the places where you might change the permissions
506 to restrict users or grant users more access. If you've created additional
507 classes that users should be able to edit and view, then you should add them
508 to the "new permissions for this schema" section at the start of the security
509 block. Then add them to the "Assign the access and edit permissions" section
510 too, so people actually have the new Permission you've created.
512 One final change is needed that finishes off the security system's
513 initialisation. We need to add a call to ``db.post_init()`` at the end of the
514 dbinit open() function. Add it like this::
516     import detectors
517     detectors.init(db)
519     # schema is set up - run any post-initialisation
520     db.post_init()
521     return db
523 You may verify the setup of Permissions and Roles using the new
524 "``roundup-admin security``" command.
527 0.5.0 User changes
528 ~~~~~~~~~~~~~~~~~~
530 To support all those schema changes, you'll need to massage your user database
531 a little too, to:
533 1. make sure there's an "anonymous" user - this user is mandatory now and is
534    the one that unknown users are logged in as.
535 2. make sure all users have at least one Role.
537 If you don't have the "anonymous" user, create it now with the command::
539   roundup-admin create user username=anonymous roles=Anonymous
541 making sure the capitalisation is the same as above. Once you've done that,
542 you'll need to set the roles property on all users to a reasonable default.
543 The admin user should get "Admin", the anonymous user "Anonymous"
544 and all other users "User". The ``fixroles.py`` script in the tools directory
545 will do this. Run it like so (where python is your python 2+ binary)::
547   python tools/fixroles.py -i <tracker home> fixroles
551 0.5.0 CGI interface changes
552 ---------------------------
554 The CGI interface code was completely reorganised and largely rewritten. The
555 end result is that this section of your tracker interfaces module will need
556 changing from::
558  from roundup import cgi_client, mailgw
559  from roundup.i18n import _
560  
561  class Client(cgi_client.Client):
562      ''' derives basic CGI implementation from the standard module,
563          with any specific extensions
564      '''
565      pass
567 to::
569  from roundup import mailgw
570  from roundup.cgi import client
571  
572  class Client(client.Client): 
573      ''' derives basic CGI implementation from the standard module,
574          with any specific extensions
575      '''
576      pass
578 You will also need to install the new version of roundup.cgi from the source
579 cgi-bin directory if you're using it.
582 0.5.0 HTML templating
583 ---------------------
585 You'll want to make a backup of your current tracker html directory. You
586 should then copy the html directory from the Roundup source "classic" template
587 and modify it according to your local schema changes.
589 If you need help with the new templating system, please ask questions on the
590 roundup-users mailing list (available through the roundup project page on
591 sourceforge, http://roundup.sf.net/)
594 0.5.0 Detectors
595 ---------------
597 The nosy reactor has been updated to handle the tracker not having an
598 "assignedto" property on issues. You may want to copy it into your tracker's
599 detectors directory. Chances are you've already fixed it though :)
602 Migrating from 0.4.1 to 0.4.2
603 =============================
605 0.4.2 Configuration
606 -------------------
607 The USER_INDEX definition introduced in 0.4.1 was too restrictive in its
608 allowing replacement of 'assignedto' with the user's userid. Users must change
609 the None value of 'assignedto' to 'CURRENT USER' (the string, in quotes) for
610 the replacement behaviour to occur now.
612 The new configuration variables are:
614 - EMAIL_KEEP_QUOTED_TEXT 
615 - EMAIL_LEAVE_BODY_UNCHANGED
616 - ADD_RECIPIENTS_TO_NOSY
618 See the sample configuration files in::
620  <roundup source>/roundup/templates/classic/instance_config.py
622 and::
624  <roundup source>/roundup/templates/extended/instance_config.py
626 and the `customisation documentation`_ for information on how they're used.
629 0.4.2 Changes to detectors
630 --------------------------
631 You will need to copy the detectors from the distribution into your instance
632 home "detectors" directory. If you used the classic schema, the detectors
633 are in::
635  <roundup source>/roundup/templates/classic/detectors/
637 If you used the extended schema, the detectors are in::
639  <roundup source>/roundup/templates/extended/detectors/
641 The change means that schema-specific code has been removed from the
642 mail gateway and cgi interface and made into auditors:
644 - nosyreactor.py has now got an updatenosy auditor which updates the nosy
645   list with author, recipient and assignedto information.
646 - statusauditor.py makes the unread or resolved -> chatting changes and
647   presets the status of an issue to unread.
649 There's also a bug or two fixed in the nosyreactor code.
651 0.4.2 HTML templating changes
652 -----------------------------
653 The link() htmltemplate function now has a "showid" option for links and
654 multilinks. When true, it only displays the linked item id as the anchor
655 text. The link value is displayed as a tooltip using the title anchor
656 attribute. To use in eg. the superseder field, have something like this::
658    <td>
659     <display call="field('superseder', showid=1)">
660     <display call="classhelp('issue', 'id,title', label='list', width=500)">
661     <property name="superseder">
662      <br>View: <display call="link('superseder', showid=1)">
663     </property>
664    </td>
666 The stylesheets have been cleaned up too. You may want to use the newer
667 versions in::
669  <roundup source>/roundup/templates/<template>/html/default.css
673 Migrating from 0.4.0 to 0.4.1
674 =============================
676 0.4.1 Files storage
677 -------------------
679 Messages and files from newly created issues will be put into subdierectories
680 in thousands e.g. msg123 will be put into files/msg/0/msg123, file2003
681 will go into files/file/2/file2003. Previous messages are still found, but
682 could be put into this structure.
684 0.4.1 Configuration
685 -------------------
687 To allow more fine-grained access control, the variable used to check
688 permission to auto-register users in the mail gateway is now called
689 ANONYMOUS_REGISTER_MAIL rather than overloading ANONYMOUS_REGISTER. If the
690 variable doesn't exist, then ANONYMOUS_REGISTER is tested as before.
692 Configuring the links in the web header is now easier too. The following
693 variables have been added to the classic instance_config.py::
695   HEADER_INDEX_LINKS   - defines the "index" links to be made available
696   HEADER_ADD_LINKS     - defines the "add" links
697   DEFAULT_INDEX        - specifies the index view for DEFAULT
698   UNASSIGNED_INDEX     - specifies the index view for UNASSIGNED
699   USER_INDEX           - specifies the index view for USER
701 See the <roundup source>/roundup/templates/classic/instance_config.py for more
702 information - including how the variables are to be set up. Most users will
703 just be able to copy the variables from the source to their instance home. If
704 you've modified the header by changing the source of the interfaces.py file in
705 the instance home, you'll need to remove that customisation and move it into
706 the appropriate variables in instance_config.py.
708 The extended schema has similar variables added too - see the source for more
709 info.
711 0.4.1 Alternate E-Mail Addresses
712 --------------------------------
714 If you add the property "alternate_addresses" to your user class, your users
715 will be able to register alternate email addresses that they may use to
716 communicate with roundup as. All email from roundup will continue to be sent
717 to their primary address.
719 If you have not edited the dbinit.py file in your instance home directory,
720 you may simply copy the new dbinit.py file from the core code. If you used
721 the classic schema, the interfaces file is in::
723  <roundup source>/roundup/templates/classic/dbinit.py
725 If you used the extended schema, the file is in::
727  <roundup source>/roundup/templates/extended/dbinit.py 
729 If you have modified your dbinit.py file, you need to edit the dbinit.py
730 file in your instance home directory. Find the lines which define the user
731 class::
733     user = Class(db, "msg",
734                     username=String(),   password=Password(),
735                     address=String(),    realname=String(), 
736                     phone=String(),      organisation=String(),
737                     alternate_addresses=String())
739 You will also want to add the property to the user's details page. The
740 template for this is the "user.item" file in your instance home "html"
741 directory. Similar to above, you may copy the file from the roundup source if
742 you haven't modified it. Otherwise, add the following to the template::
744    <display call="multiline('alternate_addresses')">
746 with appropriate labelling etc. See the standard template for an idea.
750 Migrating from 0.3.x to 0.4.0
751 =============================
753 0.4.0 Message-ID and In-Reply-To addition
754 -----------------------------------------
755 0.4.0 adds the tracking of messages by message-id and allows threading
756 using in-reply-to. Most e-mail clients support threading using this
757 feature, and we hope to add support for it to the web gateway. If you
758 have not edited the dbinit.py file in your instance home directory, you may
759 simply copy the new dbinit.py file from the core code. If you used the
760 classic schema, the interfaces file is in::
762  <roundup source>/roundup/templates/classic/dbinit.py
764 If you used the extended schema, the file is in::
766  <roundup source>/roundup/templates/extended/dbinit.py 
768 If you have modified your dbinit.py file, you need to edit the dbinit.py
769 file in your instance home directory. Find the lines which define the msg
770 class::
772     msg = FileClass(db, "msg",
773                     author=Link("user"), recipients=Multilink("user"),
774                     date=Date(),         summary=String(),
775                     files=Multilink("file"))
777 and add the messageid and inreplyto properties like so::
779     msg = FileClass(db, "msg",
780                     author=Link("user"), recipients=Multilink("user"),
781                     date=Date(),         summary=String(),
782                     files=Multilink("file"),
783                     messageid=String(),  inreplyto=String())
785 Also, configuration is being cleaned up. This means that your dbinit.py will
786 also need to be changed in the open function. If you haven't changed your
787 dbinit.py, the above copy will be enough. If you have, you'll need to change
788 the line (round line 50)::
790     db = Database(instance_config.DATABASE, name)
792 to::
794     db = Database(instance_config, name)
797 0.4.0 Configuration
798 --------------------
799 ``TRACKER_NAME`` and ``EMAIL_SIGNATURE_POSITION`` have been added to the
800 instance_config.py. The simplest solution is to copy the default values
801 from template in the core source.
803 The mail gateway now checks ``ANONYMOUS_REGISTER`` to see if unknown users
804 are to be automatically registered with the tracker. If it is set to "deny"
805 then unknown users will not have access. If it is set to "allow" they will be
806 automatically registered with the tracker.
809 0.4.0 CGI script roundup.cgi
810 ----------------------------
811 The CGI script has been updated with some features and a bugfix, so you should
812 copy it from the roundup cgi-bin source directory again. Make sure you update
813 the ROUNDUP_INSTANCE_HOMES after the copy.
816 0.4.0 Nosy reactor
817 ------------------
818 The nosy reactor has also changed - copy the nosyreactor.py file from the core
819 source::
821    <roundup source>/roundup/templates/<template>/detectors/nosyreactor.py
823 to your instance home "detectors" directory.
826 0.4.0 HTML templating
827 ---------------------
828 The field() function was incorrectly implemented - links and multilinks now
829 display as text fields when rendered using field(). To display a menu (drop-
830 down or select box) you need to use the menu() function.
834 Migrating from 0.2.x to 0.3.x
835 =============================
837 0.3.x Cookie Authentication changes
838 -----------------------------------
839 0.3.0 introduces cookie authentication - you will need to copy the
840 interfaces.py file from the roundup source to your instance home to enable
841 authentication. If you used the classic schema, the interfaces file is in::
843  <roundup source>/roundup/templates/classic/interfaces.py
845 If you used the extended schema, the file is in::
847  <roundup source>/roundup/templates/extended/interfaces.py
849 If you have modified your interfaces.Client class, you will need to take
850 note of the login/logout functionality provided in roundup.cgi_client.Client
851 (classic schema) or roundup.cgi_client.ExtendedClient (extended schema) and
852 modify your instance code apropriately.
855 0.3.x Password encoding
856 -----------------------
857 This release also introduces encoding of passwords in the database. If you
858 have not edited the dbinit.py file in your instance home directory, you may
859 simply copy the new dbinit.py file from the core code. If you used the
860 classic schema, the interfaces file is in::
862  <roundup source>/roundup/templates/classic/dbinit.py
864 If you used the extended schema, the file is in::
866  <roundup source>/roundup/templates/extended/dbinit.py
869 If you have modified your dbinit.py file, you may use encoded passwords:
871 1. Edit the dbinit.py file in your instance home directory
872    a. At the first code line of the open() function::
874        from roundup.hyperdb import String, Date, Link, Multilink
876       alter to include Password, as so::
878        from roundup.hyperdb import String, Password, Date, Link, Multilink
880    b. Where the password property is defined (around line 66)::
882        user = Class(db, "user", 
883                        username=String(),   password=String(),
884                        address=String(),    realname=String(), 
885                        phone=String(),      organisation=String())
886        user.setkey("username")
888       alter the "password=String()" to "password=Password()"::
890        user = Class(db, "user", 
891                        username=String(),   password=Password(),
892                        address=String(),    realname=String(), 
893                        phone=String(),      organisation=String())
894        user.setkey("username")
896 2. Any existing passwords in the database will remain cleartext until they
897    are edited. It is recommended that at a minimum the admin password be
898    changed immediately::
900       roundup-admin -i <instance home> set user1 password=<new password>
903 0.3.x Configuration
904 -------------------
905 FILTER_POSITION, ANONYMOUS_ACCESS, ANONYMOUS_REGISTER have been added to
906 the instance_config.py. Simplest solution is to copy the default values from
907 template in the core source.
909 MESSAGES_TO_AUTHOR has been added to the IssueClass in dbinit.py. Set to 'yes'
910 to send nosy messages to the author. Default behaviour is to not send nosy
911 messages to the author. You will need to add MESSAGES_TO_AUTHOR to your
912 dbinit.py in your instance home.
915 0.3.x CGI script roundup.cgi
916 ----------------------------
917 There have been some structural changes to the roundup.cgi script - you will
918 need to install it again from the cgi-bin directory of the source
919 distribution. Make sure you update the ROUNDUP_INSTANCE_HOMES after the
920 copy.
923 .. _`customisation documentation`: customizing.html
924 .. _`security documentation`: security.html