Code

include some additional docs
[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 Fixing some potential security holes
26 ------------------------------------
28 Some HTML templates were found to have formatting security problems:
30 ``html/page.html``::
32   -tal:replace="request/user/username">username</span></b><br>
33   +tal:replace="python:request.user.username.plain(escape=1)">username</span></b><br>
35 ``html/_generic.help-list.html``::
37   -tal:content="structure python:item[prop]"></label>
38   +tal:content="python:item[prop]"></label>
40 The lines marked "+" should be added and lines marked "-" should be
41 deleted (minus the "+"/"-" signs).
44 Migrating from 1.4.x to 1.4.11
45 ==============================
47 Close potential security hole
48 -----------------------------
50 If your tracker has untrusted users you should examine its ``schema.py``
51 file and look for the section granting the "Edit" permission to your users.
52 This should look something like::
54     p = db.security.addPermission(name='Edit', klass='user', check=own_record,
55         description="User is allowed to edit their own user details")
57 and should be modified to restrict the list of properties they are allowed
58 to edit by adding the ``properties=`` section like::
60     p = db.security.addPermission(name='Edit', klass='user', check=own_record,
61         properties=('username', 'password', 'address', 'realname', 'phone',
62             'organisation', 'alternate_addresses', 'queries', 'timezone'),
63         description="User is allowed to edit their own user details")
65 Most importantly the "roles" property should not be editable - thus not
66 appear in that list of properties.
69 Grant the "Register" permission to the Anonymous role
70 -----------------------------------------------------
72 A separate "Register" permission has been introduced to allow
73 anonymous users to register. This means you will need to add the
74 following to your tracker's ``schema.py`` to add the permission and
75 assign it to the Anonymous role (replacing any previously assigned
76 "Create user" permission for the Anonymous role)::
78   +db.security.addPermission(name='Register', klass='user',
79   +     description='User is allowed to register new user')
80  
81    # Assign the appropriate permissions to the anonymous user's Anonymous
82    # Role. Choices here are:
83    # - Allow anonymous users to register
84   -db.security.addPermissionToRole('Anonymous', 'Create', 'user')
85   +db.security.addPermissionToRole('Anonymous', 'Register', 'user')
87 The lines marked "+" should be added and lines marked "-" should be
88 deleted (minus the "+"/"-" signs).
90 You should also modify the ``html/page.py`` template to change the
91 permission tested there::
93    -tal:condition="python:request.user.hasPermission('Create', 'user')"
94    +tal:condition="python:request.user.hasPermission('Register', 'user')"
97 Generic class editor may now restore retired items
98 --------------------------------------------------
100 The instructions for doing so won't be present in your tracker unless you copy
101 the ``_generic.index.html`` template from the roundup distribution in
102 ``share/roundup/templates/classic/html`` to your tracker's ``html`` directory.
105 Migrating from 1.4.x to 1.4.9
106 =============================
108 Customized MailGW Class
109 -----------------------
111 If you have customized the MailGW class in your tracker: The new MailGW
112 class opens the database for each message in the method handle_message
113 (instance.open) instead of passing the opened database as a parameter to
114 the MailGW constructor. The old handle_message has been renamed to
115 _handle_message. The new method opens the database and wraps the call to
116 the old method into a try/finally.
118 Your customized MailGW class needs to mirror this behavior.
120 Fix the "remove" button in issue files and messages lists
121 ---------------------------------------------------------
123 The "remove" button(s) in the issue messages list needs to be altered. Find
124 the following in your tracker's ``html/issue.item.html`` template::
126   <td>
127    <form style="padding:0" tal:condition="context/is_edit_ok"
128          tal:attributes="action string:issue${context/id}">
129     <input type="hidden" name="@remove@files" tal:attributes="value file/id">
131 and add ``method="POST"`` as shown below::
133   <td>
134    <form style="padding:0" method="POST" tal:condition="context/is_edit_ok"
135          tal:attributes="action string:issue${context/id}">
136     <input type="hidden" name="@remove@files" tal:attributes="value file/id">
138 Then also find::
140   <td>
141    <form style="padding:0" tal:condition="context/is_edit_ok"
142          tal:attributes="action string:issue${context/id}">
143     <input type="hidden" name="@remove@messages" tal:attributes="value msg/id">
145 and add ``method="POST"`` as shown below::
147   <td>
148    <form style="padding:0" method="POST" tal:condition="context/is_edit_ok"
149          tal:attributes="action string:issue${context/id}">
150     <input type="hidden" name="@remove@messages" tal:attributes="value msg/id">
153 Fixing the "retire" button in user management list
154 --------------------------------------------------
156 If you made the change to the "reture" link in the user management list as
157 listed below in `Migrating from 1.4.x to 1.4.7`_ then you'll need to fix that
158 change by adding ``method="POST"`` to the ``<form>`` tag::
160      <form style="padding:0" method="POST"
161            tal:attributes="action string:user${user/id}">
162       <input type="hidden" name="@template" value="index">
163       <input type="hidden" name="@action" value="retire">
164       <input type="submit" value="retire" i18n:attributes="value">
165      </form>
168 Migrating from 1.4.x to 1.4.7
169 =============================
171 Several security issues were addressed in this release. Some aspects of your
172 trackers may no longer function depending on your local customisations. Core
173 functionality that will need to be modified:
175 Grant the "retire" permission to users for their queries
176 --------------------------------------------------------
178 Users will no longer be able to retire their own queries. To remedy this you
179 will need to add the following to your tracker's ``schema.py`` just under the
180 line that grants them permission to edit their own queries::
182    p = db.security.addPermission(name='Edit', klass='query', check=edit_query,
183       description="User is allowed to edit their queries")
184    db.security.addPermissionToRole('User', p)
185  + p = db.security.addPermission(name='Retire', klass='query', check=edit_query,
186  +    description="User is allowed to retire their queries")
187  + db.security.addPermissionToRole('User', p)
188    p = db.security.addPermission(name='Create', klass='query',
189       description="User is allowed to create queries")
190    db.security.addPermissionToRole('User', p)
192 The lines marked "+" should be added, minus the "+" sign.
195 Fix the "retire" link in the users list for admin users
196 -------------------------------------------------------
198 The "retire" link found in the file ``html/users.index.html``::
200   <td tal:condition="context/is_edit_ok">
201    <a tal:attributes="href string:user${user/id}?@action=retire&@template=index"
202     i18n:translate="">retire</a>
204 Should be replaced with::
206   <td tal:condition="context/is_retire_ok">
207      <form style="padding:0" method="POST"
208            tal:attributes="action string:user${user/id}">
209       <input type="hidden" name="@template" value="index">
210       <input type="hidden" name="@action" value="retire">
211       <input type="submit" value="retire" i18n:attributes="value">
212      </form>
215 Fix for Python 2.6+ users
216 -------------------------
218 If you use Python 2.6 you should edit your tracker's
219 ``detectors/nosyreaction.py`` file to change::
221    import sets
223 at the top to::
225    from roundup.anypy.sets_ import set
227 and then all instances of ``sets.Set()`` to ``set()`` in the later code.
231 Trackers currently allowing HTML file uploading
232 -----------------------------------------------
234 Trackers which wish to continue to allow uploading of HTML content against issues
235 will need to set a new configuration variable in the ``[web]`` section of the
236 tracker's ``config.ini`` file:
238    # Setting this option enables Roundup to serve uploaded HTML
239    # file content *as HTML*. This is a potential security risk
240    # and is therefore disabled by default. Set to 'yes' if you
241    # trust *all* users uploading content to your tracker.
242    # Allowed values: yes, no
243    # Default: no
244    allow_html_file = no
248 Migrating from 1.4.2 to 1.4.3
249 =============================
251 If you are using the MySQL backend you will need to replace some indexes
252 that may have been created by version 1.4.2.
254 You should to access your MySQL database directly and remove any indexes
255 with a name ending in "_key_retired_idx". You should then re-add them with
256 the same spec except the key column name needs a size. So an index on
257 "_user (__retired, _name)" should become "_user (__retired, _name(255))".
260 Migrating from 1.4.x to 1.4.2
261 =============================
263 You should run the "roundup-admin migrate" command for your tracker once
264 you've installed the latest codebase. 
266 Do this before you use the web, command-line or mail interface and before
267 any users access the tracker.
269 This command will respond with either "Tracker updated" (if you've not
270 previously run it on an RDBMS backend) or "No migration action required"
271 (if you have run it, or have used another interface to the tracker,
272 or are using anydbm).
274 It's safe to run this even if it's not required, so just get into the
275 habit.
278 Migrating from 1.3.3 to 1.4.0
279 =============================
281 Value of the "refwd_re" tracker configuration option (section "mailgw")
282 is treated as UTF-8 string.  In previous versions, it was ISO8859-1.
284 If you have running trackers based on the classic template, please
285 update the messagesummary detector as follows::
287     --- detectors/messagesummary.py 17 Apr 2003 03:26:38 -0000      1.1
288     +++ detectors/messagesummary.py 3 Apr 2007 06:47:21 -0000       1.2
289     @@ -8,7 +8,7 @@
290      if newvalues.has_key('summary') or not newvalues.has_key('content'):
291          return
293     -    summary, content = parseContent(newvalues['content'], 1, 1)
294     +    summary, content = parseContent(newvalues['content'], config=db.config)
295      newvalues['summary'] = summary
297 In the latest version we have added some database indexes to the
298 SQL-backends (mysql, postgresql, sqlite) for speeding up building the
299 roundup-index for full-text search. We recommend that you create the
300 following database indexes on the database by hand::
302  CREATE INDEX words_by_id ON __words (_textid)
303  CREATE UNIQUE INDEX __textids_by_props ON __textids (_class, _itemid, _prop)
305 Migrating from 1.2.x to 1.3.0
306 =============================
308 1.3.0 Web interface changes
309 ---------------------------
311 Some of the HTML files in the "classic" and "minimal" tracker templates
312 were changed to fix some bugs and clean them up. You may wish to compare
313 them to the HTML files in your tracker and apply any changes.
316 Migrating from 1.1.2 to 1.2.0
317 =============================
319 1.2.0 Sorting and grouping by multiple properties
320 -------------------------------------------------
322 Starting with this version, sorting and grouping by multiple properties
323 is possible. This means that request.sort and request.group are now
324 lists. This is reflected in several places:
326  * ``renderWith`` now has list attributes for ``sort`` and ``group``,
327    where you previously wrote::
328    
329     renderWith(... sort=('-', 'activity'), group=('+', 'priority')
331    you write now::
333     renderWith(... sort=[('-', 'activity')], group=[('+', 'priority')]
335  * In templates that permit to edit sorting/grouping, request.sort and
336    request.group are (possibly empty) lists. You can now sort and group
337    by multiple attributes. For an example, see the classic template. You
338    may want search for the variable ``n_sort`` which can be set to the
339    number of sort/group properties.
341  * Templates that diplay new headlines for each group of items with
342    equal group properties can now use the modified ``batch.propchanged``
343    method that can take several properties which are checked for
344    changes. See the example in the classic template which makes use of
345    ``batch.propchanged``.
347 Migrating from 1.1.0 to 1.1.1
348 =============================
350 1.1.1 "Clear this message"
351 --------------------------
353 In 1.1.1, the standard ``page.html`` template includes a "clear this message"
354 link in the green "ok" message bar that appears after a successful edit
355 (or other) action.
357 To include this in your tracker, change the following in your ``page.html``
358 template::
360  <p tal:condition="options/ok_message | nothing" class="ok-message"
361     tal:repeat="m options/ok_message" tal:content="structure m">error</p>
363 to be::
365  <p tal:condition="options/ok_message | nothing" class="ok-message">
366    <span tal:repeat="m options/ok_message"
367       tal:content="structure string:$m <br/ > " />
368     <a class="form-small" tal:attributes="href request/current_url"
369        i18n:translate="">clear this message</a>
370  </p>
373 If you implemented the "clear this message" in your 1.1.0 tracker, then you
374 should change it to the above and it will work much better!
377 Migrating from 1.0.x to 1.1.0
378 =============================
380 1.1 Login "For Session Only"
381 ----------------------------
383 In 1.1, web logins are alive for the length of a session only, *unless* you
384 add the following to the login form in your tracker's ``page.html``::
386     <input type="checkbox" name="remember" id="remember">
387     <label for="remember" i18n:translate="">Remember me?</label><br>
389 See the classic tracker ``page.html`` if you're unsure where this should
390 go.
393 1.1 Query Display Name
394 ----------------------
396 The ``dispname`` web variable has been renamed ``@dispname`` to avoid
397 clashing with other variables of the same name. If you are using the
398 display name feature, you will need to edit your tracker's ``page.html``
399 and ``issue.index.html`` pages to change ``dispname`` to ``@dispname``.
401 A side-effect of this change is that the renderWith method used in the
402 ``home.html`` page may now take a dispname argument.
405 1.1 "Clear this message"
406 ------------------------
408 In 1.1, the standard ``page.html`` template includes a "clear this message"
409 link in the green "ok" message bar that appears after a successful edit
410 (or other) action.
412 To include this in your tracker, change the following in your ``page.html``
413 template::
415  <p tal:condition="options/ok_message | nothing" class="ok-message"
416     tal:repeat="m options/ok_message" tal:content="structure m">error</p>
418 to be::
420  <p tal:condition="options/ok_message | nothing" class="ok-message">
421    <span tal:repeat="m options/ok_message"
422       tal:content="structure string:$m <br/ > " />
423     <a class="form-small" tal:attributes="href string:issue${context/id}"
424        i18n:translate="">clear this message</a>
425  </p>
428 Migrating from 0.8.x to 1.0
429 ===========================
431 1.0 New Query Permissions
432 -------------------------
434 New permissions are defined for query editing and viewing. To include these
435 in your tracker, you need to add these lines to your tracker's
436 ``schema.py``::
438  # Users should be able to edit and view their own queries. They should also
439  # be able to view any marked as not private. They should not be able to
440  # edit others' queries, even if they're not private
441  def view_query(db, userid, itemid):
442      private_for = db.query.get(itemid, 'private_for')
443      if not private_for: return True
444      return userid == private_for
445  def edit_query(db, userid, itemid):
446      return userid == db.query.get(itemid, 'creator')
447  p = db.security.addPermission(name='View', klass='query', check=view_query,
448      description="User is allowed to view their own and public queries")
449  db.security.addPermissionToRole('User', p)
450  p = db.security.addPermission(name='Edit', klass='query', check=edit_query,
451      description="User is allowed to edit their queries")
452  db.security.addPermissionToRole('User', p)
453  p = db.security.addPermission(name='Create', klass='query',
454      description="User is allowed to create queries")
455  db.security.addPermissionToRole('User', p)
457 and then remove 'query' from the line::
459  # Assign the access and edit Permissions for issue, file and message
460  # to regular users now
461  for cl in 'issue', 'file', 'msg', 'query', 'keyword':
463 so it looks like::
465  for cl in 'issue', 'file', 'msg', 'keyword':
468 Migrating from 0.8.0 to 0.8.3
469 =============================
471 0.8.3 Nosy Handling Changes
472 ---------------------------
474 A change was made to fix a bug in the ``nosyreaction.py`` standard
475 detector. To incorporate this fix in your trackers, you will need to copy
476 the ``nosyreaction.py`` file from the ``templates/classic/detectors``
477 directory of the source to your tracker's ``templates`` directory.
479 If you have modified the ``nosyreaction.py`` file from the standard
480 version, you will need to roll your changes into the new file.
483 Migrating from 0.7.1 to 0.8.0
484 =============================
486 You *must* fully uninstall previous Roundup version before installing
487 Roundup 0.8.0.  If you don't do that, ``roundup-admin install``
488 command may fail to function properly.
490 0.8.0 Backend changes
491 ---------------------
493 Backends 'bsddb' and 'bsddb3' are removed.  If you are using one of these,
494 you *must* migrate to another backend before upgrading.
497 0.8.0 API changes
498 -----------------
500 Class.safeget() was removed from the API. Test your item ids before calling
501 Class.get() instead.
504 0.8.0 New tracker layout
505 ------------------------
507 The ``config.py`` file has been replaced by ``config.ini``. You may use the
508 roundup-admin command "genconfig" to generate a new config file::
510   roundup-admin genconfig <tracker home>/config.ini
512 and modify the values therein based on the contents of your old config.py.
513 In most cases, the names of the config variables are the same.
515 The ``select_db.py`` file has been replaced by a file in the ``db``
516 directory called ``backend_name``. As you might guess, this file contains
517 just the name of the backend. To figure what the contents of yours should
518 be, use the following table:
520   ================================ =========================
521   ``select_db.py`` contents        ``backend_name`` contents
522   ================================ =========================
523   from back_anydbm import ...      anydbm
524   from back_metakit import ...     metakit
525   from back_sqlite import ...      sqlite
526   from back_mysql import ...       mysql
527   from back_postgresql import ...  postgresql
528   ================================ =========================
530 The ``dbinit.py`` file has been split into two new files,
531 ``initial_data.py`` and ``schema.py``. The contents of this file are:
533 ``initial_data.py``
534   You don't need one of these as your tracker is already initialised.
536 ``schema.py``
537   Copy the body of the ``def open(name=None)`` function from your old
538   tracker's ``dbinit.py`` file to this file. As the lines you're copying
539   aren't part of a function definition anymore, one level of indentation
540   needs to be removed (remove only the leading four spaces on each
541   line). 
543   The first few lines -- those starting with ``from roundup.hyperdb
544   import ...`` and the ``db = Database(config, name)`` line -- don't
545   need to be copied. Neither do the last few lines -- those starting
546   with ``import detectors``, down to ``return db`` inclusive.
548 You may remove the ``__init__.py`` module from the "detectors" directory as
549 it is no longer used.
551 There's a new way to write extension code for Roundup. If you have code in
552 an ``interfaces.py`` file you should move it. See the `customisation
553 documentation`_ for information about how extensions are now written.
554 Note that some older trackers may use ``interfaces.py`` to customise the
555 mail gateway behaviour. You will need to keep your ``interfaces.py`` file
556 if this is the case.
559 0.8.0 Permissions Changes
560 -------------------------
562 The creation of a new item in the user interfaces is now controlled by the
563 "Create" Permission. You will need to add an assignment of this Permission
564 to your users who are allowed to create items. The most common form of this
565 is the following in your ``schema.py`` added just under the current
566 assignation of the Edit Permission::
568     for cl in 'issue', 'file', 'msg', 'query', 'keyword':
569         p = db.security.getPermission('Create', cl)
570         db.security.addPermissionToRole('User', p)
572 You will need to explicitly let anonymous users access the web interface so
573 that regular users are able to see the login form. Note that almost all
574 trackers will need this Permission. The only situation where it's not
575 required is in a tracker that uses an HTTP Basic Authenticated front-end.
576 It's enabled by adding to your ``schema.py``::
578     p = db.security.getPermission('Web Access')
579     db.security.addPermissionToRole('Anonymous', p)
581 Finally, you will need to enable permission for your users to edit their
582 own details by adding the following to ``schema.py``::
584     # Users should be able to edit their own details. Note that this
585     # permission is limited to only the situation where the Viewed or
586     # Edited item is their own.
587     def own_record(db, userid, itemid):
588         '''Determine whether the userid matches the item being accessed.'''
589         return userid == itemid
590     p = db.security.addPermission(name='View', klass='user', check=own_record,
591         description="User is allowed to view their own user details")
592     p = db.security.addPermission(name='Edit', klass='user', check=own_record,
593         description="User is allowed to edit their own user details")
594     db.security.addPermissionToRole('User', p)
597 0.8.0 Use of TemplatingUtils
598 ----------------------------
600 If you used custom python functions in TemplatingUtils, they must
601 be moved from interfaces.py to a new file in the ``extensions`` directory. 
603 Each Function that should be available through TAL needs to be defined
604 as a toplevel function in the newly created file. Furthermore you
605 add an inititialization function, that registers the functions with the 
606 tracker.
608 If you find this too tedious, donfu wrote an automatic init function that
609 takes an existing TemplatingUtils class, and registers all class methods
610 that do not start with an underscore. The following hack should be placed
611 in the ``extensions`` directory alongside other extensions::
613     class TemplatingUtils:
614          # copy from interfaces.py
616     def init(tracker):
617          util = TemplatingUtils()
619          def setClient(tu):
620              util.client = tu.client
621              return util
623          def execUtil(name):
624              return lambda tu, *args, **kwargs: \
625                      getattr(setClient(tu), name)(*args, **kwargs)
627          for name in dir(util):
628              if callable(getattr(util, name)) and not name.startswith('_'):
629                   tracker.registerUtil(name, execUtil(name))
632 0.8.0 Logging Configuration
633 ---------------------------
635 See the `administration guide`_ for information about configuring the new
636 logging implemented in 0.8.0.
639 Migrating from 0.7.2 to 0.7.3
640 =============================
642 0.7.3 Configuration
643 -------------------
645 If you choose, you may specify the directory from which static files are
646 served (those which use the URL component ``@@file``). Currently the
647 directory defaults to the ``TEMPLATES`` configuration variable. You may
648 define a new variable, ``STATIC_FILES`` which overrides this value for
649 static files.
652 Migrating from 0.7.0 to 0.7.2
653 =============================
655 0.7.2 DEFAULT_TIMEZONE is now required
656 --------------------------------------
658 The DEFAULT_TIMEZONE configuration variable is now required. Add the
659 following to your tracker's ``config.py`` file::
661     # You may specify a different default timezone, for use when users do not
662     # choose their own in their settings.
663     DEFAULT_TIMEZONE = 0            # specify as numeric hour offest
666 Migrating from 0.7.0 to 0.7.1
667 =============================
669 0.7.1 Permission assignments
670 ----------------------------
672 If you allow anonymous access to your tracker, you might need to assign
673 some additional View (or Edit if your tracker is that open) permissions
674 to the "anonymous" user. To do so, find the code in your ``dbinit.py`` that
675 says::
677     for cl in 'issue', 'file', 'msg', 'query', 'keyword':
678         p = db.security.getPermission('View', cl)
679         db.security.addPermissionToRole('User', p)
680         p = db.security.getPermission('Edit', cl)
681         db.security.addPermissionToRole('User', p)
682     for cl in 'priority', 'status':
683         p = db.security.getPermission('View', cl)
684         db.security.addPermissionToRole('User', p)
686 Add add a line::
688         db.security.addPermissionToRole('Anonymous', p)
690 next to the existing ``'User'`` lines for the Permissions you wish to
691 assign to the anonymous user.
694 Migrating from 0.6 to 0.7
695 =========================
697 0.7.0 Permission assignments
698 ----------------------------
700 Due to a change in the rendering of web widgets, permissions are now
701 checked on Classes where they previously weren't (this is a good thing).
703 You will need to add some additional Permission assignments for your
704 regular users, or some displays will break. After the following in your 
705 tracker's ``dbinit.py``::
707     # Assign the access and edit Permissions for issue, file and message
708     # to regular users now
709     for cl in 'issue', 'file', 'msg', 'query', 'keyword':
710         p = db.security.getPermission('View', cl)
711         db.security.addPermissionToRole('User', p)
712         p = db.security.getPermission('Edit', cl)
713         db.security.addPermissionToRole('User', p)
715 add::
717     for cl in 'priority', 'status':
718         p = db.security.getPermission('View', cl)
719         db.security.addPermissionToRole('User', p)
722 0.7.0 Getting the current user id
723 ---------------------------------
725 The Database.curuserid attribute has been removed.
727 Any code referencing this attribute should be replaced with a
728 call to Database.getuid().
731 0.7.0 ZRoundup changes
732 ----------------------
734 The templates in your tracker's html directory will need updating if you
735 wish to use ZRoundup. If you've not modified those files (or some of them),
736 you may just copy the new versions from the Roundup source in the
737 templates/classic/html directory.
739 If you have modified the html files, then you'll need to manually edit them
740 to change all occurances of special form variables from using the colon ":"
741 special character to the at "@" special character. That is, variables such
742 as::
744   :action :required :template :remove:messages ...
746 should become::
748   @action @required @template @remove@messages ...
750 Note that ``tal:`` statements are unaffected. So are TAL expression type
751 prefixes such as ``python:`` and ``string:``. Please ask on the
752 roundup-users mailing list for help if you're unsure.
755 0.7.0 Edit collision detection
756 ------------------------------
758 Roundup now detects collisions with editing in the web interface (that is,
759 two people editing the same item at the same time).
761 You must copy the ``_generic.collision.html`` file from Roundup source in
762 the ``templates/classic/html`` directory. to your tracker's ``html``
763 directory.
766 Migrating from 0.6.x to 0.6.3
767 =============================
769 0.6.3 Configuration
770 -------------------
772 You will need to copy the file::
774   templates/classic/detectors/__init__.py
776 to your tracker's ``detectors`` directory, replacing the one already there.
777 This fixes a couple of bugs in that file.
781 Migrating from 0.5 to 0.6
782 =========================
785 0.6.0 Configuration
786 -------------------
788 Introduced EMAIL_FROM_TAG config variable. This value is inserted into
789 the From: line of nosy email. If the sending user is "Foo Bar", the
790 From: line is usually::
792      "Foo Bar" <issue_tracker@tracker.example>
794 the EMAIL_FROM_TAG goes inside the "Foo Bar" quotes like so::
796      "Foo Bar EMAIL_FROM_TAG" <issue_tracker@tracker.example>
798 I've altered the mechanism in the detectors __init__.py module so that it
799 doesn't cross-import detectors from other trackers (if you run more than one
800 in a single roundup-server). This change means that you'll need to copy the
801 __init__.py from roundup/templates/classic/detectors/__init__.py to your
802 <tracker home>/detectors/__init__.py. Don't worry, the "classic" __init__ is a
803 one-size-fits-all, so it'll work even if you've added/removed detectors.
805 0.6.0 Templating changes
806 ------------------------
808 The ``user.item`` template (in the tracker home "templates" directory)
809 needs to have the following hidden variable added to its form (between the
810 ``<form...>`` and ``</form>`` tags::
812   <input type="hidden" name=":template" value="item">
815 0.6.0 Form handling changes
816 ---------------------------
818 Roundup's form handling capabilities have been significantly expanded. This
819 should not affect users of 0.5 installations - but if you find you're
820 getting errors from form submissions, please ask for help on the Roundup
821 users mailing list:
823   http://lists.sourceforge.net/lists/listinfo/roundup-users
825 See the customisation doc section on `Form Values`__ for documentation of the
826 new form variables possible.
828 __ customizing.html#form-values
831 0.6.0 Multilingual character set support
832 ----------------------------------------
834 Added internationalization support. This is done via encoding all data
835 stored in roundup database to utf-8 (unicode encoding). To support utf-8 in
836 web interface you should add the folowing line to your tracker's html/page
837 and html/_generic.help files inside <head> tag::
838   
839     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
841 Since latin characters in utf-8 have the same codes as in ASCII table, this
842 modification is optional for users who use only plain latin characters. 
844 After this modification, you will be able to see and enter any world
845 character via web interface. Data received via mail interface also converted
846 to utf-8, however only new messages will be converted. If your roundup
847 database contains some of non-ASCII characters in one of 8-bit encoding,
848 they will not be visible in new unicode environment. Some of such data (e.g.
849 user names, keywords, etc)  can be edited by administrator, the others
850 (e.g. messages' contents) is not editable via web interface. Currently there
851 is no tool for converting such data, the only solution is to close
852 appropriate old issues and create new ones with the same content.
855 0.6.0 User timezone support
856 ---------------------------
858 From version 0.6.0 roundup supports displaying of Date data in user' local
859 timezone if he/she has provided timezone information. To make it possible
860 some modification to tracker's schema and HTML templates are required.
861 First you must add string property 'timezone' to user class in dbinit.py
862 like this::
863   
864     user = Class(db, "user", 
865                     username=String(),   password=Password(),
866                     address=String(),    realname=String(), 
867                     phone=String(),      organisation=String(),
868                     alternate_addresses=String(),
869                     queries=Multilink('query'), roles=String(),
870                     timezone=String())
871   
872 And second - html interface. Add following lines to
873 $TRACKER_HOME/html/user.item template::
874   
875      <tr>
876       <th>Timezone</th>
877       <td tal:content="structure context/timezone/field">timezone</td>
878      </tr>
880 After that all users should be able to provide their timezone information.
881 Timezone should be a positive or negative integer - offset from GMT.
883 After providing timezone, roundup will show all dates values, found in web
884 and mail interfaces in local time. It will also accept any Date info in
885 local time, convert and store it in GMT.
888 0.6.0 Search page structure
889 ---------------------------
891 In order to accomodate query editing the search page has been restructured. If
892 you want to provide your users with query editing, you should update your
893 search page using the macros detailed in the customisation doc section
894 `Searching on categories`__.
896 __ customizing.html#searching-on-categories
898 Also, the url field in the query class no longer starts with a '?'. You'll need
899 to remove this question mark from the url field to support queries. There's
900 a script in the "tools" directory called ``migrate-queries.py`` that should
901 automatically change any existing queries for you. As always, make a backup
902 of your database before running such a script.
905 0.6.0 Notes for metakit backend users
906 -------------------------------------
908 Roundup 0.6.0 introduced searching on ranges of dates and intervals. To
909 support it, some modifications to interval storing routine were made. So if
910 your tracker uses metakit backend and your db schema contains intervals
911 property, searches on that property will not be accurate for db items that
912 was stored before roundup' upgrade. However all new records should be
913 searchable on intervals.
915 It is possible to convert your database to new format: you can export and
916 import back all your data (consult "Migrating backends" in "Maintenance"
917 documentation). After this operation all your interval properties should
918 become searchable.
920 Users of backends others than metakit should not worry about this issue.
923 Migrating from 0.4.x to 0.5.0
924 =============================
926 This has been a fairly major revision of Roundup:
928 1. Brand new, much more powerful, flexible, tasty and nutritious templating.
929    Unfortunately, this means all your current templates are useless. Hopefully
930    the new documentation and examples will be enough to help you make the
931    transition. Please don't hesitate to ask on roundup-users for help (or
932    complete conversions if you're completely stuck)!
933 2. The database backed got a lot more flexible, allowing Metakit and SQL
934    databases! The only decent SQL database implemented at present is sqlite,
935    but others shouldn't be a whole lot more work.
936 3. A brand new, highly flexible and much more robust security system including
937    a system of Permissions, Roles and Role assignments to users. You may now
938    define your own Permissions that may be checked in CGI transactions.
939 4. Journalling has been made less storage-hungry, so has been turned on
940    by default *except* for author, recipient and nosy link/unlink events. You
941    are advised to turn it off in your trackers too.
942 5. We've changed the terminology from "instance" to "tracker", to ease the
943    learning curve/impact for new users.
944 6. Because of the above changes, the tracker configuration has seen some
945    major changes. See below for the details.
947 Please, **back up your database** before you start the migration process. This
948 is as simple as copying the "db" directory and all its contents from your
949 tracker to somewhere safe.
952 0.5.0 Configuration
953 -------------------
955 First up, rename your ``instance_config.py`` file to just ``config.py``.
957 Then edit your tracker's ``__init__.py`` module. It'll currently look
958 like this::
960  from instance_config import *
961  try:
962      from dbinit import *
963  except ImportError:
964      pass # in installdir (probably :)
965  from interfaces import *
967 and it needs to be::
969  import config
970  from dbinit import open, init
971  from interfaces import Client, MailGW
973 Due to the new templating having a top-level ``page`` that defines links for
974 searching, indexes, adding items etc, the following variables are no longer
975 used:
977 - HEADER_INDEX_LINKS
978 - HEADER_ADD_LINKS
979 - HEADER_SEARCH_LINKS
980 - SEARCH_FILTERS
981 - DEFAULT_INDEX
982 - UNASSIGNED_INDEX
983 - USER_INDEX
984 - ISSUE_FILTER
986 The new security implementation will require additions to the dbinit module,
987 but also removes the need for the following tracker config variables:
989 - ANONYMOUS_ACCESS
990 - ANONYMOUS_REGISTER
992 but requires two new variables which define the Roles assigned to users who
993 register through the web and e-mail interfaces:
995 - NEW_WEB_USER_ROLES
996 - NEW_EMAIL_USER_ROLES
998 in both cases, 'User' is a good initial setting. To emulate
999 ``ANONYMOUS_ACCESS='deny'``, remove all "View" Permissions from the
1000 "Anonymous" Role. To emulate ``ANONYMOUS_REGISTER='deny'``, remove the "Web
1001 Registration" and/or the "Email Registration" Permission from the "Anonymous"
1002 Role. See the section on customising security in the `customisation
1003 documentation`_ for more information.
1005 Finally, the following config variables have been renamed to make more sense:
1007 - INSTANCE_HOME -> TRACKER_HOME
1008 - INSTANCE_NAME -> TRACKER_NAME
1009 - ISSUE_TRACKER_WEB -> TRACKER_WEB
1010 - ISSUE_TRACKER_EMAIL -> TRACKER_EMAIL
1013 0.5.0 Schema Specification
1014 --------------------------
1016 0.5.0 Database backend changes
1017 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1019 Your select_db module in your tracker has changed a fair bit. Where it used
1020 to contain::
1022  # WARNING: DO NOT EDIT THIS FILE!!!
1023  from roundup.backends.back_anydbm import Database
1025 it must now contain::
1027  # WARNING: DO NOT EDIT THIS FILE!!!
1028  from roundup.backends.back_anydbm import Database, Class, FileClass, IssueClass
1030 Yes, I realise the irony of the "DO NOT EDIT THIS FILE" statement :)
1031 Note the addition of the Class, FileClass, IssueClass imports. These are very
1032 important, as they're going to make the next change work too. You now need to
1033 modify the top of the dbinit module in your tracker from::
1035  import instance_config
1036  from roundup import roundupdb
1037  from select_db import Database
1039  from roundup.roundupdb import Class, FileClass
1041  class Database(roundupdb.Database, select_db.Database):
1042      ''' Creates a hybrid database from:
1043           . the selected database back-end from select_db
1044           . the roundup extensions from roundupdb
1045      '''
1046      pass
1048  class IssueClass(roundupdb.IssueClass):
1049      ''' issues need the email information
1050      '''
1051      pass
1053 to::
1055  import config
1056  from select_db import Database, Class, FileClass, IssueClass
1058 Yes, remove the Database and IssueClass definitions and those other imports.
1059 They're not needed any more!
1061 Look for places in dbinit.py where ``instance_config`` is used too, and
1062 rename them ``config``.
1065 0.5.0 Journalling changes
1066 ~~~~~~~~~~~~~~~~~~~~~~~~~
1068 Journalling has been optimised for storage. Journalling of links has been
1069 turned back on by default. If your tracker has a large user base, you may wish
1070 to turn off journalling of nosy list, message author and message recipient
1071 link and unlink events. You do this by adding ``do_journal='no'`` to the Class
1072 initialisation in your dbinit. For example, your *msg* class initialisation
1073 probably looks like this::
1075     msg = FileClass(db, "msg",
1076                     author=Link("user"), recipients=Multilink("user"),
1077                     date=Date(),         summary=String(),
1078                     files=Multilink("file"),
1079                     messageid=String(),  inreplyto=String())
1081 to turn off journalling of author and recipient link events, add
1082 ``do_journal='no'`` to the ``author=Link("user")`` part of the statement,
1083 like so::
1085     msg = FileClass(db, "msg",
1086                     author=Link("user", do_journal='no'),
1087                     recipients=Multilink("user", do_journal='no'),
1088                     date=Date(),         summary=String(),
1089                     files=Multilink("file"),
1090                     messageid=String(),  inreplyto=String())
1092 Nosy list link event journalling is actually turned off by default now. If you
1093 want to turn it on, change to your issue class' nosy list, change its
1094 definition from::
1096     issue = IssueClass(db, "issue",
1097                     assignedto=Link("user"), topic=Multilink("keyword"),
1098                     priority=Link("priority"), status=Link("status"))
1100 to::
1102     issue = IssueClass(db, "issue", nosy=Multilink("user", do_journal='yes'),
1103                     assignedto=Link("user"), topic=Multilink("keyword"),
1104                     priority=Link("priority"), status=Link("status"))
1106 noting that your definition of the nosy Multilink will override the normal one.
1109 0.5.0 User schema changes
1110 ~~~~~~~~~~~~~~~~~~~~~~~~~
1112 Users have two more properties, "queries" and "roles". You'll have something
1113 like this in your dbinit module now::
1115     user = Class(db, "user",
1116                     username=String(),   password=Password(),
1117                     address=String(),    realname=String(),
1118                     phone=String(),      organisation=String(),
1119                     alternate_addresses=String())
1120     user.setkey("username")
1122 and you'll need to add the new properties and the new "query" class to it
1123 like so::
1125     query = Class(db, "query",
1126                     klass=String(),     name=String(),
1127                     url=String())
1128     query.setkey("name")
1130     # Note: roles is a comma-separated string of Role names
1131     user = Class(db, "user",
1132                     username=String(),   password=Password(),
1133                     address=String(),    realname=String(),
1134                     phone=String(),      organisation=String(),
1135                     alternate_addresses=String(),
1136                     queries=Multilink('query'), roles=String())
1137     user.setkey("username")
1139 The "queries" property is used to store off the user's favourite database
1140 queries. The "roles" property is explained below in `0.5.0 Security
1141 Settings`_.
1144 0.5.0 Security Settings
1145 ~~~~~~~~~~~~~~~~~~~~~~~
1147 See the `security documentation`_ for an explanation of how the new security
1148 system works. In a nutshell though, the security is handled as a four step
1149 process:
1151 1. Permissions are defined as having a name and optionally a hyperdb class
1152    they're specific to,
1153 2. Roles are defined that have one or more Permissions,
1154 3. Users are assigned Roles in their "roles" property, and finally
1155 4. Roundup checks that users have appropriate Permissions at appropriate times
1156    (like editing issues).
1158 Your tracker dbinit module's *open* function now has to define any
1159 Permissions that are specific to your tracker, and also the assignment
1160 of Permissions to Roles. At the moment, your open function
1161 ends with::
1163     import detectors
1164     detectors.init(db)
1166     return db
1168 and what we need to do is insert some commands that will set up the security
1169 parameters. Right above the ``import detectors`` line, you'll want to insert
1170 these lines::
1172     #
1173     # SECURITY SETTINGS
1174     #
1175     # new permissions for this schema
1176     for cl in 'issue', 'file', 'msg', 'user':
1177         db.security.addPermission(name="Edit", klass=cl,
1178             description="User is allowed to edit "+cl)
1179         db.security.addPermission(name="View", klass=cl,
1180             description="User is allowed to access "+cl)
1182     # Assign the access and edit permissions for issue, file and message
1183     # to regular users now
1184     for cl in 'issue', 'file', 'msg':
1185         p = db.security.getPermission('View', cl)
1186         db.security.addPermissionToRole('User', p)
1187         p = db.security.getPermission('Edit', cl)
1188         db.security.addPermissionToRole('User', p)
1189     # and give the regular users access to the web and email interface
1190     p = db.security.getPermission('Web Access')
1191     db.security.addPermissionToRole('User', p)
1192     p = db.security.getPermission('Email Access')
1193     db.security.addPermissionToRole('User', p)
1195     # May users view other user information? Comment these lines out
1196     # if you don't want them to
1197     p = db.security.getPermission('View', 'user')
1198     db.security.addPermissionToRole('User', p)
1200     # Assign the appropriate permissions to the anonymous user's Anonymous
1201     # Role. Choices here are:
1202     # - Allow anonymous users to register through the web
1203     p = db.security.getPermission('Web Registration')
1204     db.security.addPermissionToRole('Anonymous', p)
1205     # - Allow anonymous (new) users to register through the email gateway
1206     p = db.security.getPermission('Email Registration')
1207     db.security.addPermissionToRole('Anonymous', p)
1208     # - Allow anonymous users access to the "issue" class of data
1209     #   Note: this also grants access to related information like files,
1210     #         messages, statuses etc that are linked to issues
1211     #p = db.security.getPermission('View', 'issue')
1212     #db.security.addPermissionToRole('Anonymous', p)
1213     # - Allow anonymous users access to edit the "issue" class of data
1214     #   Note: this also grants access to create related information like
1215     #         files and messages etc that are linked to issues
1216     #p = db.security.getPermission('Edit', 'issue')
1217     #db.security.addPermissionToRole('Anonymous', p)
1219     # oh, g'wan, let anonymous access the web interface too
1220     p = db.security.getPermission('Web Access')
1221     db.security.addPermissionToRole('Anonymous', p)
1223 Note in the comments there the places where you might change the permissions
1224 to restrict users or grant users more access. If you've created additional
1225 classes that users should be able to edit and view, then you should add them
1226 to the "new permissions for this schema" section at the start of the security
1227 block. Then add them to the "Assign the access and edit permissions" section
1228 too, so people actually have the new Permission you've created.
1230 One final change is needed that finishes off the security system's
1231 initialisation. We need to add a call to ``db.post_init()`` at the end of the
1232 dbinit open() function. Add it like this::
1234     import detectors
1235     detectors.init(db)
1237     # schema is set up - run any post-initialisation
1238     db.post_init()
1239     return db
1241 You may verify the setup of Permissions and Roles using the new
1242 "``roundup-admin security``" command.
1245 0.5.0 User changes
1246 ~~~~~~~~~~~~~~~~~~
1248 To support all those schema changes, you'll need to massage your user database
1249 a little too, to:
1251 1. make sure there's an "anonymous" user - this user is mandatory now and is
1252    the one that unknown users are logged in as.
1253 2. make sure all users have at least one Role.
1255 If you don't have the "anonymous" user, create it now with the command::
1257   roundup-admin create user username=anonymous roles=Anonymous
1259 making sure the capitalisation is the same as above. Once you've done that,
1260 you'll need to set the roles property on all users to a reasonable default.
1261 The admin user should get "Admin", the anonymous user "Anonymous"
1262 and all other users "User". The ``fixroles.py`` script in the tools directory
1263 will do this. Run it like so (where python is your python 2+ binary)::
1265   python tools/fixroles.py -i <tracker home> fixroles
1269 0.5.0 CGI interface changes
1270 ---------------------------
1272 The CGI interface code was completely reorganised and largely rewritten. The
1273 end result is that this section of your tracker interfaces module will need
1274 changing from::
1276  from roundup import cgi_client, mailgw
1277  from roundup.i18n import _
1278  
1279  class Client(cgi_client.Client):
1280      ''' derives basic CGI implementation from the standard module,
1281          with any specific extensions
1282      '''
1283      pass
1285 to::
1287  from roundup import mailgw
1288  from roundup.cgi import client
1289  
1290  class Client(client.Client): 
1291      ''' derives basic CGI implementation from the standard module,
1292          with any specific extensions
1293      '''
1294      pass
1296 You will also need to install the new version of roundup.cgi from the source
1297 cgi-bin directory if you're using it.
1300 0.5.0 HTML templating
1301 ---------------------
1303 You'll want to make a backup of your current tracker html directory. You
1304 should then copy the html directory from the Roundup source "classic" template
1305 and modify it according to your local schema changes.
1307 If you need help with the new templating system, please ask questions on the
1308 roundup-users mailing list (available through the roundup project page on
1309 sourceforge, http://roundup.sf.net/)
1312 0.5.0 Detectors
1313 ---------------
1315 The nosy reactor has been updated to handle the tracker not having an
1316 "assignedto" property on issues. You may want to copy it into your tracker's
1317 detectors directory. Chances are you've already fixed it though :)
1320 Migrating from 0.4.1 to 0.4.2
1321 =============================
1323 0.4.2 Configuration
1324 -------------------
1325 The USER_INDEX definition introduced in 0.4.1 was too restrictive in its
1326 allowing replacement of 'assignedto' with the user's userid. Users must change
1327 the None value of 'assignedto' to 'CURRENT USER' (the string, in quotes) for
1328 the replacement behaviour to occur now.
1330 The new configuration variables are:
1332 - EMAIL_KEEP_QUOTED_TEXT 
1333 - EMAIL_LEAVE_BODY_UNCHANGED
1334 - ADD_RECIPIENTS_TO_NOSY
1336 See the sample configuration files in::
1338  <roundup source>/roundup/templates/classic/instance_config.py
1340 and::
1342  <roundup source>/roundup/templates/extended/instance_config.py
1344 and the `customisation documentation`_ for information on how they're used.
1347 0.4.2 Changes to detectors
1348 --------------------------
1349 You will need to copy the detectors from the distribution into your instance
1350 home "detectors" directory. If you used the classic schema, the detectors
1351 are in::
1353  <roundup source>/roundup/templates/classic/detectors/
1355 If you used the extended schema, the detectors are in::
1357  <roundup source>/roundup/templates/extended/detectors/
1359 The change means that schema-specific code has been removed from the
1360 mail gateway and cgi interface and made into auditors:
1362 - nosyreactor.py has now got an updatenosy auditor which updates the nosy
1363   list with author, recipient and assignedto information.
1364 - statusauditor.py makes the unread or resolved -> chatting changes and
1365   presets the status of an issue to unread.
1367 There's also a bug or two fixed in the nosyreactor code.
1369 0.4.2 HTML templating changes
1370 -----------------------------
1371 The link() htmltemplate function now has a "showid" option for links and
1372 multilinks. When true, it only displays the linked item id as the anchor
1373 text. The link value is displayed as a tooltip using the title anchor
1374 attribute. To use in eg. the superseder field, have something like this::
1376    <td>
1377     <display call="field('superseder', showid=1)">
1378     <display call="classhelp('issue', 'id,title', label='list', width=500)">
1379     <property name="superseder">
1380      <br>View: <display call="link('superseder', showid=1)">
1381     </property>
1382    </td>
1384 The stylesheets have been cleaned up too. You may want to use the newer
1385 versions in::
1387  <roundup source>/roundup/templates/<template>/html/default.css
1391 Migrating from 0.4.0 to 0.4.1
1392 =============================
1394 0.4.1 Files storage
1395 -------------------
1397 Messages and files from newly created issues will be put into subdierectories
1398 in thousands e.g. msg123 will be put into files/msg/0/msg123, file2003
1399 will go into files/file/2/file2003. Previous messages are still found, but
1400 could be put into this structure.
1402 0.4.1 Configuration
1403 -------------------
1405 To allow more fine-grained access control, the variable used to check
1406 permission to auto-register users in the mail gateway is now called
1407 ANONYMOUS_REGISTER_MAIL rather than overloading ANONYMOUS_REGISTER. If the
1408 variable doesn't exist, then ANONYMOUS_REGISTER is tested as before.
1410 Configuring the links in the web header is now easier too. The following
1411 variables have been added to the classic instance_config.py::
1413   HEADER_INDEX_LINKS   - defines the "index" links to be made available
1414   HEADER_ADD_LINKS     - defines the "add" links
1415   DEFAULT_INDEX        - specifies the index view for DEFAULT
1416   UNASSIGNED_INDEX     - specifies the index view for UNASSIGNED
1417   USER_INDEX           - specifies the index view for USER
1419 See the <roundup source>/roundup/templates/classic/instance_config.py for more
1420 information - including how the variables are to be set up. Most users will
1421 just be able to copy the variables from the source to their instance home. If
1422 you've modified the header by changing the source of the interfaces.py file in
1423 the instance home, you'll need to remove that customisation and move it into
1424 the appropriate variables in instance_config.py.
1426 The extended schema has similar variables added too - see the source for more
1427 info.
1429 0.4.1 Alternate E-Mail Addresses
1430 --------------------------------
1432 If you add the property "alternate_addresses" to your user class, your users
1433 will be able to register alternate email addresses that they may use to
1434 communicate with roundup as. All email from roundup will continue to be sent
1435 to their primary address.
1437 If you have not edited the dbinit.py file in your instance home directory,
1438 you may simply copy the new dbinit.py file from the core code. If you used
1439 the classic schema, the interfaces file is in::
1441  <roundup source>/roundup/templates/classic/dbinit.py
1443 If you used the extended schema, the file is in::
1445  <roundup source>/roundup/templates/extended/dbinit.py 
1447 If you have modified your dbinit.py file, you need to edit the dbinit.py
1448 file in your instance home directory. Find the lines which define the user
1449 class::
1451     user = Class(db, "msg",
1452                     username=String(),   password=Password(),
1453                     address=String(),    realname=String(), 
1454                     phone=String(),      organisation=String(),
1455                     alternate_addresses=String())
1457 You will also want to add the property to the user's details page. The
1458 template for this is the "user.item" file in your instance home "html"
1459 directory. Similar to above, you may copy the file from the roundup source if
1460 you haven't modified it. Otherwise, add the following to the template::
1462    <display call="multiline('alternate_addresses')">
1464 with appropriate labelling etc. See the standard template for an idea.
1468 Migrating from 0.3.x to 0.4.0
1469 =============================
1471 0.4.0 Message-ID and In-Reply-To addition
1472 -----------------------------------------
1473 0.4.0 adds the tracking of messages by message-id and allows threading
1474 using in-reply-to. Most e-mail clients support threading using this
1475 feature, and we hope to add support for it to the web gateway. If you
1476 have not edited the dbinit.py file in your instance home directory, you may
1477 simply copy the new dbinit.py file from the core code. If you used the
1478 classic schema, the interfaces file is in::
1480  <roundup source>/roundup/templates/classic/dbinit.py
1482 If you used the extended schema, the file is in::
1484  <roundup source>/roundup/templates/extended/dbinit.py 
1486 If you have modified your dbinit.py file, you need to edit the dbinit.py
1487 file in your instance home directory. Find the lines which define the msg
1488 class::
1490     msg = FileClass(db, "msg",
1491                     author=Link("user"), recipients=Multilink("user"),
1492                     date=Date(),         summary=String(),
1493                     files=Multilink("file"))
1495 and add the messageid and inreplyto properties like so::
1497     msg = FileClass(db, "msg",
1498                     author=Link("user"), recipients=Multilink("user"),
1499                     date=Date(),         summary=String(),
1500                     files=Multilink("file"),
1501                     messageid=String(),  inreplyto=String())
1503 Also, configuration is being cleaned up. This means that your dbinit.py will
1504 also need to be changed in the open function. If you haven't changed your
1505 dbinit.py, the above copy will be enough. If you have, you'll need to change
1506 the line (round line 50)::
1508     db = Database(instance_config.DATABASE, name)
1510 to::
1512     db = Database(instance_config, name)
1515 0.4.0 Configuration
1516 --------------------
1517 ``TRACKER_NAME`` and ``EMAIL_SIGNATURE_POSITION`` have been added to the
1518 instance_config.py. The simplest solution is to copy the default values
1519 from template in the core source.
1521 The mail gateway now checks ``ANONYMOUS_REGISTER`` to see if unknown users
1522 are to be automatically registered with the tracker. If it is set to "deny"
1523 then unknown users will not have access. If it is set to "allow" they will be
1524 automatically registered with the tracker.
1527 0.4.0 CGI script roundup.cgi
1528 ----------------------------
1529 The CGI script has been updated with some features and a bugfix, so you should
1530 copy it from the roundup cgi-bin source directory again. Make sure you update
1531 the ROUNDUP_INSTANCE_HOMES after the copy.
1534 0.4.0 Nosy reactor
1535 ------------------
1536 The nosy reactor has also changed - copy the nosyreactor.py file from the core
1537 source::
1539    <roundup source>/roundup/templates/<template>/detectors/nosyreactor.py
1541 to your instance home "detectors" directory.
1544 0.4.0 HTML templating
1545 ---------------------
1546 The field() function was incorrectly implemented - links and multilinks now
1547 display as text fields when rendered using field(). To display a menu (drop-
1548 down or select box) you need to use the menu() function.
1552 Migrating from 0.2.x to 0.3.x
1553 =============================
1555 0.3.x Cookie Authentication changes
1556 -----------------------------------
1557 0.3.0 introduces cookie authentication - you will need to copy the
1558 interfaces.py file from the roundup source to your instance home to enable
1559 authentication. If you used the classic schema, the interfaces file is in::
1561  <roundup source>/roundup/templates/classic/interfaces.py
1563 If you used the extended schema, the file is in::
1565  <roundup source>/roundup/templates/extended/interfaces.py
1567 If you have modified your interfaces.Client class, you will need to take
1568 note of the login/logout functionality provided in roundup.cgi_client.Client
1569 (classic schema) or roundup.cgi_client.ExtendedClient (extended schema) and
1570 modify your instance code apropriately.
1573 0.3.x Password encoding
1574 -----------------------
1575 This release also introduces encoding of passwords in the database. If you
1576 have not edited the dbinit.py file in your instance home directory, you may
1577 simply copy the new dbinit.py file from the core code. If you used the
1578 classic schema, the interfaces file is in::
1580  <roundup source>/roundup/templates/classic/dbinit.py
1582 If you used the extended schema, the file is in::
1584  <roundup source>/roundup/templates/extended/dbinit.py
1587 If you have modified your dbinit.py file, you may use encoded passwords:
1589 1. Edit the dbinit.py file in your instance home directory
1590    a. At the first code line of the open() function::
1592        from roundup.hyperdb import String, Date, Link, Multilink
1594       alter to include Password, as so::
1596        from roundup.hyperdb import String, Password, Date, Link, Multilink
1598    b. Where the password property is defined (around line 66)::
1600        user = Class(db, "user", 
1601                        username=String(),   password=String(),
1602                        address=String(),    realname=String(), 
1603                        phone=String(),      organisation=String())
1604        user.setkey("username")
1606       alter the "password=String()" to "password=Password()"::
1608        user = Class(db, "user", 
1609                        username=String(),   password=Password(),
1610                        address=String(),    realname=String(), 
1611                        phone=String(),      organisation=String())
1612        user.setkey("username")
1614 2. Any existing passwords in the database will remain cleartext until they
1615    are edited. It is recommended that at a minimum the admin password be
1616    changed immediately::
1618       roundup-admin -i <instance home> set user1 password=<new password>
1621 0.3.x Configuration
1622 -------------------
1623 FILTER_POSITION, ANONYMOUS_ACCESS, ANONYMOUS_REGISTER have been added to
1624 the instance_config.py. Simplest solution is to copy the default values from
1625 template in the core source.
1627 MESSAGES_TO_AUTHOR has been added to the IssueClass in dbinit.py. Set to 'yes'
1628 to send nosy messages to the author. Default behaviour is to not send nosy
1629 messages to the author. You will need to add MESSAGES_TO_AUTHOR to your
1630 dbinit.py in your instance home.
1633 0.3.x CGI script roundup.cgi
1634 ----------------------------
1635 There have been some structural changes to the roundup.cgi script - you will
1636 need to install it again from the cgi-bin directory of the source
1637 distribution. Make sure you update the ROUNDUP_INSTANCE_HOMES after the
1638 copy.
1641 .. _`customisation documentation`: customizing.html
1642 .. _`security documentation`: security.html
1643 .. _`administration guide`: admin_guide.html