Code

1a461d3d270b62592d8b712d2ace74df28280ae5
[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 If a specific version transition isn't mentioned here (eg. 0.6.7 to 0.6.8)
10 then you don't need to do anything. If you're upgrading from 0.5.6 to
11 0.6.8 though, you'll need to check the "0.5 to 0.6" and "0.6.x to 0.6.3"
12 steps.
14 .. contents::
16 Migrating from 1.4.x to 1.4.12
17 ==============================
19 Item creation now checks the "Create" permission instead of the "Edit"
20 permission for individual properties. If you have modified your tracker
21 permissions from the default distribution, you should check that
22 "Create" permissions exist for all properties you want users to be able
23 to create.
25 Migrating from 1.4.x to 1.4.11
26 ==============================
28 Close potential security hole
29 -----------------------------
31 If your tracker has untrusted users you should examine its ``schema.py``
32 file and look for the section granting the "Edit" permission to your users.
33 This should look something like::
35     p = db.security.addPermission(name='Edit', klass='user', check=own_record,
36         description="User is allowed to edit their own user details")
38 and should be modified to restrict the list of properties they are allowed
39 to edit by adding the ``properties=`` section like::
41     p = db.security.addPermission(name='Edit', klass='user', check=own_record,
42         properties=('username', 'password', 'address', 'realname', 'phone',
43             'organisation', 'alternate_addresses', 'queries', 'timezone'),
44         description="User is allowed to edit their own user details")
46 Most importantly the "roles" property should not be editable - thus not
47 appear in that list of properties.
50 Grant the "Register" permission to the Anonymous role
51 -----------------------------------------------------
53 A separate "Register" permission has been introduced to allow
54 anonymous users to register. This means you will need to add the
55 following to your tracker's ``schema.py`` to add the permission and
56 assign it to the Anonymous role (replacing any previously assigned
57 "Create user" permission for the Anonymous role)::
59   +db.security.addPermission(name='Register', klass='user',
60   +     description='User is allowed to register new user')
61  
62    # Assign the appropriate permissions to the anonymous user's Anonymous
63    # Role. Choices here are:
64    # - Allow anonymous users to register
65   -db.security.addPermissionToRole('Anonymous', 'Create', 'user')
66   +db.security.addPermissionToRole('Anonymous', 'Register', 'user')
68 The lines marked "+" should be added and lines marked "-" should be
69 deleted (minus the "+"/"-" signs).
72 Generic class editor may now restore retired items
73 --------------------------------------------------
75 The instructions for doing so won't be present in your tracker unless you copy
76 the ``_generic.index.html`` template from the roundup distribution in
77 ``share/roundup/templates/classic/html`` to your tracker's ``html`` directory.
80 Migrating from 1.4.x to 1.4.9
81 =============================
83 Customized MailGW Class
84 -----------------------
86 If you have customized the MailGW class in your tracker: The new MailGW
87 class opens the database for each message in the method handle_message
88 (instance.open) instead of passing the opened database as a parameter to
89 the MailGW constructor. The old handle_message has been renamed to
90 _handle_message. The new method opens the database and wraps the call to
91 the old method into a try/finally.
93 Your customized MailGW class needs to mirror this behavior.
95 Fix the "remove" button in issue files and messages lists
96 ---------------------------------------------------------
98 The "remove" button(s) in the issue messages list needs to be altered. Find
99 the following in your tracker's ``html/issue.item.html`` template::
101   <td>
102    <form style="padding:0" tal:condition="context/is_edit_ok"
103          tal:attributes="action string:issue${context/id}">
104     <input type="hidden" name="@remove@files" tal:attributes="value file/id">
106 and add ``method="POST"`` as shown below::
108   <td>
109    <form style="padding:0" method="POST" tal:condition="context/is_edit_ok"
110          tal:attributes="action string:issue${context/id}">
111     <input type="hidden" name="@remove@files" tal:attributes="value file/id">
113 Then also find::
115   <td>
116    <form style="padding:0" tal:condition="context/is_edit_ok"
117          tal:attributes="action string:issue${context/id}">
118     <input type="hidden" name="@remove@messages" tal:attributes="value msg/id">
120 and add ``method="POST"`` as shown below::
122   <td>
123    <form style="padding:0" method="POST" tal:condition="context/is_edit_ok"
124          tal:attributes="action string:issue${context/id}">
125     <input type="hidden" name="@remove@messages" tal:attributes="value msg/id">
128 Fixing the "retire" button in user management list
129 --------------------------------------------------
131 If you made the change to the "reture" link in the user management list as
132 listed below in `Migrating from 1.4.x to 1.4.7`_ then you'll need to fix that
133 change by adding ``method="POST"`` to the ``<form>`` tag::
135      <form style="padding:0" method="POST"
136            tal:attributes="action string:user${user/id}">
137       <input type="hidden" name="@template" value="index">
138       <input type="hidden" name="@action" value="retire">
139       <input type="submit" value="retire" i18n:attributes="value">
140      </form>
143 Migrating from 1.4.x to 1.4.7
144 =============================
146 Several security issues were addressed in this release. Some aspects of your
147 trackers may no longer function depending on your local customisations. Core
148 functionality that will need to be modified:
150 Grant the "retire" permission to users for their queries
151 --------------------------------------------------------
153 Users will no longer be able to retire their own queries. To remedy this you
154 will need to add the following to your tracker's ``schema.py`` just under the
155 line that grants them permission to edit their own queries::
157    p = db.security.addPermission(name='Edit', klass='query', check=edit_query,
158       description="User is allowed to edit their queries")
159    db.security.addPermissionToRole('User', p)
160  + p = db.security.addPermission(name='Retire', klass='query', check=edit_query,
161  +    description="User is allowed to retire their queries")
162  + db.security.addPermissionToRole('User', p)
163    p = db.security.addPermission(name='Create', klass='query',
164       description="User is allowed to create queries")
165    db.security.addPermissionToRole('User', p)
167 The lines marked "+" should be added, minus the "+" sign.
170 Fix the "retire" link in the users list for admin users
171 -------------------------------------------------------
173 The "retire" link found in the file ``html/users.index.html``::
175   <td tal:condition="context/is_edit_ok">
176    <a tal:attributes="href string:user${user/id}?@action=retire&@template=index"
177     i18n:translate="">retire</a>
179 Should be replaced with::
181   <td tal:condition="context/is_retire_ok">
182      <form style="padding:0" method="POST"
183            tal:attributes="action string:user${user/id}">
184       <input type="hidden" name="@template" value="index">
185       <input type="hidden" name="@action" value="retire">
186       <input type="submit" value="retire" i18n:attributes="value">
187      </form>
190 Fix for Python 2.6+ users
191 -------------------------
193 If you use Python 2.6 you should edit your tracker's
194 ``detectors/nosyreaction.py`` file to change::
196    import sets
198 at the top to::
200    from roundup.anypy.sets_ import set
202 and then all instances of ``sets.Set()`` to ``set()`` in the later code.
206 Trackers currently allowing HTML file uploading
207 -----------------------------------------------
209 Trackers which wish to continue to allow uploading of HTML content against issues
210 will need to set a new configuration variable in the ``[web]`` section of the
211 tracker's ``config.ini`` file:
213    # Setting this option enables Roundup to serve uploaded HTML
214    # file content *as HTML*. This is a potential security risk
215    # and is therefore disabled by default. Set to 'yes' if you
216    # trust *all* users uploading content to your tracker.
217    # Allowed values: yes, no
218    # Default: no
219    allow_html_file = no
223 Migrating from 1.4.2 to 1.4.3
224 =============================
226 If you are using the MySQL backend you will need to replace some indexes
227 that may have been created by version 1.4.2.
229 You should to access your MySQL database directly and remove any indexes
230 with a name ending in "_key_retired_idx". You should then re-add them with
231 the same spec except the key column name needs a size. So an index on
232 "_user (__retired, _name)" should become "_user (__retired, _name(255))".
235 Migrating from 1.4.x to 1.4.2
236 =============================
238 You should run the "roundup-admin migrate" command for your tracker once
239 you've installed the latest codebase. 
241 Do this before you use the web, command-line or mail interface and before
242 any users access the tracker.
244 This command will respond with either "Tracker updated" (if you've not
245 previously run it on an RDBMS backend) or "No migration action required"
246 (if you have run it, or have used another interface to the tracker,
247 or are using anydbm).
249 It's safe to run this even if it's not required, so just get into the
250 habit.
253 Migrating from 1.3.3 to 1.4.0
254 =============================
256 Value of the "refwd_re" tracker configuration option (section "mailgw")
257 is treated as UTF-8 string.  In previous versions, it was ISO8859-1.
259 If you have running trackers based on the classic template, please
260 update the messagesummary detector as follows::
262     --- detectors/messagesummary.py 17 Apr 2003 03:26:38 -0000      1.1
263     +++ detectors/messagesummary.py 3 Apr 2007 06:47:21 -0000       1.2
264     @@ -8,7 +8,7 @@
265      if newvalues.has_key('summary') or not newvalues.has_key('content'):
266          return
268     -    summary, content = parseContent(newvalues['content'], 1, 1)
269     +    summary, content = parseContent(newvalues['content'], config=db.config)
270      newvalues['summary'] = summary
272 In the latest version we have added some database indexes to the
273 SQL-backends (mysql, postgresql, sqlite) for speeding up building the
274 roundup-index for full-text search. We recommend that you create the
275 following database indexes on the database by hand::
277  CREATE INDEX words_by_id ON __words (_textid)
278  CREATE UNIQUE INDEX __textids_by_props ON __textids (_class, _itemid, _prop)
280 Migrating from 1.2.x to 1.3.0
281 =============================
283 1.3.0 Web interface changes
284 ---------------------------
286 Some of the HTML files in the "classic" and "minimal" tracker templates
287 were changed to fix some bugs and clean them up. You may wish to compare
288 them to the HTML files in your tracker and apply any changes.
291 Migrating from 1.1.2 to 1.2.0
292 =============================
294 1.2.0 Sorting and grouping by multiple properties
295 -------------------------------------------------
297 Starting with this version, sorting and grouping by multiple properties
298 is possible. This means that request.sort and request.group are now
299 lists. This is reflected in several places:
301  * ``renderWith`` now has list attributes for ``sort`` and ``group``,
302    where you previously wrote::
303    
304     renderWith(... sort=('-', 'activity'), group=('+', 'priority')
306    you write now::
308     renderWith(... sort=[('-', 'activity')], group=[('+', 'priority')]
310  * In templates that permit to edit sorting/grouping, request.sort and
311    request.group are (possibly empty) lists. You can now sort and group
312    by multiple attributes. For an example, see the classic template. You
313    may want search for the variable ``n_sort`` which can be set to the
314    number of sort/group properties.
316  * Templates that diplay new headlines for each group of items with
317    equal group properties can now use the modified ``batch.propchanged``
318    method that can take several properties which are checked for
319    changes. See the example in the classic template which makes use of
320    ``batch.propchanged``.
322 Migrating from 1.1.0 to 1.1.1
323 =============================
325 1.1.1 "Clear this message"
326 --------------------------
328 In 1.1.1, the standard ``page.html`` template includes a "clear this message"
329 link in the green "ok" message bar that appears after a successful edit
330 (or other) action.
332 To include this in your tracker, change the following in your ``page.html``
333 template::
335  <p tal:condition="options/ok_message | nothing" class="ok-message"
336     tal:repeat="m options/ok_message" tal:content="structure m">error</p>
338 to be::
340  <p tal:condition="options/ok_message | nothing" class="ok-message">
341    <span tal:repeat="m options/ok_message"
342       tal:content="structure string:$m <br/ > " />
343     <a class="form-small" tal:attributes="href request/current_url"
344        i18n:translate="">clear this message</a>
345  </p>
348 If you implemented the "clear this message" in your 1.1.0 tracker, then you
349 should change it to the above and it will work much better!
352 Migrating from 1.0.x to 1.1.0
353 =============================
355 1.1 Login "For Session Only"
356 ----------------------------
358 In 1.1, web logins are alive for the length of a session only, *unless* you
359 add the following to the login form in your tracker's ``page.html``::
361     <input type="checkbox" name="remember" id="remember">
362     <label for="remember" i18n:translate="">Remember me?</label><br>
364 See the classic tracker ``page.html`` if you're unsure where this should
365 go.
368 1.1 Query Display Name
369 ----------------------
371 The ``dispname`` web variable has been renamed ``@dispname`` to avoid
372 clashing with other variables of the same name. If you are using the
373 display name feature, you will need to edit your tracker's ``page.html``
374 and ``issue.index.html`` pages to change ``dispname`` to ``@dispname``.
376 A side-effect of this change is that the renderWith method used in the
377 ``home.html`` page may now take a dispname argument.
380 1.1 "Clear this message"
381 ------------------------
383 In 1.1, the standard ``page.html`` template includes a "clear this message"
384 link in the green "ok" message bar that appears after a successful edit
385 (or other) action.
387 To include this in your tracker, change the following in your ``page.html``
388 template::
390  <p tal:condition="options/ok_message | nothing" class="ok-message"
391     tal:repeat="m options/ok_message" tal:content="structure m">error</p>
393 to be::
395  <p tal:condition="options/ok_message | nothing" class="ok-message">
396    <span tal:repeat="m options/ok_message"
397       tal:content="structure string:$m <br/ > " />
398     <a class="form-small" tal:attributes="href string:issue${context/id}"
399        i18n:translate="">clear this message</a>
400  </p>
403 Migrating from 0.8.x to 1.0
404 ===========================
406 1.0 New Query Permissions
407 -------------------------
409 New permissions are defined for query editing and viewing. To include these
410 in your tracker, you need to add these lines to your tracker's
411 ``schema.py``::
413  # Users should be able to edit and view their own queries. They should also
414  # be able to view any marked as not private. They should not be able to
415  # edit others' queries, even if they're not private
416  def view_query(db, userid, itemid):
417      private_for = db.query.get(itemid, 'private_for')
418      if not private_for: return True
419      return userid == private_for
420  def edit_query(db, userid, itemid):
421      return userid == db.query.get(itemid, 'creator')
422  p = db.security.addPermission(name='View', klass='query', check=view_query,
423      description="User is allowed to view their own and public queries")
424  db.security.addPermissionToRole('User', p)
425  p = db.security.addPermission(name='Edit', klass='query', check=edit_query,
426      description="User is allowed to edit their queries")
427  db.security.addPermissionToRole('User', p)
428  p = db.security.addPermission(name='Create', klass='query',
429      description="User is allowed to create queries")
430  db.security.addPermissionToRole('User', p)
432 and then remove 'query' from the line::
434  # Assign the access and edit Permissions for issue, file and message
435  # to regular users now
436  for cl in 'issue', 'file', 'msg', 'query', 'keyword':
438 so it looks like::
440  for cl in 'issue', 'file', 'msg', 'keyword':
443 Migrating from 0.8.0 to 0.8.3
444 =============================
446 0.8.3 Nosy Handling Changes
447 ---------------------------
449 A change was made to fix a bug in the ``nosyreaction.py`` standard
450 detector. To incorporate this fix in your trackers, you will need to copy
451 the ``nosyreaction.py`` file from the ``templates/classic/detectors``
452 directory of the source to your tracker's ``templates`` directory.
454 If you have modified the ``nosyreaction.py`` file from the standard
455 version, you will need to roll your changes into the new file.
458 Migrating from 0.7.1 to 0.8.0
459 =============================
461 You *must* fully uninstall previous Roundup version before installing
462 Roundup 0.8.0.  If you don't do that, ``roundup-admin install``
463 command may fail to function properly.
465 0.8.0 Backend changes
466 ---------------------
468 Backends 'bsddb' and 'bsddb3' are removed.  If you are using one of these,
469 you *must* migrate to another backend before upgrading.
472 0.8.0 API changes
473 -----------------
475 Class.safeget() was removed from the API. Test your item ids before calling
476 Class.get() instead.
479 0.8.0 New tracker layout
480 ------------------------
482 The ``config.py`` file has been replaced by ``config.ini``. You may use the
483 roundup-admin command "genconfig" to generate a new config file::
485   roundup-admin genconfig <tracker home>/config.ini
487 and modify the values therein based on the contents of your old config.py.
488 In most cases, the names of the config variables are the same.
490 The ``select_db.py`` file has been replaced by a file in the ``db``
491 directory called ``backend_name``. As you might guess, this file contains
492 just the name of the backend. To figure what the contents of yours should
493 be, use the following table:
495   ================================ =========================
496   ``select_db.py`` contents        ``backend_name`` contents
497   ================================ =========================
498   from back_anydbm import ...      anydbm
499   from back_metakit import ...     metakit
500   from back_sqlite import ...      sqlite
501   from back_mysql import ...       mysql
502   from back_postgresql import ...  postgresql
503   ================================ =========================
505 The ``dbinit.py`` file has been split into two new files,
506 ``initial_data.py`` and ``schema.py``. The contents of this file are:
508 ``initial_data.py``
509   You don't need one of these as your tracker is already initialised.
511 ``schema.py``
512   Copy the body of the ``def open(name=None)`` function from your old
513   tracker's ``dbinit.py`` file to this file. As the lines you're copying
514   aren't part of a function definition anymore, one level of indentation
515   needs to be removed (remove only the leading four spaces on each
516   line). 
518   The first few lines -- those starting with ``from roundup.hyperdb
519   import ...`` and the ``db = Database(config, name)`` line -- don't
520   need to be copied. Neither do the last few lines -- those starting
521   with ``import detectors``, down to ``return db`` inclusive.
523 You may remove the ``__init__.py`` module from the "detectors" directory as
524 it is no longer used.
526 There's a new way to write extension code for Roundup. If you have code in
527 an ``interfaces.py`` file you should move it. See the `customisation
528 documentation`_ for information about how extensions are now written.
529 Note that some older trackers may use ``interfaces.py`` to customise the
530 mail gateway behaviour. You will need to keep your ``interfaces.py`` file
531 if this is the case.
534 0.8.0 Permissions Changes
535 -------------------------
537 The creation of a new item in the user interfaces is now controlled by the
538 "Create" Permission. You will need to add an assignment of this Permission
539 to your users who are allowed to create items. The most common form of this
540 is the following in your ``schema.py`` added just under the current
541 assignation of the Edit Permission::
543     for cl in 'issue', 'file', 'msg', 'query', 'keyword':
544         p = db.security.getPermission('Create', cl)
545         db.security.addPermissionToRole('User', p)
547 You will need to explicitly let anonymous users access the web interface so
548 that regular users are able to see the login form. Note that almost all
549 trackers will need this Permission. The only situation where it's not
550 required is in a tracker that uses an HTTP Basic Authenticated front-end.
551 It's enabled by adding to your ``schema.py``::
553     p = db.security.getPermission('Web Access')
554     db.security.addPermissionToRole('Anonymous', p)
556 Finally, you will need to enable permission for your users to edit their
557 own details by adding the following to ``schema.py``::
559     # Users should be able to edit their own details. Note that this
560     # permission is limited to only the situation where the Viewed or
561     # Edited item is their own.
562     def own_record(db, userid, itemid):
563         '''Determine whether the userid matches the item being accessed.'''
564         return userid == itemid
565     p = db.security.addPermission(name='View', klass='user', check=own_record,
566         description="User is allowed to view their own user details")
567     p = db.security.addPermission(name='Edit', klass='user', check=own_record,
568         description="User is allowed to edit their own user details")
569     db.security.addPermissionToRole('User', p)
572 0.8.0 Use of TemplatingUtils
573 ----------------------------
575 If you used custom python functions in TemplatingUtils, they must
576 be moved from interfaces.py to a new file in the ``extensions`` directory. 
578 Each Function that should be available through TAL needs to be defined
579 as a toplevel function in the newly created file. Furthermore you
580 add an inititialization function, that registers the functions with the 
581 tracker.
583 If you find this too tedious, donfu wrote an automatic init function that
584 takes an existing TemplatingUtils class, and registers all class methods
585 that do not start with an underscore. The following hack should be placed
586 in the ``extensions`` directory alongside other extensions::
588     class TemplatingUtils:
589          # copy from interfaces.py
591     def init(tracker):
592          util = TemplatingUtils()
594          def setClient(tu):
595              util.client = tu.client
596              return util
598          def execUtil(name):
599              return lambda tu, *args, **kwargs: \
600                      getattr(setClient(tu), name)(*args, **kwargs)
602          for name in dir(util):
603              if callable(getattr(util, name)) and not name.startswith('_'):
604                   tracker.registerUtil(name, execUtil(name))
607 0.8.0 Logging Configuration
608 ---------------------------
610 See the `administration guide`_ for information about configuring the new
611 logging implemented in 0.8.0.
614 Migrating from 0.7.2 to 0.7.3
615 =============================
617 0.7.3 Configuration
618 -------------------
620 If you choose, you may specify the directory from which static files are
621 served (those which use the URL component ``@@file``). Currently the
622 directory defaults to the ``TEMPLATES`` configuration variable. You may
623 define a new variable, ``STATIC_FILES`` which overrides this value for
624 static files.
627 Migrating from 0.7.0 to 0.7.2
628 =============================
630 0.7.2 DEFAULT_TIMEZONE is now required
631 --------------------------------------
633 The DEFAULT_TIMEZONE configuration variable is now required. Add the
634 following to your tracker's ``config.py`` file::
636     # You may specify a different default timezone, for use when users do not
637     # choose their own in their settings.
638     DEFAULT_TIMEZONE = 0            # specify as numeric hour offest
641 Migrating from 0.7.0 to 0.7.1
642 =============================
644 0.7.1 Permission assignments
645 ----------------------------
647 If you allow anonymous access to your tracker, you might need to assign
648 some additional View (or Edit if your tracker is that open) permissions
649 to the "anonymous" user. To do so, find the code in your ``dbinit.py`` that
650 says::
652     for cl in 'issue', 'file', 'msg', 'query', 'keyword':
653         p = db.security.getPermission('View', cl)
654         db.security.addPermissionToRole('User', p)
655         p = db.security.getPermission('Edit', cl)
656         db.security.addPermissionToRole('User', p)
657     for cl in 'priority', 'status':
658         p = db.security.getPermission('View', cl)
659         db.security.addPermissionToRole('User', p)
661 Add add a line::
663         db.security.addPermissionToRole('Anonymous', p)
665 next to the existing ``'User'`` lines for the Permissions you wish to
666 assign to the anonymous user.
669 Migrating from 0.6 to 0.7
670 =========================
672 0.7.0 Permission assignments
673 ----------------------------
675 Due to a change in the rendering of web widgets, permissions are now
676 checked on Classes where they previously weren't (this is a good thing).
678 You will need to add some additional Permission assignments for your
679 regular users, or some displays will break. After the following in your 
680 tracker's ``dbinit.py``::
682     # Assign the access and edit Permissions for issue, file and message
683     # to regular users now
684     for cl in 'issue', 'file', 'msg', 'query', 'keyword':
685         p = db.security.getPermission('View', cl)
686         db.security.addPermissionToRole('User', p)
687         p = db.security.getPermission('Edit', cl)
688         db.security.addPermissionToRole('User', p)
690 add::
692     for cl in 'priority', 'status':
693         p = db.security.getPermission('View', cl)
694         db.security.addPermissionToRole('User', p)
697 0.7.0 Getting the current user id
698 ---------------------------------
700 The Database.curuserid attribute has been removed.
702 Any code referencing this attribute should be replaced with a
703 call to Database.getuid().
706 0.7.0 ZRoundup changes
707 ----------------------
709 The templates in your tracker's html directory will need updating if you
710 wish to use ZRoundup. If you've not modified those files (or some of them),
711 you may just copy the new versions from the Roundup source in the
712 templates/classic/html directory.
714 If you have modified the html files, then you'll need to manually edit them
715 to change all occurances of special form variables from using the colon ":"
716 special character to the at "@" special character. That is, variables such
717 as::
719   :action :required :template :remove:messages ...
721 should become::
723   @action @required @template @remove@messages ...
725 Note that ``tal:`` statements are unaffected. So are TAL expression type
726 prefixes such as ``python:`` and ``string:``. Please ask on the
727 roundup-users mailing list for help if you're unsure.
730 0.7.0 Edit collision detection
731 ------------------------------
733 Roundup now detects collisions with editing in the web interface (that is,
734 two people editing the same item at the same time).
736 You must copy the ``_generic.collision.html`` file from Roundup source in
737 the ``templates/classic/html`` directory. to your tracker's ``html``
738 directory.
741 Migrating from 0.6.x to 0.6.3
742 =============================
744 0.6.3 Configuration
745 -------------------
747 You will need to copy the file::
749   templates/classic/detectors/__init__.py
751 to your tracker's ``detectors`` directory, replacing the one already there.
752 This fixes a couple of bugs in that file.
756 Migrating from 0.5 to 0.6
757 =========================
760 0.6.0 Configuration
761 -------------------
763 Introduced EMAIL_FROM_TAG config variable. This value is inserted into
764 the From: line of nosy email. If the sending user is "Foo Bar", the
765 From: line is usually::
767      "Foo Bar" <issue_tracker@tracker.example>
769 the EMAIL_FROM_TAG goes inside the "Foo Bar" quotes like so::
771      "Foo Bar EMAIL_FROM_TAG" <issue_tracker@tracker.example>
773 I've altered the mechanism in the detectors __init__.py module so that it
774 doesn't cross-import detectors from other trackers (if you run more than one
775 in a single roundup-server). This change means that you'll need to copy the
776 __init__.py from roundup/templates/classic/detectors/__init__.py to your
777 <tracker home>/detectors/__init__.py. Don't worry, the "classic" __init__ is a
778 one-size-fits-all, so it'll work even if you've added/removed detectors.
780 0.6.0 Templating changes
781 ------------------------
783 The ``user.item`` template (in the tracker home "templates" directory)
784 needs to have the following hidden variable added to its form (between the
785 ``<form...>`` and ``</form>`` tags::
787   <input type="hidden" name=":template" value="item">
790 0.6.0 Form handling changes
791 ---------------------------
793 Roundup's form handling capabilities have been significantly expanded. This
794 should not affect users of 0.5 installations - but if you find you're
795 getting errors from form submissions, please ask for help on the Roundup
796 users mailing list:
798   http://lists.sourceforge.net/lists/listinfo/roundup-users
800 See the customisation doc section on `Form Values`__ for documentation of the
801 new form variables possible.
803 __ customizing.html#form-values
806 0.6.0 Multilingual character set support
807 ----------------------------------------
809 Added internationalization support. This is done via encoding all data
810 stored in roundup database to utf-8 (unicode encoding). To support utf-8 in
811 web interface you should add the folowing line to your tracker's html/page
812 and html/_generic.help files inside <head> tag::
813   
814     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
816 Since latin characters in utf-8 have the same codes as in ASCII table, this
817 modification is optional for users who use only plain latin characters. 
819 After this modification, you will be able to see and enter any world
820 character via web interface. Data received via mail interface also converted
821 to utf-8, however only new messages will be converted. If your roundup
822 database contains some of non-ASCII characters in one of 8-bit encoding,
823 they will not be visible in new unicode environment. Some of such data (e.g.
824 user names, keywords, etc)  can be edited by administrator, the others
825 (e.g. messages' contents) is not editable via web interface. Currently there
826 is no tool for converting such data, the only solution is to close
827 appropriate old issues and create new ones with the same content.
830 0.6.0 User timezone support
831 ---------------------------
833 From version 0.6.0 roundup supports displaying of Date data in user' local
834 timezone if he/she has provided timezone information. To make it possible
835 some modification to tracker's schema and HTML templates are required.
836 First you must add string property 'timezone' to user class in dbinit.py
837 like this::
838   
839     user = Class(db, "user", 
840                     username=String(),   password=Password(),
841                     address=String(),    realname=String(), 
842                     phone=String(),      organisation=String(),
843                     alternate_addresses=String(),
844                     queries=Multilink('query'), roles=String(),
845                     timezone=String())
846   
847 And second - html interface. Add following lines to
848 $TRACKER_HOME/html/user.item template::
849   
850      <tr>
851       <th>Timezone</th>
852       <td tal:content="structure context/timezone/field">timezone</td>
853      </tr>
855 After that all users should be able to provide their timezone information.
856 Timezone should be a positive or negative integer - offset from GMT.
858 After providing timezone, roundup will show all dates values, found in web
859 and mail interfaces in local time. It will also accept any Date info in
860 local time, convert and store it in GMT.
863 0.6.0 Search page structure
864 ---------------------------
866 In order to accomodate query editing the search page has been restructured. If
867 you want to provide your users with query editing, you should update your
868 search page using the macros detailed in the customisation doc section
869 `Searching on categories`__.
871 __ customizing.html#searching-on-categories
873 Also, the url field in the query class no longer starts with a '?'. You'll need
874 to remove this question mark from the url field to support queries. There's
875 a script in the "tools" directory called ``migrate-queries.py`` that should
876 automatically change any existing queries for you. As always, make a backup
877 of your database before running such a script.
880 0.6.0 Notes for metakit backend users
881 -------------------------------------
883 Roundup 0.6.0 introduced searching on ranges of dates and intervals. To
884 support it, some modifications to interval storing routine were made. So if
885 your tracker uses metakit backend and your db schema contains intervals
886 property, searches on that property will not be accurate for db items that
887 was stored before roundup' upgrade. However all new records should be
888 searchable on intervals.
890 It is possible to convert your database to new format: you can export and
891 import back all your data (consult "Migrating backends" in "Maintenance"
892 documentation). After this operation all your interval properties should
893 become searchable.
895 Users of backends others than metakit should not worry about this issue.
898 Migrating from 0.4.x to 0.5.0
899 =============================
901 This has been a fairly major revision of Roundup:
903 1. Brand new, much more powerful, flexible, tasty and nutritious templating.
904    Unfortunately, this means all your current templates are useless. Hopefully
905    the new documentation and examples will be enough to help you make the
906    transition. Please don't hesitate to ask on roundup-users for help (or
907    complete conversions if you're completely stuck)!
908 2. The database backed got a lot more flexible, allowing Metakit and SQL
909    databases! The only decent SQL database implemented at present is sqlite,
910    but others shouldn't be a whole lot more work.
911 3. A brand new, highly flexible and much more robust security system including
912    a system of Permissions, Roles and Role assignments to users. You may now
913    define your own Permissions that may be checked in CGI transactions.
914 4. Journalling has been made less storage-hungry, so has been turned on
915    by default *except* for author, recipient and nosy link/unlink events. You
916    are advised to turn it off in your trackers too.
917 5. We've changed the terminology from "instance" to "tracker", to ease the
918    learning curve/impact for new users.
919 6. Because of the above changes, the tracker configuration has seen some
920    major changes. See below for the details.
922 Please, **back up your database** before you start the migration process. This
923 is as simple as copying the "db" directory and all its contents from your
924 tracker to somewhere safe.
927 0.5.0 Configuration
928 -------------------
930 First up, rename your ``instance_config.py`` file to just ``config.py``.
932 Then edit your tracker's ``__init__.py`` module. It'll currently look
933 like this::
935  from instance_config import *
936  try:
937      from dbinit import *
938  except ImportError:
939      pass # in installdir (probably :)
940  from interfaces import *
942 and it needs to be::
944  import config
945  from dbinit import open, init
946  from interfaces import Client, MailGW
948 Due to the new templating having a top-level ``page`` that defines links for
949 searching, indexes, adding items etc, the following variables are no longer
950 used:
952 - HEADER_INDEX_LINKS
953 - HEADER_ADD_LINKS
954 - HEADER_SEARCH_LINKS
955 - SEARCH_FILTERS
956 - DEFAULT_INDEX
957 - UNASSIGNED_INDEX
958 - USER_INDEX
959 - ISSUE_FILTER
961 The new security implementation will require additions to the dbinit module,
962 but also removes the need for the following tracker config variables:
964 - ANONYMOUS_ACCESS
965 - ANONYMOUS_REGISTER
967 but requires two new variables which define the Roles assigned to users who
968 register through the web and e-mail interfaces:
970 - NEW_WEB_USER_ROLES
971 - NEW_EMAIL_USER_ROLES
973 in both cases, 'User' is a good initial setting. To emulate
974 ``ANONYMOUS_ACCESS='deny'``, remove all "View" Permissions from the
975 "Anonymous" Role. To emulate ``ANONYMOUS_REGISTER='deny'``, remove the "Web
976 Registration" and/or the "Email Registration" Permission from the "Anonymous"
977 Role. See the section on customising security in the `customisation
978 documentation`_ for more information.
980 Finally, the following config variables have been renamed to make more sense:
982 - INSTANCE_HOME -> TRACKER_HOME
983 - INSTANCE_NAME -> TRACKER_NAME
984 - ISSUE_TRACKER_WEB -> TRACKER_WEB
985 - ISSUE_TRACKER_EMAIL -> TRACKER_EMAIL
988 0.5.0 Schema Specification
989 --------------------------
991 0.5.0 Database backend changes
992 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
994 Your select_db module in your tracker has changed a fair bit. Where it used
995 to contain::
997  # WARNING: DO NOT EDIT THIS FILE!!!
998  from roundup.backends.back_anydbm import Database
1000 it must now contain::
1002  # WARNING: DO NOT EDIT THIS FILE!!!
1003  from roundup.backends.back_anydbm import Database, Class, FileClass, IssueClass
1005 Yes, I realise the irony of the "DO NOT EDIT THIS FILE" statement :)
1006 Note the addition of the Class, FileClass, IssueClass imports. These are very
1007 important, as they're going to make the next change work too. You now need to
1008 modify the top of the dbinit module in your tracker from::
1010  import instance_config
1011  from roundup import roundupdb
1012  from select_db import Database
1014  from roundup.roundupdb import Class, FileClass
1016  class Database(roundupdb.Database, select_db.Database):
1017      ''' Creates a hybrid database from:
1018           . the selected database back-end from select_db
1019           . the roundup extensions from roundupdb
1020      '''
1021      pass
1023  class IssueClass(roundupdb.IssueClass):
1024      ''' issues need the email information
1025      '''
1026      pass
1028 to::
1030  import config
1031  from select_db import Database, Class, FileClass, IssueClass
1033 Yes, remove the Database and IssueClass definitions and those other imports.
1034 They're not needed any more!
1036 Look for places in dbinit.py where ``instance_config`` is used too, and
1037 rename them ``config``.
1040 0.5.0 Journalling changes
1041 ~~~~~~~~~~~~~~~~~~~~~~~~~
1043 Journalling has been optimised for storage. Journalling of links has been
1044 turned back on by default. If your tracker has a large user base, you may wish
1045 to turn off journalling of nosy list, message author and message recipient
1046 link and unlink events. You do this by adding ``do_journal='no'`` to the Class
1047 initialisation in your dbinit. For example, your *msg* class initialisation
1048 probably looks like this::
1050     msg = FileClass(db, "msg",
1051                     author=Link("user"), recipients=Multilink("user"),
1052                     date=Date(),         summary=String(),
1053                     files=Multilink("file"),
1054                     messageid=String(),  inreplyto=String())
1056 to turn off journalling of author and recipient link events, add
1057 ``do_journal='no'`` to the ``author=Link("user")`` part of the statement,
1058 like so::
1060     msg = FileClass(db, "msg",
1061                     author=Link("user", do_journal='no'),
1062                     recipients=Multilink("user", do_journal='no'),
1063                     date=Date(),         summary=String(),
1064                     files=Multilink("file"),
1065                     messageid=String(),  inreplyto=String())
1067 Nosy list link event journalling is actually turned off by default now. If you
1068 want to turn it on, change to your issue class' nosy list, change its
1069 definition from::
1071     issue = IssueClass(db, "issue",
1072                     assignedto=Link("user"), topic=Multilink("keyword"),
1073                     priority=Link("priority"), status=Link("status"))
1075 to::
1077     issue = IssueClass(db, "issue", nosy=Multilink("user", do_journal='yes'),
1078                     assignedto=Link("user"), topic=Multilink("keyword"),
1079                     priority=Link("priority"), status=Link("status"))
1081 noting that your definition of the nosy Multilink will override the normal one.
1084 0.5.0 User schema changes
1085 ~~~~~~~~~~~~~~~~~~~~~~~~~
1087 Users have two more properties, "queries" and "roles". You'll have something
1088 like this in your dbinit module now::
1090     user = Class(db, "user",
1091                     username=String(),   password=Password(),
1092                     address=String(),    realname=String(),
1093                     phone=String(),      organisation=String(),
1094                     alternate_addresses=String())
1095     user.setkey("username")
1097 and you'll need to add the new properties and the new "query" class to it
1098 like so::
1100     query = Class(db, "query",
1101                     klass=String(),     name=String(),
1102                     url=String())
1103     query.setkey("name")
1105     # Note: roles is a comma-separated string of Role names
1106     user = Class(db, "user",
1107                     username=String(),   password=Password(),
1108                     address=String(),    realname=String(),
1109                     phone=String(),      organisation=String(),
1110                     alternate_addresses=String(),
1111                     queries=Multilink('query'), roles=String())
1112     user.setkey("username")
1114 The "queries" property is used to store off the user's favourite database
1115 queries. The "roles" property is explained below in `0.5.0 Security
1116 Settings`_.
1119 0.5.0 Security Settings
1120 ~~~~~~~~~~~~~~~~~~~~~~~
1122 See the `security documentation`_ for an explanation of how the new security
1123 system works. In a nutshell though, the security is handled as a four step
1124 process:
1126 1. Permissions are defined as having a name and optionally a hyperdb class
1127    they're specific to,
1128 2. Roles are defined that have one or more Permissions,
1129 3. Users are assigned Roles in their "roles" property, and finally
1130 4. Roundup checks that users have appropriate Permissions at appropriate times
1131    (like editing issues).
1133 Your tracker dbinit module's *open* function now has to define any
1134 Permissions that are specific to your tracker, and also the assignment
1135 of Permissions to Roles. At the moment, your open function
1136 ends with::
1138     import detectors
1139     detectors.init(db)
1141     return db
1143 and what we need to do is insert some commands that will set up the security
1144 parameters. Right above the ``import detectors`` line, you'll want to insert
1145 these lines::
1147     #
1148     # SECURITY SETTINGS
1149     #
1150     # new permissions for this schema
1151     for cl in 'issue', 'file', 'msg', 'user':
1152         db.security.addPermission(name="Edit", klass=cl,
1153             description="User is allowed to edit "+cl)
1154         db.security.addPermission(name="View", klass=cl,
1155             description="User is allowed to access "+cl)
1157     # Assign the access and edit permissions for issue, file and message
1158     # to regular users now
1159     for cl in 'issue', 'file', 'msg':
1160         p = db.security.getPermission('View', cl)
1161         db.security.addPermissionToRole('User', p)
1162         p = db.security.getPermission('Edit', cl)
1163         db.security.addPermissionToRole('User', p)
1164     # and give the regular users access to the web and email interface
1165     p = db.security.getPermission('Web Access')
1166     db.security.addPermissionToRole('User', p)
1167     p = db.security.getPermission('Email Access')
1168     db.security.addPermissionToRole('User', p)
1170     # May users view other user information? Comment these lines out
1171     # if you don't want them to
1172     p = db.security.getPermission('View', 'user')
1173     db.security.addPermissionToRole('User', p)
1175     # Assign the appropriate permissions to the anonymous user's Anonymous
1176     # Role. Choices here are:
1177     # - Allow anonymous users to register through the web
1178     p = db.security.getPermission('Web Registration')
1179     db.security.addPermissionToRole('Anonymous', p)
1180     # - Allow anonymous (new) users to register through the email gateway
1181     p = db.security.getPermission('Email Registration')
1182     db.security.addPermissionToRole('Anonymous', p)
1183     # - Allow anonymous users access to the "issue" class of data
1184     #   Note: this also grants access to related information like files,
1185     #         messages, statuses etc that are linked to issues
1186     #p = db.security.getPermission('View', 'issue')
1187     #db.security.addPermissionToRole('Anonymous', p)
1188     # - Allow anonymous users access to edit the "issue" class of data
1189     #   Note: this also grants access to create related information like
1190     #         files and messages etc that are linked to issues
1191     #p = db.security.getPermission('Edit', 'issue')
1192     #db.security.addPermissionToRole('Anonymous', p)
1194     # oh, g'wan, let anonymous access the web interface too
1195     p = db.security.getPermission('Web Access')
1196     db.security.addPermissionToRole('Anonymous', p)
1198 Note in the comments there the places where you might change the permissions
1199 to restrict users or grant users more access. If you've created additional
1200 classes that users should be able to edit and view, then you should add them
1201 to the "new permissions for this schema" section at the start of the security
1202 block. Then add them to the "Assign the access and edit permissions" section
1203 too, so people actually have the new Permission you've created.
1205 One final change is needed that finishes off the security system's
1206 initialisation. We need to add a call to ``db.post_init()`` at the end of the
1207 dbinit open() function. Add it like this::
1209     import detectors
1210     detectors.init(db)
1212     # schema is set up - run any post-initialisation
1213     db.post_init()
1214     return db
1216 You may verify the setup of Permissions and Roles using the new
1217 "``roundup-admin security``" command.
1220 0.5.0 User changes
1221 ~~~~~~~~~~~~~~~~~~
1223 To support all those schema changes, you'll need to massage your user database
1224 a little too, to:
1226 1. make sure there's an "anonymous" user - this user is mandatory now and is
1227    the one that unknown users are logged in as.
1228 2. make sure all users have at least one Role.
1230 If you don't have the "anonymous" user, create it now with the command::
1232   roundup-admin create user username=anonymous roles=Anonymous
1234 making sure the capitalisation is the same as above. Once you've done that,
1235 you'll need to set the roles property on all users to a reasonable default.
1236 The admin user should get "Admin", the anonymous user "Anonymous"
1237 and all other users "User". The ``fixroles.py`` script in the tools directory
1238 will do this. Run it like so (where python is your python 2+ binary)::
1240   python tools/fixroles.py -i <tracker home> fixroles
1244 0.5.0 CGI interface changes
1245 ---------------------------
1247 The CGI interface code was completely reorganised and largely rewritten. The
1248 end result is that this section of your tracker interfaces module will need
1249 changing from::
1251  from roundup import cgi_client, mailgw
1252  from roundup.i18n import _
1253  
1254  class Client(cgi_client.Client):
1255      ''' derives basic CGI implementation from the standard module,
1256          with any specific extensions
1257      '''
1258      pass
1260 to::
1262  from roundup import mailgw
1263  from roundup.cgi import client
1264  
1265  class Client(client.Client): 
1266      ''' derives basic CGI implementation from the standard module,
1267          with any specific extensions
1268      '''
1269      pass
1271 You will also need to install the new version of roundup.cgi from the source
1272 cgi-bin directory if you're using it.
1275 0.5.0 HTML templating
1276 ---------------------
1278 You'll want to make a backup of your current tracker html directory. You
1279 should then copy the html directory from the Roundup source "classic" template
1280 and modify it according to your local schema changes.
1282 If you need help with the new templating system, please ask questions on the
1283 roundup-users mailing list (available through the roundup project page on
1284 sourceforge, http://roundup.sf.net/)
1287 0.5.0 Detectors
1288 ---------------
1290 The nosy reactor has been updated to handle the tracker not having an
1291 "assignedto" property on issues. You may want to copy it into your tracker's
1292 detectors directory. Chances are you've already fixed it though :)
1295 Migrating from 0.4.1 to 0.4.2
1296 =============================
1298 0.4.2 Configuration
1299 -------------------
1300 The USER_INDEX definition introduced in 0.4.1 was too restrictive in its
1301 allowing replacement of 'assignedto' with the user's userid. Users must change
1302 the None value of 'assignedto' to 'CURRENT USER' (the string, in quotes) for
1303 the replacement behaviour to occur now.
1305 The new configuration variables are:
1307 - EMAIL_KEEP_QUOTED_TEXT 
1308 - EMAIL_LEAVE_BODY_UNCHANGED
1309 - ADD_RECIPIENTS_TO_NOSY
1311 See the sample configuration files in::
1313  <roundup source>/roundup/templates/classic/instance_config.py
1315 and::
1317  <roundup source>/roundup/templates/extended/instance_config.py
1319 and the `customisation documentation`_ for information on how they're used.
1322 0.4.2 Changes to detectors
1323 --------------------------
1324 You will need to copy the detectors from the distribution into your instance
1325 home "detectors" directory. If you used the classic schema, the detectors
1326 are in::
1328  <roundup source>/roundup/templates/classic/detectors/
1330 If you used the extended schema, the detectors are in::
1332  <roundup source>/roundup/templates/extended/detectors/
1334 The change means that schema-specific code has been removed from the
1335 mail gateway and cgi interface and made into auditors:
1337 - nosyreactor.py has now got an updatenosy auditor which updates the nosy
1338   list with author, recipient and assignedto information.
1339 - statusauditor.py makes the unread or resolved -> chatting changes and
1340   presets the status of an issue to unread.
1342 There's also a bug or two fixed in the nosyreactor code.
1344 0.4.2 HTML templating changes
1345 -----------------------------
1346 The link() htmltemplate function now has a "showid" option for links and
1347 multilinks. When true, it only displays the linked item id as the anchor
1348 text. The link value is displayed as a tooltip using the title anchor
1349 attribute. To use in eg. the superseder field, have something like this::
1351    <td>
1352     <display call="field('superseder', showid=1)">
1353     <display call="classhelp('issue', 'id,title', label='list', width=500)">
1354     <property name="superseder">
1355      <br>View: <display call="link('superseder', showid=1)">
1356     </property>
1357    </td>
1359 The stylesheets have been cleaned up too. You may want to use the newer
1360 versions in::
1362  <roundup source>/roundup/templates/<template>/html/default.css
1366 Migrating from 0.4.0 to 0.4.1
1367 =============================
1369 0.4.1 Files storage
1370 -------------------
1372 Messages and files from newly created issues will be put into subdierectories
1373 in thousands e.g. msg123 will be put into files/msg/0/msg123, file2003
1374 will go into files/file/2/file2003. Previous messages are still found, but
1375 could be put into this structure.
1377 0.4.1 Configuration
1378 -------------------
1380 To allow more fine-grained access control, the variable used to check
1381 permission to auto-register users in the mail gateway is now called
1382 ANONYMOUS_REGISTER_MAIL rather than overloading ANONYMOUS_REGISTER. If the
1383 variable doesn't exist, then ANONYMOUS_REGISTER is tested as before.
1385 Configuring the links in the web header is now easier too. The following
1386 variables have been added to the classic instance_config.py::
1388   HEADER_INDEX_LINKS   - defines the "index" links to be made available
1389   HEADER_ADD_LINKS     - defines the "add" links
1390   DEFAULT_INDEX        - specifies the index view for DEFAULT
1391   UNASSIGNED_INDEX     - specifies the index view for UNASSIGNED
1392   USER_INDEX           - specifies the index view for USER
1394 See the <roundup source>/roundup/templates/classic/instance_config.py for more
1395 information - including how the variables are to be set up. Most users will
1396 just be able to copy the variables from the source to their instance home. If
1397 you've modified the header by changing the source of the interfaces.py file in
1398 the instance home, you'll need to remove that customisation and move it into
1399 the appropriate variables in instance_config.py.
1401 The extended schema has similar variables added too - see the source for more
1402 info.
1404 0.4.1 Alternate E-Mail Addresses
1405 --------------------------------
1407 If you add the property "alternate_addresses" to your user class, your users
1408 will be able to register alternate email addresses that they may use to
1409 communicate with roundup as. All email from roundup will continue to be sent
1410 to their primary address.
1412 If you have not edited the dbinit.py file in your instance home directory,
1413 you may simply copy the new dbinit.py file from the core code. If you used
1414 the classic schema, the interfaces file is in::
1416  <roundup source>/roundup/templates/classic/dbinit.py
1418 If you used the extended schema, the file is in::
1420  <roundup source>/roundup/templates/extended/dbinit.py 
1422 If you have modified your dbinit.py file, you need to edit the dbinit.py
1423 file in your instance home directory. Find the lines which define the user
1424 class::
1426     user = Class(db, "msg",
1427                     username=String(),   password=Password(),
1428                     address=String(),    realname=String(), 
1429                     phone=String(),      organisation=String(),
1430                     alternate_addresses=String())
1432 You will also want to add the property to the user's details page. The
1433 template for this is the "user.item" file in your instance home "html"
1434 directory. Similar to above, you may copy the file from the roundup source if
1435 you haven't modified it. Otherwise, add the following to the template::
1437    <display call="multiline('alternate_addresses')">
1439 with appropriate labelling etc. See the standard template for an idea.
1443 Migrating from 0.3.x to 0.4.0
1444 =============================
1446 0.4.0 Message-ID and In-Reply-To addition
1447 -----------------------------------------
1448 0.4.0 adds the tracking of messages by message-id and allows threading
1449 using in-reply-to. Most e-mail clients support threading using this
1450 feature, and we hope to add support for it to the web gateway. If you
1451 have not edited the dbinit.py file in your instance home directory, you may
1452 simply copy the new dbinit.py file from the core code. If you used the
1453 classic schema, the interfaces file is in::
1455  <roundup source>/roundup/templates/classic/dbinit.py
1457 If you used the extended schema, the file is in::
1459  <roundup source>/roundup/templates/extended/dbinit.py 
1461 If you have modified your dbinit.py file, you need to edit the dbinit.py
1462 file in your instance home directory. Find the lines which define the msg
1463 class::
1465     msg = FileClass(db, "msg",
1466                     author=Link("user"), recipients=Multilink("user"),
1467                     date=Date(),         summary=String(),
1468                     files=Multilink("file"))
1470 and add the messageid and inreplyto properties like so::
1472     msg = FileClass(db, "msg",
1473                     author=Link("user"), recipients=Multilink("user"),
1474                     date=Date(),         summary=String(),
1475                     files=Multilink("file"),
1476                     messageid=String(),  inreplyto=String())
1478 Also, configuration is being cleaned up. This means that your dbinit.py will
1479 also need to be changed in the open function. If you haven't changed your
1480 dbinit.py, the above copy will be enough. If you have, you'll need to change
1481 the line (round line 50)::
1483     db = Database(instance_config.DATABASE, name)
1485 to::
1487     db = Database(instance_config, name)
1490 0.4.0 Configuration
1491 --------------------
1492 ``TRACKER_NAME`` and ``EMAIL_SIGNATURE_POSITION`` have been added to the
1493 instance_config.py. The simplest solution is to copy the default values
1494 from template in the core source.
1496 The mail gateway now checks ``ANONYMOUS_REGISTER`` to see if unknown users
1497 are to be automatically registered with the tracker. If it is set to "deny"
1498 then unknown users will not have access. If it is set to "allow" they will be
1499 automatically registered with the tracker.
1502 0.4.0 CGI script roundup.cgi
1503 ----------------------------
1504 The CGI script has been updated with some features and a bugfix, so you should
1505 copy it from the roundup cgi-bin source directory again. Make sure you update
1506 the ROUNDUP_INSTANCE_HOMES after the copy.
1509 0.4.0 Nosy reactor
1510 ------------------
1511 The nosy reactor has also changed - copy the nosyreactor.py file from the core
1512 source::
1514    <roundup source>/roundup/templates/<template>/detectors/nosyreactor.py
1516 to your instance home "detectors" directory.
1519 0.4.0 HTML templating
1520 ---------------------
1521 The field() function was incorrectly implemented - links and multilinks now
1522 display as text fields when rendered using field(). To display a menu (drop-
1523 down or select box) you need to use the menu() function.
1527 Migrating from 0.2.x to 0.3.x
1528 =============================
1530 0.3.x Cookie Authentication changes
1531 -----------------------------------
1532 0.3.0 introduces cookie authentication - you will need to copy the
1533 interfaces.py file from the roundup source to your instance home to enable
1534 authentication. If you used the classic schema, the interfaces file is in::
1536  <roundup source>/roundup/templates/classic/interfaces.py
1538 If you used the extended schema, the file is in::
1540  <roundup source>/roundup/templates/extended/interfaces.py
1542 If you have modified your interfaces.Client class, you will need to take
1543 note of the login/logout functionality provided in roundup.cgi_client.Client
1544 (classic schema) or roundup.cgi_client.ExtendedClient (extended schema) and
1545 modify your instance code apropriately.
1548 0.3.x Password encoding
1549 -----------------------
1550 This release also introduces encoding of passwords in the database. If you
1551 have not edited the dbinit.py file in your instance home directory, you may
1552 simply copy the new dbinit.py file from the core code. If you used the
1553 classic schema, the interfaces file is in::
1555  <roundup source>/roundup/templates/classic/dbinit.py
1557 If you used the extended schema, the file is in::
1559  <roundup source>/roundup/templates/extended/dbinit.py
1562 If you have modified your dbinit.py file, you may use encoded passwords:
1564 1. Edit the dbinit.py file in your instance home directory
1565    a. At the first code line of the open() function::
1567        from roundup.hyperdb import String, Date, Link, Multilink
1569       alter to include Password, as so::
1571        from roundup.hyperdb import String, Password, Date, Link, Multilink
1573    b. Where the password property is defined (around line 66)::
1575        user = Class(db, "user", 
1576                        username=String(),   password=String(),
1577                        address=String(),    realname=String(), 
1578                        phone=String(),      organisation=String())
1579        user.setkey("username")
1581       alter the "password=String()" to "password=Password()"::
1583        user = Class(db, "user", 
1584                        username=String(),   password=Password(),
1585                        address=String(),    realname=String(), 
1586                        phone=String(),      organisation=String())
1587        user.setkey("username")
1589 2. Any existing passwords in the database will remain cleartext until they
1590    are edited. It is recommended that at a minimum the admin password be
1591    changed immediately::
1593       roundup-admin -i <instance home> set user1 password=<new password>
1596 0.3.x Configuration
1597 -------------------
1598 FILTER_POSITION, ANONYMOUS_ACCESS, ANONYMOUS_REGISTER have been added to
1599 the instance_config.py. Simplest solution is to copy the default values from
1600 template in the core source.
1602 MESSAGES_TO_AUTHOR has been added to the IssueClass in dbinit.py. Set to 'yes'
1603 to send nosy messages to the author. Default behaviour is to not send nosy
1604 messages to the author. You will need to add MESSAGES_TO_AUTHOR to your
1605 dbinit.py in your instance home.
1608 0.3.x CGI script roundup.cgi
1609 ----------------------------
1610 There have been some structural changes to the roundup.cgi script - you will
1611 need to install it again from the cgi-bin directory of the source
1612 distribution. Make sure you update the ROUNDUP_INSTANCE_HOMES after the
1613 copy.
1616 .. _`customisation documentation`: customizing.html
1617 .. _`security documentation`: security.html
1618 .. _`administration guide`: admin_guide.html