Code

Allow user to choose the tracker template for demo.
[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::
17 Migrating from 1.4.x to 1.4.7
18 =============================
20 Several security issues were addressed in this release. Some aspects of your
21 trackers may no longer function depending on your local customisations. Core
22 functionality that will need to be modified:
24 Grant the "retire" permission to users for their queries
25 --------------------------------------------------------
27 Users will no longer be able to retire their own queries. To remedy this you
28 will need to add the following to your tracker's ``schema.py`` just under the
29 line that grants them permission to edit their own queries::
31    p = db.security.addPermission(name='Edit', klass='query', check=edit_query,
32       description="User is allowed to edit their queries")
33    db.security.addPermissionToRole('User', p)
34  + p = db.security.addPermission(name='Retire', klass='query', check=edit_query,
35  +    description="User is allowed to retire their queries")
36  + db.security.addPermissionToRole('User', p)
37    p = db.security.addPermission(name='Create', klass='query',
38       description="User is allowed to create queries")
39    db.security.addPermissionToRole('User', p)
41 The lines marked "+" should be added, minus the "+" sign.
44 Fix the "retire" link in the users list for admin users
45 -------------------------------------------------------
47 The "retire" link found in the file ``html/users.index.html``::
49   <td tal:condition="context/is_edit_ok">
50    <a tal:attributes="href string:user${user/id}?@action=retire&@template=index"
51     i18n:translate="">retire</a>
53 Should be replaced with::
55   <td tal:condition="context/is_retire_ok">
56      <form style="padding:0"
57            tal:attributes="action string:user${user/id}">
58       <input type="hidden" name="@template" value="index">
59       <input type="hidden" name="@action" value="retire">
60       <input type="submit" value="retire" i18n:attributes="value">
61      </form>
64 Fix for Python 2.6+ users
65 -------------------------
67 If you use Python 2.6 you should edit your tracker's
68 ``detectors/nosyreaction.py`` file to change::
70    import sets
72 at the top to::
74    from roundup.anypy.sets_ import set
76 and then all instances of ``sets.Set()`` to ``set()`` in the later code.
80 Trackers currently allowing HTML file uploading
81 -----------------------------------------------
83 Trackers which wish to continue to allow uploading of HTML content against issues
84 will need to set a new configuration variable in the ``[web]`` section of the
85 tracker's ``config.ini`` file:
87    # Setting this option enables Roundup to serve uploaded HTML
88    # file content *as HTML*. This is a potential security risk
89    # and is therefore disabled by default. Set to 'yes' if you
90    # trust *all* users uploading content to your tracker.
91    # Allowed values: yes, no
92    # Default: no
93    allow_html_file = no
97 Migrating from 1.4.2 to 1.4.3
98 =============================
100 If you are using the MySQL backend you will need to replace some indexes
101 that may have been created by version 1.4.2.
103 You should to access your MySQL database directly and remove any indexes
104 with a name ending in "_key_retired_idx". You should then re-add them with
105 the same spec except the key column name needs a size. So an index on
106 "_user (__retired, _name)" should become "_user (__retired, _name(255))".
109 Migrating from 1.4.x to 1.4.2
110 =============================
112 You should run the "roundup-admin migrate" command for your tracker once
113 you've installed the latest codebase. 
115 Do this before you use the web, command-line or mail interface and before
116 any users access the tracker.
118 This command will respond with either "Tracker updated" (if you've not
119 previously run it on an RDBMS backend) or "No migration action required"
120 (if you have run it, or have used another interface to the tracker,
121 or are using anydbm).
123 It's safe to run this even if it's not required, so just get into the
124 habit.
127 Migrating from 1.3.3 to 1.4.0
128 =============================
130 Value of the "refwd_re" tracker configuration option (section "mailgw")
131 is treated as UTF-8 string.  In previous versions, it was ISO8859-1.
133 If you have running trackers based on the classic template, please
134 update the messagesummary detector as follows::
136     --- detectors/messagesummary.py 17 Apr 2003 03:26:38 -0000      1.1
137     +++ detectors/messagesummary.py 3 Apr 2007 06:47:21 -0000       1.2
138     @@ -8,7 +8,7 @@
139      if newvalues.has_key('summary') or not newvalues.has_key('content'):
140          return
142     -    summary, content = parseContent(newvalues['content'], 1, 1)
143     +    summary, content = parseContent(newvalues['content'], config=db.config)
144      newvalues['summary'] = summary
146 In the latest version we have added some database indexes to the
147 SQL-backends (mysql, postgresql, sqlite) for speeding up building the
148 roundup-index for full-text search. We recommend that you create the
149 following database indexes on the database by hand::
151  CREATE INDEX words_by_id ON __words (_textid)
152  CREATE UNIQUE INDEX __textids_by_props ON __textids (_class, _itemid, _prop)
154 Migrating from 1.2.x to 1.3.0
155 =============================
157 1.3.0 Web interface changes
158 ---------------------------
160 Some of the HTML files in the "classic" and "minimal" tracker templates
161 were changed to fix some bugs and clean them up. You may wish to compare
162 them to the HTML files in your tracker and apply any changes.
165 Migrating from 1.1.2 to 1.2.0
166 =============================
168 1.2.0 Sorting and grouping by multiple properties
169 -------------------------------------------------
171 Starting with this version, sorting and grouping by multiple properties
172 is possible. This means that request.sort and request.group are now
173 lists. This is reflected in several places:
175  * ``renderWith`` now has list attributes for ``sort`` and ``group``,
176    where you previously wrote::
177    
178     renderWith(... sort=('-', 'activity'), group=('+', 'priority')
180    you write now::
182     renderWith(... sort=[('-', 'activity')], group=[('+', 'priority')]
184  * In templates that permit to edit sorting/grouping, request.sort and
185    request.group are (possibly empty) lists. You can now sort and group
186    by multiple attributes. For an example, see the classic template. You
187    may want search for the variable ``n_sort`` which can be set to the
188    number of sort/group properties.
190  * Templates that diplay new headlines for each group of items with
191    equal group properties can now use the modified ``batch.propchanged``
192    method that can take several properties which are checked for
193    changes. See the example in the classic template which makes use of
194    ``batch.propchanged``.
196 Migrating from 1.1.0 to 1.1.1
197 =============================
199 1.1.1 "Clear this message"
200 --------------------------
202 In 1.1.1, the standard ``page.html`` template includes a "clear this message"
203 link in the green "ok" message bar that appears after a successful edit
204 (or other) action.
206 To include this in your tracker, change the following in your ``page.html``
207 template::
209  <p tal:condition="options/ok_message | nothing" class="ok-message"
210     tal:repeat="m options/ok_message" tal:content="structure m">error</p>
212 to be::
214  <p tal:condition="options/ok_message | nothing" class="ok-message">
215    <span tal:repeat="m options/ok_message"
216       tal:content="structure string:$m <br/ > " />
217     <a class="form-small" tal:attributes="href request/current_url"
218        i18n:translate="">clear this message</a>
219  </p>
222 If you implemented the "clear this message" in your 1.1.0 tracker, then you
223 should change it to the above and it will work much better!
226 Migrating from 1.0.x to 1.1.0
227 =============================
229 1.1 Login "For Session Only"
230 ----------------------------
232 In 1.1, web logins are alive for the length of a session only, *unless* you
233 add the following to the login form in your tracker's ``page.html``::
235     <input type="checkbox" name="remember" id="remember">
236     <label for="remember" i18n:translate="">Remember me?</label><br>
238 See the classic tracker ``page.html`` if you're unsure where this should
239 go.
242 1.1 Query Display Name
243 ----------------------
245 The ``dispname`` web variable has been renamed ``@dispname`` to avoid
246 clashing with other variables of the same name. If you are using the
247 display name feature, you will need to edit your tracker's ``page.html``
248 and ``issue.index.html`` pages to change ``dispname`` to ``@dispname``.
250 A side-effect of this change is that the renderWith method used in the
251 ``home.html`` page may now take a dispname argument.
254 1.1 "Clear this message"
255 ------------------------
257 In 1.1, the standard ``page.html`` template includes a "clear this message"
258 link in the green "ok" message bar that appears after a successful edit
259 (or other) action.
261 To include this in your tracker, change the following in your ``page.html``
262 template::
264  <p tal:condition="options/ok_message | nothing" class="ok-message"
265     tal:repeat="m options/ok_message" tal:content="structure m">error</p>
267 to be::
269  <p tal:condition="options/ok_message | nothing" class="ok-message">
270    <span tal:repeat="m options/ok_message"
271       tal:content="structure string:$m <br/ > " />
272     <a class="form-small" tal:attributes="href string:issue${context/id}"
273        i18n:translate="">clear this message</a>
274  </p>
277 Migrating from 0.8.x to 1.0
278 ===========================
280 1.0 New Query Permissions
281 -------------------------
283 New permissions are defined for query editing and viewing. To include these
284 in your tracker, you need to add these lines to your tracker's
285 ``schema.py``::
287  # Users should be able to edit and view their own queries. They should also
288  # be able to view any marked as not private. They should not be able to
289  # edit others' queries, even if they're not private
290  def view_query(db, userid, itemid):
291      private_for = db.query.get(itemid, 'private_for')
292      if not private_for: return True
293      return userid == private_for
294  def edit_query(db, userid, itemid):
295      return userid == db.query.get(itemid, 'creator')
296  p = db.security.addPermission(name='View', klass='query', check=view_query,
297      description="User is allowed to view their own and public queries")
298  db.security.addPermissionToRole('User', p)
299  p = db.security.addPermission(name='Edit', klass='query', check=edit_query,
300      description="User is allowed to edit their queries")
301  db.security.addPermissionToRole('User', p)
302  p = db.security.addPermission(name='Create', klass='query',
303      description="User is allowed to create queries")
304  db.security.addPermissionToRole('User', p)
306 and then remove 'query' from the line::
308  # Assign the access and edit Permissions for issue, file and message
309  # to regular users now
310  for cl in 'issue', 'file', 'msg', 'query', 'keyword':
312 so it looks like::
314  for cl in 'issue', 'file', 'msg', 'keyword':
317 Migrating from 0.8.0 to 0.8.3
318 =============================
320 0.8.3 Nosy Handling Changes
321 ---------------------------
323 A change was made to fix a bug in the ``nosyreaction.py`` standard
324 detector. To incorporate this fix in your trackers, you will need to copy
325 the ``nosyreaction.py`` file from the ``templates/classic/detectors``
326 directory of the source to your tracker's ``templates`` directory.
328 If you have modified the ``nosyreaction.py`` file from the standard
329 version, you will need to roll your changes into the new file.
332 Migrating from 0.7.1 to 0.8.0
333 =============================
335 You *must* fully uninstall previous Roundup version before installing
336 Roundup 0.8.0.  If you don't do that, ``roundup-admin install``
337 command may fail to function properly.
339 0.8.0 Backend changes
340 ---------------------
342 Backends 'bsddb' and 'bsddb3' are removed.  If you are using one of these,
343 you *must* migrate to another backend before upgrading.
346 0.8.0 API changes
347 -----------------
349 Class.safeget() was removed from the API. Test your item ids before calling
350 Class.get() instead.
353 0.8.0 New tracker layout
354 ------------------------
356 The ``config.py`` file has been replaced by ``config.ini``. You may use the
357 roundup-admin command "genconfig" to generate a new config file::
359   roundup-admin genconfig <tracker home>/config.ini
361 and modify the values therein based on the contents of your old config.py.
362 In most cases, the names of the config variables are the same.
364 The ``select_db.py`` file has been replaced by a file in the ``db``
365 directory called ``backend_name``. As you might guess, this file contains
366 just the name of the backend. To figure what the contents of yours should
367 be, use the following table:
369   ================================ =========================
370   ``select_db.py`` contents        ``backend_name`` contents
371   ================================ =========================
372   from back_anydbm import ...      anydbm
373   from back_metakit import ...     metakit
374   from back_sqlite import ...      sqlite
375   from back_mysql import ...       mysql
376   from back_postgresql import ...  postgresql
377   ================================ =========================
379 The ``dbinit.py`` file has been split into two new files,
380 ``initial_data.py`` and ``schema.py``. The contents of this file are:
382 ``initial_data.py``
383   You don't need one of these as your tracker is already initialised.
385 ``schema.py``
386   Copy the body of the ``def open(name=None)`` function from your old
387   tracker's ``dbinit.py`` file to this file. As the lines you're copying
388   aren't part of a function definition anymore, one level of indentation
389   needs to be removed (remove only the leading four spaces on each
390   line). 
392   The first few lines -- those starting with ``from roundup.hyperdb
393   import ...`` and the ``db = Database(config, name)`` line -- don't
394   need to be copied. Neither do the last few lines -- those starting
395   with ``import detectors``, down to ``return db`` inclusive.
397 You may remove the ``__init__.py`` module from the "detectors" directory as
398 it is no longer used.
400 There's a new way to write extension code for Roundup. If you have code in
401 an ``interfaces.py`` file you should move it. See the `customisation
402 documentation`_ for information about how extensions are now written.
403 Note that some older trackers may use ``interfaces.py`` to customise the
404 mail gateway behaviour. You will need to keep your ``interfaces.py`` file
405 if this is the case.
408 0.8.0 Permissions Changes
409 -------------------------
411 The creation of a new item in the user interfaces is now controlled by the
412 "Create" Permission. You will need to add an assignment of this Permission
413 to your users who are allowed to create items. The most common form of this
414 is the following in your ``schema.py`` added just under the current
415 assignation of the Edit Permission::
417     for cl in 'issue', 'file', 'msg', 'query', 'keyword':
418         p = db.security.getPermission('Create', cl)
419         db.security.addPermissionToRole('User', p)
421 You will need to explicitly let anonymous users access the web interface so
422 that regular users are able to see the login form. Note that almost all
423 trackers will need this Permission. The only situation where it's not
424 required is in a tracker that uses an HTTP Basic Authenticated front-end.
425 It's enabled by adding to your ``schema.py``::
427     p = db.security.getPermission('Web Access')
428     db.security.addPermissionToRole('Anonymous', p)
430 Finally, you will need to enable permission for your users to edit their
431 own details by adding the following to ``schema.py``::
433     # Users should be able to edit their own details. Note that this
434     # permission is limited to only the situation where the Viewed or
435     # Edited item is their own.
436     def own_record(db, userid, itemid):
437         '''Determine whether the userid matches the item being accessed.'''
438         return userid == itemid
439     p = db.security.addPermission(name='View', klass='user', check=own_record,
440         description="User is allowed to view their own user details")
441     p = db.security.addPermission(name='Edit', klass='user', check=own_record,
442         description="User is allowed to edit their own user details")
443     db.security.addPermissionToRole('User', p)
446 0.8.0 Use of TemplatingUtils
447 ----------------------------
449 If you used custom python functions in TemplatingUtils, they must
450 be moved from interfaces.py to a new file in the ``extensions`` directory. 
452 Each Function that should be available through TAL needs to be defined
453 as a toplevel function in the newly created file. Furthermore you
454 add an inititialization function, that registers the functions with the 
455 tracker.
457 If you find this too tedious, donfu wrote an automatic init function that
458 takes an existing TemplatingUtils class, and registers all class methods
459 that do not start with an underscore. The following hack should be placed
460 in the ``extensions`` directory alongside other extensions::
462     class TemplatingUtils:
463          # copy from interfaces.py
465     def init(tracker):
466          util = TemplatingUtils()
468          def setClient(tu):
469              util.client = tu.client
470              return util
472          def execUtil(name):
473              return lambda tu, *args, **kwargs: \
474                      getattr(setClient(tu), name)(*args, **kwargs)
476          for name in dir(util):
477              if callable(getattr(util, name)) and not name.startswith('_'):
478                   tracker.registerUtil(name, execUtil(name))
481 0.8.0 Logging Configuration
482 ---------------------------
484 See the `administration guide`_ for information about configuring the new
485 logging implemented in 0.8.0.
488 Migrating from 0.7.2 to 0.7.3
489 =============================
491 0.7.3 Configuration
492 -------------------
494 If you choose, you may specify the directory from which static files are
495 served (those which use the URL component ``@@file``). Currently the
496 directory defaults to the ``TEMPLATES`` configuration variable. You may
497 define a new variable, ``STATIC_FILES`` which overrides this value for
498 static files.
501 Migrating from 0.7.0 to 0.7.2
502 =============================
504 0.7.2 DEFAULT_TIMEZONE is now required
505 --------------------------------------
507 The DEFAULT_TIMEZONE configuration variable is now required. Add the
508 following to your tracker's ``config.py`` file::
510     # You may specify a different default timezone, for use when users do not
511     # choose their own in their settings.
512     DEFAULT_TIMEZONE = 0            # specify as numeric hour offest
515 Migrating from 0.7.0 to 0.7.1
516 =============================
518 0.7.1 Permission assignments
519 ----------------------------
521 If you allow anonymous access to your tracker, you might need to assign
522 some additional View (or Edit if your tracker is that open) permissions
523 to the "anonymous" user. To do so, find the code in your ``dbinit.py`` that
524 says::
526     for cl in 'issue', 'file', 'msg', 'query', 'keyword':
527         p = db.security.getPermission('View', cl)
528         db.security.addPermissionToRole('User', p)
529         p = db.security.getPermission('Edit', cl)
530         db.security.addPermissionToRole('User', p)
531     for cl in 'priority', 'status':
532         p = db.security.getPermission('View', cl)
533         db.security.addPermissionToRole('User', p)
535 Add add a line::
537         db.security.addPermissionToRole('Anonymous', p)
539 next to the existing ``'User'`` lines for the Permissions you wish to
540 assign to the anonymous user.
543 Migrating from 0.6 to 0.7
544 =========================
546 0.7.0 Permission assignments
547 ----------------------------
549 Due to a change in the rendering of web widgets, permissions are now
550 checked on Classes where they previously weren't (this is a good thing).
552 You will need to add some additional Permission assignments for your
553 regular users, or some displays will break. After the following in your 
554 tracker's ``dbinit.py``::
556     # Assign the access and edit Permissions for issue, file and message
557     # to regular users now
558     for cl in 'issue', 'file', 'msg', 'query', 'keyword':
559         p = db.security.getPermission('View', cl)
560         db.security.addPermissionToRole('User', p)
561         p = db.security.getPermission('Edit', cl)
562         db.security.addPermissionToRole('User', p)
564 add::
566     for cl in 'priority', 'status':
567         p = db.security.getPermission('View', cl)
568         db.security.addPermissionToRole('User', p)
571 0.7.0 Getting the current user id
572 ---------------------------------
574 The Database.curuserid attribute has been removed.
576 Any code referencing this attribute should be replaced with a
577 call to Database.getuid().
580 0.7.0 ZRoundup changes
581 ----------------------
583 The templates in your tracker's html directory will need updating if you
584 wish to use ZRoundup. If you've not modified those files (or some of them),
585 you may just copy the new versions from the Roundup source in the
586 templates/classic/html directory.
588 If you have modified the html files, then you'll need to manually edit them
589 to change all occurances of special form variables from using the colon ":"
590 special character to the at "@" special character. That is, variables such
591 as::
593   :action :required :template :remove:messages ...
595 should become::
597   @action @required @template @remove@messages ...
599 Note that ``tal:`` statements are unaffected. So are TAL expression type
600 prefixes such as ``python:`` and ``string:``. Please ask on the
601 roundup-users mailing list for help if you're unsure.
604 0.7.0 Edit collision detection
605 ------------------------------
607 Roundup now detects collisions with editing in the web interface (that is,
608 two people editing the same item at the same time).
610 You must copy the ``_generic.collision.html`` file from Roundup source in
611 the ``templates/classic/html`` directory. to your tracker's ``html``
612 directory.
615 Migrating from 0.6.x to 0.6.3
616 =============================
618 0.6.3 Configuration
619 -------------------
621 You will need to copy the file::
623   templates/classic/detectors/__init__.py
625 to your tracker's ``detectors`` directory, replacing the one already there.
626 This fixes a couple of bugs in that file.
630 Migrating from 0.5 to 0.6
631 =========================
634 0.6.0 Configuration
635 -------------------
637 Introduced EMAIL_FROM_TAG config variable. This value is inserted into
638 the From: line of nosy email. If the sending user is "Foo Bar", the
639 From: line is usually::
641      "Foo Bar" <issue_tracker@tracker.example>
643 the EMAIL_FROM_TAG goes inside the "Foo Bar" quotes like so::
645      "Foo Bar EMAIL_FROM_TAG" <issue_tracker@tracker.example>
647 I've altered the mechanism in the detectors __init__.py module so that it
648 doesn't cross-import detectors from other trackers (if you run more than one
649 in a single roundup-server). This change means that you'll need to copy the
650 __init__.py from roundup/templates/classic/detectors/__init__.py to your
651 <tracker home>/detectors/__init__.py. Don't worry, the "classic" __init__ is a
652 one-size-fits-all, so it'll work even if you've added/removed detectors.
654 0.6.0 Templating changes
655 ------------------------
657 The ``user.item`` template (in the tracker home "templates" directory)
658 needs to have the following hidden variable added to its form (between the
659 ``<form...>`` and ``</form>`` tags::
661   <input type="hidden" name=":template" value="item">
664 0.6.0 Form handling changes
665 ---------------------------
667 Roundup's form handling capabilities have been significantly expanded. This
668 should not affect users of 0.5 installations - but if you find you're
669 getting errors from form submissions, please ask for help on the Roundup
670 users mailing list:
672   http://lists.sourceforge.net/lists/listinfo/roundup-users
674 See the customisation doc section on `Form Values`__ for documentation of the
675 new form variables possible.
677 __ customizing.html#form-values
680 0.6.0 Multilingual character set support
681 ----------------------------------------
683 Added internationalization support. This is done via encoding all data
684 stored in roundup database to utf-8 (unicode encoding). To support utf-8 in
685 web interface you should add the folowing line to your tracker's html/page
686 and html/_generic.help files inside <head> tag::
687   
688     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
690 Since latin characters in utf-8 have the same codes as in ASCII table, this
691 modification is optional for users who use only plain latin characters. 
693 After this modification, you will be able to see and enter any world
694 character via web interface. Data received via mail interface also converted
695 to utf-8, however only new messages will be converted. If your roundup
696 database contains some of non-ASCII characters in one of 8-bit encoding,
697 they will not be visible in new unicode environment. Some of such data (e.g.
698 user names, keywords, etc)  can be edited by administrator, the others
699 (e.g. messages' contents) is not editable via web interface. Currently there
700 is no tool for converting such data, the only solution is to close
701 appropriate old issues and create new ones with the same content.
704 0.6.0 User timezone support
705 ---------------------------
707 From version 0.6.0 roundup supports displaying of Date data in user' local
708 timezone if he/she has provided timezone information. To make it possible
709 some modification to tracker's schema and HTML templates are required.
710 First you must add string property 'timezone' to user class in dbinit.py
711 like this::
712   
713     user = Class(db, "user", 
714                     username=String(),   password=Password(),
715                     address=String(),    realname=String(), 
716                     phone=String(),      organisation=String(),
717                     alternate_addresses=String(),
718                     queries=Multilink('query'), roles=String(),
719                     timezone=String())
720   
721 And second - html interface. Add following lines to
722 $TRACKER_HOME/html/user.item template::
723   
724      <tr>
725       <th>Timezone</th>
726       <td tal:content="structure context/timezone/field">timezone</td>
727      </tr>
729 After that all users should be able to provide their timezone information.
730 Timezone should be a positive or negative integer - offset from GMT.
732 After providing timezone, roundup will show all dates values, found in web
733 and mail interfaces in local time. It will also accept any Date info in
734 local time, convert and store it in GMT.
737 0.6.0 Search page structure
738 ---------------------------
740 In order to accomodate query editing the search page has been restructured. If
741 you want to provide your users with query editing, you should update your
742 search page using the macros detailed in the customisation doc section
743 `Searching on categories`__.
745 __ customizing.html#searching-on-categories
747 Also, the url field in the query class no longer starts with a '?'. You'll need
748 to remove this question mark from the url field to support queries. There's
749 a script in the "tools" directory called ``migrate-queries.py`` that should
750 automatically change any existing queries for you. As always, make a backup
751 of your database before running such a script.
754 0.6.0 Notes for metakit backend users
755 -------------------------------------
757 Roundup 0.6.0 introduced searching on ranges of dates and intervals. To
758 support it, some modifications to interval storing routine were made. So if
759 your tracker uses metakit backend and your db schema contains intervals
760 property, searches on that property will not be accurate for db items that
761 was stored before roundup' upgrade. However all new records should be
762 searchable on intervals.
764 It is possible to convert your database to new format: you can export and
765 import back all your data (consult "Migrating backends" in "Maintenance"
766 documentation). After this operation all your interval properties should
767 become searchable.
769 Users of backends others than metakit should not worry about this issue.
772 Migrating from 0.4.x to 0.5.0
773 =============================
775 This has been a fairly major revision of Roundup:
777 1. Brand new, much more powerful, flexible, tasty and nutritious templating.
778    Unfortunately, this means all your current templates are useless. Hopefully
779    the new documentation and examples will be enough to help you make the
780    transition. Please don't hesitate to ask on roundup-users for help (or
781    complete conversions if you're completely stuck)!
782 2. The database backed got a lot more flexible, allowing Metakit and SQL
783    databases! The only decent SQL database implemented at present is sqlite,
784    but others shouldn't be a whole lot more work.
785 3. A brand new, highly flexible and much more robust security system including
786    a system of Permissions, Roles and Role assignments to users. You may now
787    define your own Permissions that may be checked in CGI transactions.
788 4. Journalling has been made less storage-hungry, so has been turned on
789    by default *except* for author, recipient and nosy link/unlink events. You
790    are advised to turn it off in your trackers too.
791 5. We've changed the terminology from "instance" to "tracker", to ease the
792    learning curve/impact for new users.
793 6. Because of the above changes, the tracker configuration has seen some
794    major changes. See below for the details.
796 Please, **back up your database** before you start the migration process. This
797 is as simple as copying the "db" directory and all its contents from your
798 tracker to somewhere safe.
801 0.5.0 Configuration
802 -------------------
804 First up, rename your ``instance_config.py`` file to just ``config.py``.
806 Then edit your tracker's ``__init__.py`` module. It'll currently look
807 like this::
809  from instance_config import *
810  try:
811      from dbinit import *
812  except ImportError:
813      pass # in installdir (probably :)
814  from interfaces import *
816 and it needs to be::
818  import config
819  from dbinit import open, init
820  from interfaces import Client, MailGW
822 Due to the new templating having a top-level ``page`` that defines links for
823 searching, indexes, adding items etc, the following variables are no longer
824 used:
826 - HEADER_INDEX_LINKS
827 - HEADER_ADD_LINKS
828 - HEADER_SEARCH_LINKS
829 - SEARCH_FILTERS
830 - DEFAULT_INDEX
831 - UNASSIGNED_INDEX
832 - USER_INDEX
833 - ISSUE_FILTER
835 The new security implementation will require additions to the dbinit module,
836 but also removes the need for the following tracker config variables:
838 - ANONYMOUS_ACCESS
839 - ANONYMOUS_REGISTER
841 but requires two new variables which define the Roles assigned to users who
842 register through the web and e-mail interfaces:
844 - NEW_WEB_USER_ROLES
845 - NEW_EMAIL_USER_ROLES
847 in both cases, 'User' is a good initial setting. To emulate
848 ``ANONYMOUS_ACCESS='deny'``, remove all "View" Permissions from the
849 "Anonymous" Role. To emulate ``ANONYMOUS_REGISTER='deny'``, remove the "Web
850 Registration" and/or the "Email Registration" Permission from the "Anonymous"
851 Role. See the section on customising security in the `customisation
852 documentation`_ for more information.
854 Finally, the following config variables have been renamed to make more sense:
856 - INSTANCE_HOME -> TRACKER_HOME
857 - INSTANCE_NAME -> TRACKER_NAME
858 - ISSUE_TRACKER_WEB -> TRACKER_WEB
859 - ISSUE_TRACKER_EMAIL -> TRACKER_EMAIL
862 0.5.0 Schema Specification
863 --------------------------
865 0.5.0 Database backend changes
866 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
868 Your select_db module in your tracker has changed a fair bit. Where it used
869 to contain::
871  # WARNING: DO NOT EDIT THIS FILE!!!
872  from roundup.backends.back_anydbm import Database
874 it must now contain::
876  # WARNING: DO NOT EDIT THIS FILE!!!
877  from roundup.backends.back_anydbm import Database, Class, FileClass, IssueClass
879 Yes, I realise the irony of the "DO NOT EDIT THIS FILE" statement :)
880 Note the addition of the Class, FileClass, IssueClass imports. These are very
881 important, as they're going to make the next change work too. You now need to
882 modify the top of the dbinit module in your tracker from::
884  import instance_config
885  from roundup import roundupdb
886  from select_db import Database
888  from roundup.roundupdb import Class, FileClass
890  class Database(roundupdb.Database, select_db.Database):
891      ''' Creates a hybrid database from:
892           . the selected database back-end from select_db
893           . the roundup extensions from roundupdb
894      '''
895      pass
897  class IssueClass(roundupdb.IssueClass):
898      ''' issues need the email information
899      '''
900      pass
902 to::
904  import config
905  from select_db import Database, Class, FileClass, IssueClass
907 Yes, remove the Database and IssueClass definitions and those other imports.
908 They're not needed any more!
910 Look for places in dbinit.py where ``instance_config`` is used too, and
911 rename them ``config``.
914 0.5.0 Journalling changes
915 ~~~~~~~~~~~~~~~~~~~~~~~~~
917 Journalling has been optimised for storage. Journalling of links has been
918 turned back on by default. If your tracker has a large user base, you may wish
919 to turn off journalling of nosy list, message author and message recipient
920 link and unlink events. You do this by adding ``do_journal='no'`` to the Class
921 initialisation in your dbinit. For example, your *msg* class initialisation
922 probably looks like this::
924     msg = FileClass(db, "msg",
925                     author=Link("user"), recipients=Multilink("user"),
926                     date=Date(),         summary=String(),
927                     files=Multilink("file"),
928                     messageid=String(),  inreplyto=String())
930 to turn off journalling of author and recipient link events, add
931 ``do_journal='no'`` to the ``author=Link("user")`` part of the statement,
932 like so::
934     msg = FileClass(db, "msg",
935                     author=Link("user", do_journal='no'),
936                     recipients=Multilink("user", do_journal='no'),
937                     date=Date(),         summary=String(),
938                     files=Multilink("file"),
939                     messageid=String(),  inreplyto=String())
941 Nosy list link event journalling is actually turned off by default now. If you
942 want to turn it on, change to your issue class' nosy list, change its
943 definition from::
945     issue = IssueClass(db, "issue",
946                     assignedto=Link("user"), topic=Multilink("keyword"),
947                     priority=Link("priority"), status=Link("status"))
949 to::
951     issue = IssueClass(db, "issue", nosy=Multilink("user", do_journal='yes'),
952                     assignedto=Link("user"), topic=Multilink("keyword"),
953                     priority=Link("priority"), status=Link("status"))
955 noting that your definition of the nosy Multilink will override the normal one.
958 0.5.0 User schema changes
959 ~~~~~~~~~~~~~~~~~~~~~~~~~
961 Users have two more properties, "queries" and "roles". You'll have something
962 like this in your dbinit module now::
964     user = Class(db, "user",
965                     username=String(),   password=Password(),
966                     address=String(),    realname=String(),
967                     phone=String(),      organisation=String(),
968                     alternate_addresses=String())
969     user.setkey("username")
971 and you'll need to add the new properties and the new "query" class to it
972 like so::
974     query = Class(db, "query",
975                     klass=String(),     name=String(),
976                     url=String())
977     query.setkey("name")
979     # Note: roles is a comma-separated string of Role names
980     user = Class(db, "user",
981                     username=String(),   password=Password(),
982                     address=String(),    realname=String(),
983                     phone=String(),      organisation=String(),
984                     alternate_addresses=String(),
985                     queries=Multilink('query'), roles=String())
986     user.setkey("username")
988 The "queries" property is used to store off the user's favourite database
989 queries. The "roles" property is explained below in `0.5.0 Security
990 Settings`_.
993 0.5.0 Security Settings
994 ~~~~~~~~~~~~~~~~~~~~~~~
996 See the `security documentation`_ for an explanation of how the new security
997 system works. In a nutshell though, the security is handled as a four step
998 process:
1000 1. Permissions are defined as having a name and optionally a hyperdb class
1001    they're specific to,
1002 2. Roles are defined that have one or more Permissions,
1003 3. Users are assigned Roles in their "roles" property, and finally
1004 4. Roundup checks that users have appropriate Permissions at appropriate times
1005    (like editing issues).
1007 Your tracker dbinit module's *open* function now has to define any
1008 Permissions that are specific to your tracker, and also the assignment
1009 of Permissions to Roles. At the moment, your open function
1010 ends with::
1012     import detectors
1013     detectors.init(db)
1015     return db
1017 and what we need to do is insert some commands that will set up the security
1018 parameters. Right above the ``import detectors`` line, you'll want to insert
1019 these lines::
1021     #
1022     # SECURITY SETTINGS
1023     #
1024     # new permissions for this schema
1025     for cl in 'issue', 'file', 'msg', 'user':
1026         db.security.addPermission(name="Edit", klass=cl,
1027             description="User is allowed to edit "+cl)
1028         db.security.addPermission(name="View", klass=cl,
1029             description="User is allowed to access "+cl)
1031     # Assign the access and edit permissions for issue, file and message
1032     # to regular users now
1033     for cl in 'issue', 'file', 'msg':
1034         p = db.security.getPermission('View', cl)
1035         db.security.addPermissionToRole('User', p)
1036         p = db.security.getPermission('Edit', cl)
1037         db.security.addPermissionToRole('User', p)
1038     # and give the regular users access to the web and email interface
1039     p = db.security.getPermission('Web Access')
1040     db.security.addPermissionToRole('User', p)
1041     p = db.security.getPermission('Email Access')
1042     db.security.addPermissionToRole('User', p)
1044     # May users view other user information? Comment these lines out
1045     # if you don't want them to
1046     p = db.security.getPermission('View', 'user')
1047     db.security.addPermissionToRole('User', p)
1049     # Assign the appropriate permissions to the anonymous user's Anonymous
1050     # Role. Choices here are:
1051     # - Allow anonymous users to register through the web
1052     p = db.security.getPermission('Web Registration')
1053     db.security.addPermissionToRole('Anonymous', p)
1054     # - Allow anonymous (new) users to register through the email gateway
1055     p = db.security.getPermission('Email Registration')
1056     db.security.addPermissionToRole('Anonymous', p)
1057     # - Allow anonymous users access to the "issue" class of data
1058     #   Note: this also grants access to related information like files,
1059     #         messages, statuses etc that are linked to issues
1060     #p = db.security.getPermission('View', 'issue')
1061     #db.security.addPermissionToRole('Anonymous', p)
1062     # - Allow anonymous users access to edit the "issue" class of data
1063     #   Note: this also grants access to create related information like
1064     #         files and messages etc that are linked to issues
1065     #p = db.security.getPermission('Edit', 'issue')
1066     #db.security.addPermissionToRole('Anonymous', p)
1068     # oh, g'wan, let anonymous access the web interface too
1069     p = db.security.getPermission('Web Access')
1070     db.security.addPermissionToRole('Anonymous', p)
1072 Note in the comments there the places where you might change the permissions
1073 to restrict users or grant users more access. If you've created additional
1074 classes that users should be able to edit and view, then you should add them
1075 to the "new permissions for this schema" section at the start of the security
1076 block. Then add them to the "Assign the access and edit permissions" section
1077 too, so people actually have the new Permission you've created.
1079 One final change is needed that finishes off the security system's
1080 initialisation. We need to add a call to ``db.post_init()`` at the end of the
1081 dbinit open() function. Add it like this::
1083     import detectors
1084     detectors.init(db)
1086     # schema is set up - run any post-initialisation
1087     db.post_init()
1088     return db
1090 You may verify the setup of Permissions and Roles using the new
1091 "``roundup-admin security``" command.
1094 0.5.0 User changes
1095 ~~~~~~~~~~~~~~~~~~
1097 To support all those schema changes, you'll need to massage your user database
1098 a little too, to:
1100 1. make sure there's an "anonymous" user - this user is mandatory now and is
1101    the one that unknown users are logged in as.
1102 2. make sure all users have at least one Role.
1104 If you don't have the "anonymous" user, create it now with the command::
1106   roundup-admin create user username=anonymous roles=Anonymous
1108 making sure the capitalisation is the same as above. Once you've done that,
1109 you'll need to set the roles property on all users to a reasonable default.
1110 The admin user should get "Admin", the anonymous user "Anonymous"
1111 and all other users "User". The ``fixroles.py`` script in the tools directory
1112 will do this. Run it like so (where python is your python 2+ binary)::
1114   python tools/fixroles.py -i <tracker home> fixroles
1118 0.5.0 CGI interface changes
1119 ---------------------------
1121 The CGI interface code was completely reorganised and largely rewritten. The
1122 end result is that this section of your tracker interfaces module will need
1123 changing from::
1125  from roundup import cgi_client, mailgw
1126  from roundup.i18n import _
1127  
1128  class Client(cgi_client.Client):
1129      ''' derives basic CGI implementation from the standard module,
1130          with any specific extensions
1131      '''
1132      pass
1134 to::
1136  from roundup import mailgw
1137  from roundup.cgi import client
1138  
1139  class Client(client.Client): 
1140      ''' derives basic CGI implementation from the standard module,
1141          with any specific extensions
1142      '''
1143      pass
1145 You will also need to install the new version of roundup.cgi from the source
1146 cgi-bin directory if you're using it.
1149 0.5.0 HTML templating
1150 ---------------------
1152 You'll want to make a backup of your current tracker html directory. You
1153 should then copy the html directory from the Roundup source "classic" template
1154 and modify it according to your local schema changes.
1156 If you need help with the new templating system, please ask questions on the
1157 roundup-users mailing list (available through the roundup project page on
1158 sourceforge, http://roundup.sf.net/)
1161 0.5.0 Detectors
1162 ---------------
1164 The nosy reactor has been updated to handle the tracker not having an
1165 "assignedto" property on issues. You may want to copy it into your tracker's
1166 detectors directory. Chances are you've already fixed it though :)
1169 Migrating from 0.4.1 to 0.4.2
1170 =============================
1172 0.4.2 Configuration
1173 -------------------
1174 The USER_INDEX definition introduced in 0.4.1 was too restrictive in its
1175 allowing replacement of 'assignedto' with the user's userid. Users must change
1176 the None value of 'assignedto' to 'CURRENT USER' (the string, in quotes) for
1177 the replacement behaviour to occur now.
1179 The new configuration variables are:
1181 - EMAIL_KEEP_QUOTED_TEXT 
1182 - EMAIL_LEAVE_BODY_UNCHANGED
1183 - ADD_RECIPIENTS_TO_NOSY
1185 See the sample configuration files in::
1187  <roundup source>/roundup/templates/classic/instance_config.py
1189 and::
1191  <roundup source>/roundup/templates/extended/instance_config.py
1193 and the `customisation documentation`_ for information on how they're used.
1196 0.4.2 Changes to detectors
1197 --------------------------
1198 You will need to copy the detectors from the distribution into your instance
1199 home "detectors" directory. If you used the classic schema, the detectors
1200 are in::
1202  <roundup source>/roundup/templates/classic/detectors/
1204 If you used the extended schema, the detectors are in::
1206  <roundup source>/roundup/templates/extended/detectors/
1208 The change means that schema-specific code has been removed from the
1209 mail gateway and cgi interface and made into auditors:
1211 - nosyreactor.py has now got an updatenosy auditor which updates the nosy
1212   list with author, recipient and assignedto information.
1213 - statusauditor.py makes the unread or resolved -> chatting changes and
1214   presets the status of an issue to unread.
1216 There's also a bug or two fixed in the nosyreactor code.
1218 0.4.2 HTML templating changes
1219 -----------------------------
1220 The link() htmltemplate function now has a "showid" option for links and
1221 multilinks. When true, it only displays the linked item id as the anchor
1222 text. The link value is displayed as a tooltip using the title anchor
1223 attribute. To use in eg. the superseder field, have something like this::
1225    <td>
1226     <display call="field('superseder', showid=1)">
1227     <display call="classhelp('issue', 'id,title', label='list', width=500)">
1228     <property name="superseder">
1229      <br>View: <display call="link('superseder', showid=1)">
1230     </property>
1231    </td>
1233 The stylesheets have been cleaned up too. You may want to use the newer
1234 versions in::
1236  <roundup source>/roundup/templates/<template>/html/default.css
1240 Migrating from 0.4.0 to 0.4.1
1241 =============================
1243 0.4.1 Files storage
1244 -------------------
1246 Messages and files from newly created issues will be put into subdierectories
1247 in thousands e.g. msg123 will be put into files/msg/0/msg123, file2003
1248 will go into files/file/2/file2003. Previous messages are still found, but
1249 could be put into this structure.
1251 0.4.1 Configuration
1252 -------------------
1254 To allow more fine-grained access control, the variable used to check
1255 permission to auto-register users in the mail gateway is now called
1256 ANONYMOUS_REGISTER_MAIL rather than overloading ANONYMOUS_REGISTER. If the
1257 variable doesn't exist, then ANONYMOUS_REGISTER is tested as before.
1259 Configuring the links in the web header is now easier too. The following
1260 variables have been added to the classic instance_config.py::
1262   HEADER_INDEX_LINKS   - defines the "index" links to be made available
1263   HEADER_ADD_LINKS     - defines the "add" links
1264   DEFAULT_INDEX        - specifies the index view for DEFAULT
1265   UNASSIGNED_INDEX     - specifies the index view for UNASSIGNED
1266   USER_INDEX           - specifies the index view for USER
1268 See the <roundup source>/roundup/templates/classic/instance_config.py for more
1269 information - including how the variables are to be set up. Most users will
1270 just be able to copy the variables from the source to their instance home. If
1271 you've modified the header by changing the source of the interfaces.py file in
1272 the instance home, you'll need to remove that customisation and move it into
1273 the appropriate variables in instance_config.py.
1275 The extended schema has similar variables added too - see the source for more
1276 info.
1278 0.4.1 Alternate E-Mail Addresses
1279 --------------------------------
1281 If you add the property "alternate_addresses" to your user class, your users
1282 will be able to register alternate email addresses that they may use to
1283 communicate with roundup as. All email from roundup will continue to be sent
1284 to their primary address.
1286 If you have not edited the dbinit.py file in your instance home directory,
1287 you may simply copy the new dbinit.py file from the core code. If you used
1288 the classic schema, the interfaces file is in::
1290  <roundup source>/roundup/templates/classic/dbinit.py
1292 If you used the extended schema, the file is in::
1294  <roundup source>/roundup/templates/extended/dbinit.py 
1296 If you have modified your dbinit.py file, you need to edit the dbinit.py
1297 file in your instance home directory. Find the lines which define the user
1298 class::
1300     user = Class(db, "msg",
1301                     username=String(),   password=Password(),
1302                     address=String(),    realname=String(), 
1303                     phone=String(),      organisation=String(),
1304                     alternate_addresses=String())
1306 You will also want to add the property to the user's details page. The
1307 template for this is the "user.item" file in your instance home "html"
1308 directory. Similar to above, you may copy the file from the roundup source if
1309 you haven't modified it. Otherwise, add the following to the template::
1311    <display call="multiline('alternate_addresses')">
1313 with appropriate labelling etc. See the standard template for an idea.
1317 Migrating from 0.3.x to 0.4.0
1318 =============================
1320 0.4.0 Message-ID and In-Reply-To addition
1321 -----------------------------------------
1322 0.4.0 adds the tracking of messages by message-id and allows threading
1323 using in-reply-to. Most e-mail clients support threading using this
1324 feature, and we hope to add support for it to the web gateway. If you
1325 have not edited the dbinit.py file in your instance home directory, you may
1326 simply copy the new dbinit.py file from the core code. If you used the
1327 classic schema, the interfaces file is in::
1329  <roundup source>/roundup/templates/classic/dbinit.py
1331 If you used the extended schema, the file is in::
1333  <roundup source>/roundup/templates/extended/dbinit.py 
1335 If you have modified your dbinit.py file, you need to edit the dbinit.py
1336 file in your instance home directory. Find the lines which define the msg
1337 class::
1339     msg = FileClass(db, "msg",
1340                     author=Link("user"), recipients=Multilink("user"),
1341                     date=Date(),         summary=String(),
1342                     files=Multilink("file"))
1344 and add the messageid and inreplyto properties like so::
1346     msg = FileClass(db, "msg",
1347                     author=Link("user"), recipients=Multilink("user"),
1348                     date=Date(),         summary=String(),
1349                     files=Multilink("file"),
1350                     messageid=String(),  inreplyto=String())
1352 Also, configuration is being cleaned up. This means that your dbinit.py will
1353 also need to be changed in the open function. If you haven't changed your
1354 dbinit.py, the above copy will be enough. If you have, you'll need to change
1355 the line (round line 50)::
1357     db = Database(instance_config.DATABASE, name)
1359 to::
1361     db = Database(instance_config, name)
1364 0.4.0 Configuration
1365 --------------------
1366 ``TRACKER_NAME`` and ``EMAIL_SIGNATURE_POSITION`` have been added to the
1367 instance_config.py. The simplest solution is to copy the default values
1368 from template in the core source.
1370 The mail gateway now checks ``ANONYMOUS_REGISTER`` to see if unknown users
1371 are to be automatically registered with the tracker. If it is set to "deny"
1372 then unknown users will not have access. If it is set to "allow" they will be
1373 automatically registered with the tracker.
1376 0.4.0 CGI script roundup.cgi
1377 ----------------------------
1378 The CGI script has been updated with some features and a bugfix, so you should
1379 copy it from the roundup cgi-bin source directory again. Make sure you update
1380 the ROUNDUP_INSTANCE_HOMES after the copy.
1383 0.4.0 Nosy reactor
1384 ------------------
1385 The nosy reactor has also changed - copy the nosyreactor.py file from the core
1386 source::
1388    <roundup source>/roundup/templates/<template>/detectors/nosyreactor.py
1390 to your instance home "detectors" directory.
1393 0.4.0 HTML templating
1394 ---------------------
1395 The field() function was incorrectly implemented - links and multilinks now
1396 display as text fields when rendered using field(). To display a menu (drop-
1397 down or select box) you need to use the menu() function.
1401 Migrating from 0.2.x to 0.3.x
1402 =============================
1404 0.3.x Cookie Authentication changes
1405 -----------------------------------
1406 0.3.0 introduces cookie authentication - you will need to copy the
1407 interfaces.py file from the roundup source to your instance home to enable
1408 authentication. If you used the classic schema, the interfaces file is in::
1410  <roundup source>/roundup/templates/classic/interfaces.py
1412 If you used the extended schema, the file is in::
1414  <roundup source>/roundup/templates/extended/interfaces.py
1416 If you have modified your interfaces.Client class, you will need to take
1417 note of the login/logout functionality provided in roundup.cgi_client.Client
1418 (classic schema) or roundup.cgi_client.ExtendedClient (extended schema) and
1419 modify your instance code apropriately.
1422 0.3.x Password encoding
1423 -----------------------
1424 This release also introduces encoding of passwords in the database. If you
1425 have not edited the dbinit.py file in your instance home directory, you may
1426 simply copy the new dbinit.py file from the core code. If you used the
1427 classic schema, the interfaces file is in::
1429  <roundup source>/roundup/templates/classic/dbinit.py
1431 If you used the extended schema, the file is in::
1433  <roundup source>/roundup/templates/extended/dbinit.py
1436 If you have modified your dbinit.py file, you may use encoded passwords:
1438 1. Edit the dbinit.py file in your instance home directory
1439    a. At the first code line of the open() function::
1441        from roundup.hyperdb import String, Date, Link, Multilink
1443       alter to include Password, as so::
1445        from roundup.hyperdb import String, Password, Date, Link, Multilink
1447    b. Where the password property is defined (around line 66)::
1449        user = Class(db, "user", 
1450                        username=String(),   password=String(),
1451                        address=String(),    realname=String(), 
1452                        phone=String(),      organisation=String())
1453        user.setkey("username")
1455       alter the "password=String()" to "password=Password()"::
1457        user = Class(db, "user", 
1458                        username=String(),   password=Password(),
1459                        address=String(),    realname=String(), 
1460                        phone=String(),      organisation=String())
1461        user.setkey("username")
1463 2. Any existing passwords in the database will remain cleartext until they
1464    are edited. It is recommended that at a minimum the admin password be
1465    changed immediately::
1467       roundup-admin -i <instance home> set user1 password=<new password>
1470 0.3.x Configuration
1471 -------------------
1472 FILTER_POSITION, ANONYMOUS_ACCESS, ANONYMOUS_REGISTER have been added to
1473 the instance_config.py. Simplest solution is to copy the default values from
1474 template in the core source.
1476 MESSAGES_TO_AUTHOR has been added to the IssueClass in dbinit.py. Set to 'yes'
1477 to send nosy messages to the author. Default behaviour is to not send nosy
1478 messages to the author. You will need to add MESSAGES_TO_AUTHOR to your
1479 dbinit.py in your instance home.
1482 0.3.x CGI script roundup.cgi
1483 ----------------------------
1484 There have been some structural changes to the roundup.cgi script - you will
1485 need to install it again from the cgi-bin directory of the source
1486 distribution. Make sure you update the ROUNDUP_INSTANCE_HOMES after the
1487 copy.
1490 .. _`customisation documentation`: customizing.html
1491 .. _`security documentation`: security.html
1492 .. _`administration guide`: admin_guide.html