Code

9a7d182aff2662157e32a1d79e1f01d994b9f2d3
[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.17
17 ==============================
19 There is a new config-option `migrate_passwords` in section `web` to
20 auto-migrate passwords at web-login time to a more secure storage
21 scheme. Default for the new option is "yes" so if you don't want that
22 passwords are auto-migrated to a more secure password scheme on user
23 login, set this to "no" before running your tracker(s) after the
24 upgrade.
26 The standalone roundup-server now defaults to listening on localhost (no
27 longer on all network interfaces). This will not affect you if you're
28 already using a configuration file for roundup-server. If you are using
29 an empty setting for the `host` parameter in the config-file you should
30 explicitly put 0.0.0.0 there as the use of an empty string to specify
31 listening to all interfaces is deprecated and will go away in a future
32 version.  If you are starting the server without a configuration file
33 and want to explicitly listen to all network interface, you should
34 specify the -n option with the address `0.0.0.0`.
36 Searching now requires either read-permission without a check method, or
37 you will have to add a "Search" permission for a class or a list of
38 properties for a class (if you want to allow searching). For the classic
39 template (or other templates derived from it) you want to add the
40 following lines to your `schema.py` file::
42   p = db.security.addPermission(name='Search', klass='query')
43   db.security.addPermissionToRole('User', p)
45 This is needed, because for the `query` class users may view only their
46 own queries (or public queries). This is implemented with a `check`
47 method, therefore the default search permissions will not allow
48 searching and you'll have to add an explicit search permission.
49 If you have modified your schema, you can check if you're missing any
50 search permissions with the following script, run it in your tracker
51 directory, it will list for each Class and Property the roles that may
52 search for this property::
54     #!/usr/bin/python
55     import os
56     from roundup import instance
57     
58     tracker = instance.open(os.getcwd ())
59     db = tracker.open('admin')
60     
61     for cl in sorted(db.getclasses()):
62         print "Class:", cl
63         for p in sorted(db.getclass(cl).properties.keys()):
64             print "    Property:", p
65             roles = []
66             for role in sorted(db.security.role.iterkeys()):
67                 if db.security.roleHasSearchPermission(cl,p,role):
68                     roles.append(role)
69             print "        roles may search:", ', '.join(roles)
72 Migrating from 1.4.x to 1.4.12
73 ==============================
75 Item creation now checks the "Create" permission instead of the "Edit"
76 permission for individual properties. If you have modified your tracker
77 permissions from the default distribution, you should check that
78 "Create" permissions exist for all properties you want users to be able
79 to create.
82 Fixing some potential security holes
83 ------------------------------------
85 Enhanced checking was added to the user registration auditor. If you
86 run a public tracker you should update your tracker's
87 ``detectors/userauditor.py`` using the new code from
88 ``share/roundup/templates/classic/detectors/userauditor.py``. In most
89 cases you may just copy the file over, but if you've made changes to
90 the auditor in your tracker then you'll need to manually integrate
91 the new code.
93 Some HTML templates were found to have formatting security problems:
95 ``html/page.html``::
97   -tal:replace="request/user/username">username</span></b><br>
98   +tal:replace="python:request.user.username.plain(escape=1)">username</span></b><br>
100 ``html/_generic.help-list.html``::
102   -tal:content="structure python:item[prop]"></label>
103   +tal:content="python:item[prop]"></label>
105 The lines marked "+" should be added and lines marked "-" should be
106 deleted (minus the "+"/"-" signs).
109 Some HTML interface tweaks
110 --------------------------
112 You may wish to copy the ``user_utils.js`` and ``style.css` files from the
113 source distribution ``share/roundup/templates/classic/html/`` directory to the
114 ``html`` directory of your trackers as it includes a small improvement.
116 If you have made local changes to those files you'll need to manually work
117 the differences in to your versions or ignore the changes.
120 Migrating from 1.4.x to 1.4.11
121 ==============================
123 Close potential security hole
124 -----------------------------
126 If your tracker has untrusted users you should examine its ``schema.py``
127 file and look for the section granting the "Edit" permission to your users.
128 This should look something like::
130     p = db.security.addPermission(name='Edit', klass='user', check=own_record,
131         description="User is allowed to edit their own user details")
133 and should be modified to restrict the list of properties they are allowed
134 to edit by adding the ``properties=`` section like::
136     p = db.security.addPermission(name='Edit', klass='user', check=own_record,
137         properties=('username', 'password', 'address', 'realname', 'phone',
138             'organisation', 'alternate_addresses', 'queries', 'timezone'),
139         description="User is allowed to edit their own user details")
141 Most importantly the "roles" property should not be editable - thus not
142 appear in that list of properties.
145 Grant the "Register" permission to the Anonymous role
146 -----------------------------------------------------
148 A separate "Register" permission has been introduced to allow
149 anonymous users to register. This means you will need to add the
150 following to your tracker's ``schema.py`` to add the permission and
151 assign it to the Anonymous role (replacing any previously assigned
152 "Create user" permission for the Anonymous role)::
154   +db.security.addPermission(name='Register', klass='user',
155   +     description='User is allowed to register new user')
156  
157    # Assign the appropriate permissions to the anonymous user's Anonymous
158    # Role. Choices here are:
159    # - Allow anonymous users to register
160   -db.security.addPermissionToRole('Anonymous', 'Create', 'user')
161   +db.security.addPermissionToRole('Anonymous', 'Register', 'user')
163 The lines marked "+" should be added and lines marked "-" should be
164 deleted (minus the "+"/"-" signs).
166 You should also modify the ``html/page.html`` template to change the
167 permission tested there::
169    -tal:condition="python:request.user.hasPermission('Create', 'user')"
170    +tal:condition="python:request.user.hasPermission('Register', 'user')"
173 Generic class editor may now restore retired items
174 --------------------------------------------------
176 The instructions for doing so won't be present in your tracker unless you copy
177 the ``_generic.index.html`` template from the roundup distribution in
178 ``share/roundup/templates/classic/html`` to your tracker's ``html`` directory.
181 Migrating from 1.4.x to 1.4.9
182 =============================
184 Customized MailGW Class
185 -----------------------
187 If you have customized the MailGW class in your tracker: The new MailGW
188 class opens the database for each message in the method handle_message
189 (instance.open) instead of passing the opened database as a parameter to
190 the MailGW constructor. The old handle_message has been renamed to
191 _handle_message. The new method opens the database and wraps the call to
192 the old method into a try/finally.
194 Your customized MailGW class needs to mirror this behavior.
196 Fix the "remove" button in issue files and messages lists
197 ---------------------------------------------------------
199 The "remove" button(s) in the issue messages list needs to be altered. Find
200 the following in your tracker's ``html/issue.item.html`` template::
202   <td>
203    <form style="padding:0" tal:condition="context/is_edit_ok"
204          tal:attributes="action string:issue${context/id}">
205     <input type="hidden" name="@remove@files" tal:attributes="value file/id">
207 and add ``method="POST"`` as shown below::
209   <td>
210    <form style="padding:0" method="POST" tal:condition="context/is_edit_ok"
211          tal:attributes="action string:issue${context/id}">
212     <input type="hidden" name="@remove@files" tal:attributes="value file/id">
214 Then also find::
216   <td>
217    <form style="padding:0" tal:condition="context/is_edit_ok"
218          tal:attributes="action string:issue${context/id}">
219     <input type="hidden" name="@remove@messages" tal:attributes="value msg/id">
221 and add ``method="POST"`` as shown below::
223   <td>
224    <form style="padding:0" method="POST" tal:condition="context/is_edit_ok"
225          tal:attributes="action string:issue${context/id}">
226     <input type="hidden" name="@remove@messages" tal:attributes="value msg/id">
229 Fixing the "retire" button in user management list
230 --------------------------------------------------
232 If you made the change to the "reture" link in the user management list as
233 listed below in `Migrating from 1.4.x to 1.4.7`_ then you'll need to fix that
234 change by adding ``method="POST"`` to the ``<form>`` tag::
236      <form style="padding:0" method="POST"
237            tal:attributes="action string:user${user/id}">
238       <input type="hidden" name="@template" value="index">
239       <input type="hidden" name="@action" value="retire">
240       <input type="submit" value="retire" i18n:attributes="value">
241      </form>
244 Migrating from 1.4.x to 1.4.7
245 =============================
247 Several security issues were addressed in this release. Some aspects of your
248 trackers may no longer function depending on your local customisations. Core
249 functionality that will need to be modified:
251 Grant the "retire" permission to users for their queries
252 --------------------------------------------------------
254 Users will no longer be able to retire their own queries. To remedy this you
255 will need to add the following to your tracker's ``schema.py`` just under the
256 line that grants them permission to edit their own queries::
258    p = db.security.addPermission(name='Edit', klass='query', check=edit_query,
259       description="User is allowed to edit their queries")
260    db.security.addPermissionToRole('User', p)
261  + p = db.security.addPermission(name='Retire', klass='query', check=edit_query,
262  +    description="User is allowed to retire their queries")
263  + db.security.addPermissionToRole('User', p)
264    p = db.security.addPermission(name='Create', klass='query',
265       description="User is allowed to create queries")
266    db.security.addPermissionToRole('User', p)
268 The lines marked "+" should be added, minus the "+" sign.
271 Fix the "retire" link in the users list for admin users
272 -------------------------------------------------------
274 The "retire" link found in the file ``html/user.index.html``::
276   <td tal:condition="context/is_edit_ok">
277    <a tal:attributes="href string:user${user/id}?@action=retire&@template=index"
278     i18n:translate="">retire</a>
280 Should be replaced with::
282   <td tal:condition="context/is_retire_ok">
283      <form style="padding:0" method="POST"
284            tal:attributes="action string:user${user/id}">
285       <input type="hidden" name="@template" value="index">
286       <input type="hidden" name="@action" value="retire">
287       <input type="submit" value="retire" i18n:attributes="value">
288      </form>
291 Fix for Python 2.6+ users
292 -------------------------
294 If you use Python 2.6 you should edit your tracker's
295 ``detectors/nosyreaction.py`` file to change::
297    import sets
299 at the top to::
301    from roundup.anypy.sets_ import set
303 and then all instances of ``sets.Set()`` to ``set()`` in the later code.
307 Trackers currently allowing HTML file uploading
308 -----------------------------------------------
310 Trackers which wish to continue to allow uploading of HTML content against issues
311 will need to set a new configuration variable in the ``[web]`` section of the
312 tracker's ``config.ini`` file:
314    # Setting this option enables Roundup to serve uploaded HTML
315    # file content *as HTML*. This is a potential security risk
316    # and is therefore disabled by default. Set to 'yes' if you
317    # trust *all* users uploading content to your tracker.
318    # Allowed values: yes, no
319    # Default: no
320    allow_html_file = no
324 Migrating from 1.4.2 to 1.4.3
325 =============================
327 If you are using the MySQL backend you will need to replace some indexes
328 that may have been created by version 1.4.2.
330 You should to access your MySQL database directly and remove any indexes
331 with a name ending in "_key_retired_idx". You should then re-add them with
332 the same spec except the key column name needs a size. So an index on
333 "_user (__retired, _name)" should become "_user (__retired, _name(255))".
336 Migrating from 1.4.x to 1.4.2
337 =============================
339 You should run the "roundup-admin migrate" command for your tracker once
340 you've installed the latest codebase. 
342 Do this before you use the web, command-line or mail interface and before
343 any users access the tracker.
345 This command will respond with either "Tracker updated" (if you've not
346 previously run it on an RDBMS backend) or "No migration action required"
347 (if you have run it, or have used another interface to the tracker,
348 or are using anydbm).
350 It's safe to run this even if it's not required, so just get into the
351 habit.
354 Migrating from 1.3.3 to 1.4.0
355 =============================
357 Value of the "refwd_re" tracker configuration option (section "mailgw")
358 is treated as UTF-8 string.  In previous versions, it was ISO8859-1.
360 If you have running trackers based on the classic template, please
361 update the messagesummary detector as follows::
363     --- detectors/messagesummary.py 17 Apr 2003 03:26:38 -0000      1.1
364     +++ detectors/messagesummary.py 3 Apr 2007 06:47:21 -0000       1.2
365     @@ -8,7 +8,7 @@
366      if newvalues.has_key('summary') or not newvalues.has_key('content'):
367          return
369     -    summary, content = parseContent(newvalues['content'], 1, 1)
370     +    summary, content = parseContent(newvalues['content'], config=db.config)
371      newvalues['summary'] = summary
373 In the latest version we have added some database indexes to the
374 SQL-backends (mysql, postgresql, sqlite) for speeding up building the
375 roundup-index for full-text search. We recommend that you create the
376 following database indexes on the database by hand::
378  CREATE INDEX words_by_id ON __words (_textid);
379  CREATE UNIQUE INDEX __textids_by_props ON __textids (_class, _itemid, _prop);
381 Migrating from 1.2.x to 1.3.0
382 =============================
384 1.3.0 Web interface changes
385 ---------------------------
387 Some of the HTML files in the "classic" and "minimal" tracker templates
388 were changed to fix some bugs and clean them up. You may wish to compare
389 them to the HTML files in your tracker and apply any changes.
392 Migrating from 1.1.2 to 1.2.0
393 =============================
395 1.2.0 Sorting and grouping by multiple properties
396 -------------------------------------------------
398 Starting with this version, sorting and grouping by multiple properties
399 is possible. This means that request.sort and request.group are now
400 lists. This is reflected in several places:
402  * ``renderWith`` now has list attributes for ``sort`` and ``group``,
403    where you previously wrote::
404    
405     renderWith(... sort=('-', 'activity'), group=('+', 'priority')
407    you write now::
409     renderWith(... sort=[('-', 'activity')], group=[('+', 'priority')]
411  * In templates that permit to edit sorting/grouping, request.sort and
412    request.group are (possibly empty) lists. You can now sort and group
413    by multiple attributes. For an example, see the classic template. You
414    may want search for the variable ``n_sort`` which can be set to the
415    number of sort/group properties.
417  * Templates that diplay new headlines for each group of items with
418    equal group properties can now use the modified ``batch.propchanged``
419    method that can take several properties which are checked for
420    changes. See the example in the classic template which makes use of
421    ``batch.propchanged``.
423 Migrating from 1.1.0 to 1.1.1
424 =============================
426 1.1.1 "Clear this message"
427 --------------------------
429 In 1.1.1, the standard ``page.html`` template includes a "clear this message"
430 link in the green "ok" message bar that appears after a successful edit
431 (or other) action.
433 To include this in your tracker, change the following in your ``page.html``
434 template::
436  <p tal:condition="options/ok_message | nothing" class="ok-message"
437     tal:repeat="m options/ok_message" tal:content="structure m">error</p>
439 to be::
441  <p tal:condition="options/ok_message | nothing" class="ok-message">
442    <span tal:repeat="m options/ok_message"
443       tal:content="structure string:$m <br/ > " />
444     <a class="form-small" tal:attributes="href request/current_url"
445        i18n:translate="">clear this message</a>
446  </p>
449 If you implemented the "clear this message" in your 1.1.0 tracker, then you
450 should change it to the above and it will work much better!
453 Migrating from 1.0.x to 1.1.0
454 =============================
456 1.1 Login "For Session Only"
457 ----------------------------
459 In 1.1, web logins are alive for the length of a session only, *unless* you
460 add the following to the login form in your tracker's ``page.html``::
462     <input type="checkbox" name="remember" id="remember">
463     <label for="remember" i18n:translate="">Remember me?</label><br>
465 See the classic tracker ``page.html`` if you're unsure where this should
466 go.
469 1.1 Query Display Name
470 ----------------------
472 The ``dispname`` web variable has been renamed ``@dispname`` to avoid
473 clashing with other variables of the same name. If you are using the
474 display name feature, you will need to edit your tracker's ``page.html``
475 and ``issue.index.html`` pages to change ``dispname`` to ``@dispname``.
477 A side-effect of this change is that the renderWith method used in the
478 ``home.html`` page may now take a dispname argument.
481 1.1 "Clear this message"
482 ------------------------
484 In 1.1, the standard ``page.html`` template includes a "clear this message"
485 link in the green "ok" message bar that appears after a successful edit
486 (or other) action.
488 To include this in your tracker, change the following in your ``page.html``
489 template::
491  <p tal:condition="options/ok_message | nothing" class="ok-message"
492     tal:repeat="m options/ok_message" tal:content="structure m">error</p>
494 to be::
496  <p tal:condition="options/ok_message | nothing" class="ok-message">
497    <span tal:repeat="m options/ok_message"
498       tal:content="structure string:$m <br/ > " />
499     <a class="form-small" tal:attributes="href string:issue${context/id}"
500        i18n:translate="">clear this message</a>
501  </p>
504 Migrating from 0.8.x to 1.0
505 ===========================
507 1.0 New Query Permissions
508 -------------------------
510 New permissions are defined for query editing and viewing. To include these
511 in your tracker, you need to add these lines to your tracker's
512 ``schema.py``::
514  # Users should be able to edit and view their own queries. They should also
515  # be able to view any marked as not private. They should not be able to
516  # edit others' queries, even if they're not private
517  def view_query(db, userid, itemid):
518      private_for = db.query.get(itemid, 'private_for')
519      if not private_for: return True
520      return userid == private_for
521  def edit_query(db, userid, itemid):
522      return userid == db.query.get(itemid, 'creator')
523  p = db.security.addPermission(name='View', klass='query', check=view_query,
524      description="User is allowed to view their own and public queries")
525  db.security.addPermissionToRole('User', p)
526  p = db.security.addPermission(name='Edit', klass='query', check=edit_query,
527      description="User is allowed to edit their queries")
528  db.security.addPermissionToRole('User', p)
529  p = db.security.addPermission(name='Create', klass='query',
530      description="User is allowed to create queries")
531  db.security.addPermissionToRole('User', p)
533 and then remove 'query' from the line::
535  # Assign the access and edit Permissions for issue, file and message
536  # to regular users now
537  for cl in 'issue', 'file', 'msg', 'query', 'keyword':
539 so it looks like::
541  for cl in 'issue', 'file', 'msg', 'keyword':
544 Migrating from 0.8.0 to 0.8.3
545 =============================
547 0.8.3 Nosy Handling Changes
548 ---------------------------
550 A change was made to fix a bug in the ``nosyreaction.py`` standard
551 detector. To incorporate this fix in your trackers, you will need to copy
552 the ``nosyreaction.py`` file from the ``templates/classic/detectors``
553 directory of the source to your tracker's ``templates`` directory.
555 If you have modified the ``nosyreaction.py`` file from the standard
556 version, you will need to roll your changes into the new file.
559 Migrating from 0.7.1 to 0.8.0
560 =============================
562 You *must* fully uninstall previous Roundup version before installing
563 Roundup 0.8.0.  If you don't do that, ``roundup-admin install``
564 command may fail to function properly.
566 0.8.0 Backend changes
567 ---------------------
569 Backends 'bsddb' and 'bsddb3' are removed.  If you are using one of these,
570 you *must* migrate to another backend before upgrading.
573 0.8.0 API changes
574 -----------------
576 Class.safeget() was removed from the API. Test your item ids before calling
577 Class.get() instead.
580 0.8.0 New tracker layout
581 ------------------------
583 The ``config.py`` file has been replaced by ``config.ini``. You may use the
584 roundup-admin command "genconfig" to generate a new config file::
586   roundup-admin genconfig <tracker home>/config.ini
588 and modify the values therein based on the contents of your old config.py.
589 In most cases, the names of the config variables are the same.
591 The ``select_db.py`` file has been replaced by a file in the ``db``
592 directory called ``backend_name``. As you might guess, this file contains
593 just the name of the backend. To figure what the contents of yours should
594 be, use the following table:
596   ================================ =========================
597   ``select_db.py`` contents        ``backend_name`` contents
598   ================================ =========================
599   from back_anydbm import ...      anydbm
600   from back_metakit import ...     metakit
601   from back_sqlite import ...      sqlite
602   from back_mysql import ...       mysql
603   from back_postgresql import ...  postgresql
604   ================================ =========================
606 The ``dbinit.py`` file has been split into two new files,
607 ``initial_data.py`` and ``schema.py``. The contents of this file are:
609 ``initial_data.py``
610   You don't need one of these as your tracker is already initialised.
612 ``schema.py``
613   Copy the body of the ``def open(name=None)`` function from your old
614   tracker's ``dbinit.py`` file to this file. As the lines you're copying
615   aren't part of a function definition anymore, one level of indentation
616   needs to be removed (remove only the leading four spaces on each
617   line). 
619   The first few lines -- those starting with ``from roundup.hyperdb
620   import ...`` and the ``db = Database(config, name)`` line -- don't
621   need to be copied. Neither do the last few lines -- those starting
622   with ``import detectors``, down to ``return db`` inclusive.
624 You may remove the ``__init__.py`` module from the "detectors" directory as
625 it is no longer used.
627 There's a new way to write extension code for Roundup. If you have code in
628 an ``interfaces.py`` file you should move it. See the `customisation
629 documentation`_ for information about how extensions are now written.
630 Note that some older trackers may use ``interfaces.py`` to customise the
631 mail gateway behaviour. You will need to keep your ``interfaces.py`` file
632 if this is the case.
635 0.8.0 Permissions Changes
636 -------------------------
638 The creation of a new item in the user interfaces is now controlled by the
639 "Create" Permission. You will need to add an assignment of this Permission
640 to your users who are allowed to create items. The most common form of this
641 is the following in your ``schema.py`` added just under the current
642 assignation of the Edit Permission::
644     for cl in 'issue', 'file', 'msg', 'query', 'keyword':
645         p = db.security.getPermission('Create', cl)
646         db.security.addPermissionToRole('User', p)
648 You will need to explicitly let anonymous users access the web interface so
649 that regular users are able to see the login form. Note that almost all
650 trackers will need this Permission. The only situation where it's not
651 required is in a tracker that uses an HTTP Basic Authenticated front-end.
652 It's enabled by adding to your ``schema.py``::
654     p = db.security.getPermission('Web Access')
655     db.security.addPermissionToRole('Anonymous', p)
657 Finally, you will need to enable permission for your users to edit their
658 own details by adding the following to ``schema.py``::
660     # Users should be able to edit their own details. Note that this
661     # permission is limited to only the situation where the Viewed or
662     # Edited item is their own.
663     def own_record(db, userid, itemid):
664         '''Determine whether the userid matches the item being accessed.'''
665         return userid == itemid
666     p = db.security.addPermission(name='View', klass='user', check=own_record,
667         description="User is allowed to view their own user details")
668     p = db.security.addPermission(name='Edit', klass='user', check=own_record,
669         description="User is allowed to edit their own user details")
670     db.security.addPermissionToRole('User', p)
673 0.8.0 Use of TemplatingUtils
674 ----------------------------
676 If you used custom python functions in TemplatingUtils, they must
677 be moved from interfaces.py to a new file in the ``extensions`` directory. 
679 Each Function that should be available through TAL needs to be defined
680 as a toplevel function in the newly created file. Furthermore you
681 add an inititialization function, that registers the functions with the 
682 tracker.
684 If you find this too tedious, donfu wrote an automatic init function that
685 takes an existing TemplatingUtils class, and registers all class methods
686 that do not start with an underscore. The following hack should be placed
687 in the ``extensions`` directory alongside other extensions::
689     class TemplatingUtils:
690          # copy from interfaces.py
692     def init(tracker):
693          util = TemplatingUtils()
695          def setClient(tu):
696              util.client = tu.client
697              return util
699          def execUtil(name):
700              return lambda tu, *args, **kwargs: \
701                      getattr(setClient(tu), name)(*args, **kwargs)
703          for name in dir(util):
704              if callable(getattr(util, name)) and not name.startswith('_'):
705                   tracker.registerUtil(name, execUtil(name))
708 0.8.0 Logging Configuration
709 ---------------------------
711 See the `administration guide`_ for information about configuring the new
712 logging implemented in 0.8.0.
715 Migrating from 0.7.2 to 0.7.3
716 =============================
718 0.7.3 Configuration
719 -------------------
721 If you choose, you may specify the directory from which static files are
722 served (those which use the URL component ``@@file``). Currently the
723 directory defaults to the ``TEMPLATES`` configuration variable. You may
724 define a new variable, ``STATIC_FILES`` which overrides this value for
725 static files.
728 Migrating from 0.7.0 to 0.7.2
729 =============================
731 0.7.2 DEFAULT_TIMEZONE is now required
732 --------------------------------------
734 The DEFAULT_TIMEZONE configuration variable is now required. Add the
735 following to your tracker's ``config.py`` file::
737     # You may specify a different default timezone, for use when users do not
738     # choose their own in their settings.
739     DEFAULT_TIMEZONE = 0            # specify as numeric hour offest
742 Migrating from 0.7.0 to 0.7.1
743 =============================
745 0.7.1 Permission assignments
746 ----------------------------
748 If you allow anonymous access to your tracker, you might need to assign
749 some additional View (or Edit if your tracker is that open) permissions
750 to the "anonymous" user. To do so, find the code in your ``dbinit.py`` that
751 says::
753     for cl in 'issue', 'file', 'msg', 'query', 'keyword':
754         p = db.security.getPermission('View', cl)
755         db.security.addPermissionToRole('User', p)
756         p = db.security.getPermission('Edit', cl)
757         db.security.addPermissionToRole('User', p)
758     for cl in 'priority', 'status':
759         p = db.security.getPermission('View', cl)
760         db.security.addPermissionToRole('User', p)
762 Add add a line::
764         db.security.addPermissionToRole('Anonymous', p)
766 next to the existing ``'User'`` lines for the Permissions you wish to
767 assign to the anonymous user.
770 Migrating from 0.6 to 0.7
771 =========================
773 0.7.0 Permission assignments
774 ----------------------------
776 Due to a change in the rendering of web widgets, permissions are now
777 checked on Classes where they previously weren't (this is a good thing).
779 You will need to add some additional Permission assignments for your
780 regular users, or some displays will break. After the following in your 
781 tracker's ``dbinit.py``::
783     # Assign the access and edit Permissions for issue, file and message
784     # to regular users now
785     for cl in 'issue', 'file', 'msg', 'query', 'keyword':
786         p = db.security.getPermission('View', cl)
787         db.security.addPermissionToRole('User', p)
788         p = db.security.getPermission('Edit', cl)
789         db.security.addPermissionToRole('User', p)
791 add::
793     for cl in 'priority', 'status':
794         p = db.security.getPermission('View', cl)
795         db.security.addPermissionToRole('User', p)
798 0.7.0 Getting the current user id
799 ---------------------------------
801 The Database.curuserid attribute has been removed.
803 Any code referencing this attribute should be replaced with a
804 call to Database.getuid().
807 0.7.0 ZRoundup changes
808 ----------------------
810 The templates in your tracker's html directory will need updating if you
811 wish to use ZRoundup. If you've not modified those files (or some of them),
812 you may just copy the new versions from the Roundup source in the
813 templates/classic/html directory.
815 If you have modified the html files, then you'll need to manually edit them
816 to change all occurances of special form variables from using the colon ":"
817 special character to the at "@" special character. That is, variables such
818 as::
820   :action :required :template :remove:messages ...
822 should become::
824   @action @required @template @remove@messages ...
826 Note that ``tal:`` statements are unaffected. So are TAL expression type
827 prefixes such as ``python:`` and ``string:``. Please ask on the
828 roundup-users mailing list for help if you're unsure.
831 0.7.0 Edit collision detection
832 ------------------------------
834 Roundup now detects collisions with editing in the web interface (that is,
835 two people editing the same item at the same time).
837 You must copy the ``_generic.collision.html`` file from Roundup source in
838 the ``templates/classic/html`` directory. to your tracker's ``html``
839 directory.
842 Migrating from 0.6.x to 0.6.3
843 =============================
845 0.6.3 Configuration
846 -------------------
848 You will need to copy the file::
850   templates/classic/detectors/__init__.py
852 to your tracker's ``detectors`` directory, replacing the one already there.
853 This fixes a couple of bugs in that file.
857 Migrating from 0.5 to 0.6
858 =========================
861 0.6.0 Configuration
862 -------------------
864 Introduced EMAIL_FROM_TAG config variable. This value is inserted into
865 the From: line of nosy email. If the sending user is "Foo Bar", the
866 From: line is usually::
868      "Foo Bar" <issue_tracker@tracker.example>
870 the EMAIL_FROM_TAG goes inside the "Foo Bar" quotes like so::
872      "Foo Bar EMAIL_FROM_TAG" <issue_tracker@tracker.example>
874 I've altered the mechanism in the detectors __init__.py module so that it
875 doesn't cross-import detectors from other trackers (if you run more than one
876 in a single roundup-server). This change means that you'll need to copy the
877 __init__.py from roundup/templates/classic/detectors/__init__.py to your
878 <tracker home>/detectors/__init__.py. Don't worry, the "classic" __init__ is a
879 one-size-fits-all, so it'll work even if you've added/removed detectors.
881 0.6.0 Templating changes
882 ------------------------
884 The ``user.item`` template (in the tracker home "templates" directory)
885 needs to have the following hidden variable added to its form (between the
886 ``<form...>`` and ``</form>`` tags::
888   <input type="hidden" name=":template" value="item">
891 0.6.0 Form handling changes
892 ---------------------------
894 Roundup's form handling capabilities have been significantly expanded. This
895 should not affect users of 0.5 installations - but if you find you're
896 getting errors from form submissions, please ask for help on the Roundup
897 users mailing list:
899   http://lists.sourceforge.net/lists/listinfo/roundup-users
901 See the customisation doc section on `Form Values`__ for documentation of the
902 new form variables possible.
904 __ customizing.html#form-values
907 0.6.0 Multilingual character set support
908 ----------------------------------------
910 Added internationalization support. This is done via encoding all data
911 stored in roundup database to utf-8 (unicode encoding). To support utf-8 in
912 web interface you should add the folowing line to your tracker's html/page
913 and html/_generic.help files inside <head> tag::
914   
915     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
917 Since latin characters in utf-8 have the same codes as in ASCII table, this
918 modification is optional for users who use only plain latin characters. 
920 After this modification, you will be able to see and enter any world
921 character via web interface. Data received via mail interface also converted
922 to utf-8, however only new messages will be converted. If your roundup
923 database contains some of non-ASCII characters in one of 8-bit encoding,
924 they will not be visible in new unicode environment. Some of such data (e.g.
925 user names, keywords, etc)  can be edited by administrator, the others
926 (e.g. messages' contents) is not editable via web interface. Currently there
927 is no tool for converting such data, the only solution is to close
928 appropriate old issues and create new ones with the same content.
931 0.6.0 User timezone support
932 ---------------------------
934 From version 0.6.0 roundup supports displaying of Date data in user' local
935 timezone if he/she has provided timezone information. To make it possible
936 some modification to tracker's schema and HTML templates are required.
937 First you must add string property 'timezone' to user class in dbinit.py
938 like this::
939   
940     user = Class(db, "user", 
941                     username=String(),   password=Password(),
942                     address=String(),    realname=String(), 
943                     phone=String(),      organisation=String(),
944                     alternate_addresses=String(),
945                     queries=Multilink('query'), roles=String(),
946                     timezone=String())
947   
948 And second - html interface. Add following lines to
949 $TRACKER_HOME/html/user.item template::
950   
951      <tr>
952       <th>Timezone</th>
953       <td tal:content="structure context/timezone/field">timezone</td>
954      </tr>
956 After that all users should be able to provide their timezone information.
957 Timezone should be a positive or negative integer - offset from GMT.
959 After providing timezone, roundup will show all dates values, found in web
960 and mail interfaces in local time. It will also accept any Date info in
961 local time, convert and store it in GMT.
964 0.6.0 Search page structure
965 ---------------------------
967 In order to accomodate query editing the search page has been restructured. If
968 you want to provide your users with query editing, you should update your
969 search page using the macros detailed in the customisation doc section
970 `Searching on categories`__.
972 __ customizing.html#searching-on-categories
974 Also, the url field in the query class no longer starts with a '?'. You'll need
975 to remove this question mark from the url field to support queries. There's
976 a script in the "tools" directory called ``migrate-queries.py`` that should
977 automatically change any existing queries for you. As always, make a backup
978 of your database before running such a script.
981 0.6.0 Notes for metakit backend users
982 -------------------------------------
984 Roundup 0.6.0 introduced searching on ranges of dates and intervals. To
985 support it, some modifications to interval storing routine were made. So if
986 your tracker uses metakit backend and your db schema contains intervals
987 property, searches on that property will not be accurate for db items that
988 was stored before roundup' upgrade. However all new records should be
989 searchable on intervals.
991 It is possible to convert your database to new format: you can export and
992 import back all your data (consult "Migrating backends" in "Maintenance"
993 documentation). After this operation all your interval properties should
994 become searchable.
996 Users of backends others than metakit should not worry about this issue.
999 Migrating from 0.4.x to 0.5.0
1000 =============================
1002 This has been a fairly major revision of Roundup:
1004 1. Brand new, much more powerful, flexible, tasty and nutritious templating.
1005    Unfortunately, this means all your current templates are useless. Hopefully
1006    the new documentation and examples will be enough to help you make the
1007    transition. Please don't hesitate to ask on roundup-users for help (or
1008    complete conversions if you're completely stuck)!
1009 2. The database backed got a lot more flexible, allowing Metakit and SQL
1010    databases! The only decent SQL database implemented at present is sqlite,
1011    but others shouldn't be a whole lot more work.
1012 3. A brand new, highly flexible and much more robust security system including
1013    a system of Permissions, Roles and Role assignments to users. You may now
1014    define your own Permissions that may be checked in CGI transactions.
1015 4. Journalling has been made less storage-hungry, so has been turned on
1016    by default *except* for author, recipient and nosy link/unlink events. You
1017    are advised to turn it off in your trackers too.
1018 5. We've changed the terminology from "instance" to "tracker", to ease the
1019    learning curve/impact for new users.
1020 6. Because of the above changes, the tracker configuration has seen some
1021    major changes. See below for the details.
1023 Please, **back up your database** before you start the migration process. This
1024 is as simple as copying the "db" directory and all its contents from your
1025 tracker to somewhere safe.
1028 0.5.0 Configuration
1029 -------------------
1031 First up, rename your ``instance_config.py`` file to just ``config.py``.
1033 Then edit your tracker's ``__init__.py`` module. It'll currently look
1034 like this::
1036  from instance_config import *
1037  try:
1038      from dbinit import *
1039  except ImportError:
1040      pass # in installdir (probably :)
1041  from interfaces import *
1043 and it needs to be::
1045  import config
1046  from dbinit import open, init
1047  from interfaces import Client, MailGW
1049 Due to the new templating having a top-level ``page`` that defines links for
1050 searching, indexes, adding items etc, the following variables are no longer
1051 used:
1053 - HEADER_INDEX_LINKS
1054 - HEADER_ADD_LINKS
1055 - HEADER_SEARCH_LINKS
1056 - SEARCH_FILTERS
1057 - DEFAULT_INDEX
1058 - UNASSIGNED_INDEX
1059 - USER_INDEX
1060 - ISSUE_FILTER
1062 The new security implementation will require additions to the dbinit module,
1063 but also removes the need for the following tracker config variables:
1065 - ANONYMOUS_ACCESS
1066 - ANONYMOUS_REGISTER
1068 but requires two new variables which define the Roles assigned to users who
1069 register through the web and e-mail interfaces:
1071 - NEW_WEB_USER_ROLES
1072 - NEW_EMAIL_USER_ROLES
1074 in both cases, 'User' is a good initial setting. To emulate
1075 ``ANONYMOUS_ACCESS='deny'``, remove all "View" Permissions from the
1076 "Anonymous" Role. To emulate ``ANONYMOUS_REGISTER='deny'``, remove the "Web
1077 Registration" and/or the "Email Registration" Permission from the "Anonymous"
1078 Role. See the section on customising security in the `customisation
1079 documentation`_ for more information.
1081 Finally, the following config variables have been renamed to make more sense:
1083 - INSTANCE_HOME -> TRACKER_HOME
1084 - INSTANCE_NAME -> TRACKER_NAME
1085 - ISSUE_TRACKER_WEB -> TRACKER_WEB
1086 - ISSUE_TRACKER_EMAIL -> TRACKER_EMAIL
1089 0.5.0 Schema Specification
1090 --------------------------
1092 0.5.0 Database backend changes
1093 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1095 Your select_db module in your tracker has changed a fair bit. Where it used
1096 to contain::
1098  # WARNING: DO NOT EDIT THIS FILE!!!
1099  from roundup.backends.back_anydbm import Database
1101 it must now contain::
1103  # WARNING: DO NOT EDIT THIS FILE!!!
1104  from roundup.backends.back_anydbm import Database, Class, FileClass, IssueClass
1106 Yes, I realise the irony of the "DO NOT EDIT THIS FILE" statement :)
1107 Note the addition of the Class, FileClass, IssueClass imports. These are very
1108 important, as they're going to make the next change work too. You now need to
1109 modify the top of the dbinit module in your tracker from::
1111  import instance_config
1112  from roundup import roundupdb
1113  from select_db import Database
1115  from roundup.roundupdb import Class, FileClass
1117  class Database(roundupdb.Database, select_db.Database):
1118      ''' Creates a hybrid database from:
1119           . the selected database back-end from select_db
1120           . the roundup extensions from roundupdb
1121      '''
1122      pass
1124  class IssueClass(roundupdb.IssueClass):
1125      ''' issues need the email information
1126      '''
1127      pass
1129 to::
1131  import config
1132  from select_db import Database, Class, FileClass, IssueClass
1134 Yes, remove the Database and IssueClass definitions and those other imports.
1135 They're not needed any more!
1137 Look for places in dbinit.py where ``instance_config`` is used too, and
1138 rename them ``config``.
1141 0.5.0 Journalling changes
1142 ~~~~~~~~~~~~~~~~~~~~~~~~~
1144 Journalling has been optimised for storage. Journalling of links has been
1145 turned back on by default. If your tracker has a large user base, you may wish
1146 to turn off journalling of nosy list, message author and message recipient
1147 link and unlink events. You do this by adding ``do_journal='no'`` to the Class
1148 initialisation in your dbinit. For example, your *msg* class initialisation
1149 probably looks like this::
1151     msg = FileClass(db, "msg",
1152                     author=Link("user"), recipients=Multilink("user"),
1153                     date=Date(),         summary=String(),
1154                     files=Multilink("file"),
1155                     messageid=String(),  inreplyto=String())
1157 to turn off journalling of author and recipient link events, add
1158 ``do_journal='no'`` to the ``author=Link("user")`` part of the statement,
1159 like so::
1161     msg = FileClass(db, "msg",
1162                     author=Link("user", do_journal='no'),
1163                     recipients=Multilink("user", do_journal='no'),
1164                     date=Date(),         summary=String(),
1165                     files=Multilink("file"),
1166                     messageid=String(),  inreplyto=String())
1168 Nosy list link event journalling is actually turned off by default now. If you
1169 want to turn it on, change to your issue class' nosy list, change its
1170 definition from::
1172     issue = IssueClass(db, "issue",
1173                     assignedto=Link("user"), topic=Multilink("keyword"),
1174                     priority=Link("priority"), status=Link("status"))
1176 to::
1178     issue = IssueClass(db, "issue", nosy=Multilink("user", do_journal='yes'),
1179                     assignedto=Link("user"), topic=Multilink("keyword"),
1180                     priority=Link("priority"), status=Link("status"))
1182 noting that your definition of the nosy Multilink will override the normal one.
1185 0.5.0 User schema changes
1186 ~~~~~~~~~~~~~~~~~~~~~~~~~
1188 Users have two more properties, "queries" and "roles". You'll have something
1189 like this in your dbinit module now::
1191     user = Class(db, "user",
1192                     username=String(),   password=Password(),
1193                     address=String(),    realname=String(),
1194                     phone=String(),      organisation=String(),
1195                     alternate_addresses=String())
1196     user.setkey("username")
1198 and you'll need to add the new properties and the new "query" class to it
1199 like so::
1201     query = Class(db, "query",
1202                     klass=String(),     name=String(),
1203                     url=String())
1204     query.setkey("name")
1206     # Note: roles is a comma-separated string of Role names
1207     user = Class(db, "user",
1208                     username=String(),   password=Password(),
1209                     address=String(),    realname=String(),
1210                     phone=String(),      organisation=String(),
1211                     alternate_addresses=String(),
1212                     queries=Multilink('query'), roles=String())
1213     user.setkey("username")
1215 The "queries" property is used to store off the user's favourite database
1216 queries. The "roles" property is explained below in `0.5.0 Security
1217 Settings`_.
1220 0.5.0 Security Settings
1221 ~~~~~~~~~~~~~~~~~~~~~~~
1223 See the `security documentation`_ for an explanation of how the new security
1224 system works. In a nutshell though, the security is handled as a four step
1225 process:
1227 1. Permissions are defined as having a name and optionally a hyperdb class
1228    they're specific to,
1229 2. Roles are defined that have one or more Permissions,
1230 3. Users are assigned Roles in their "roles" property, and finally
1231 4. Roundup checks that users have appropriate Permissions at appropriate times
1232    (like editing issues).
1234 Your tracker dbinit module's *open* function now has to define any
1235 Permissions that are specific to your tracker, and also the assignment
1236 of Permissions to Roles. At the moment, your open function
1237 ends with::
1239     import detectors
1240     detectors.init(db)
1242     return db
1244 and what we need to do is insert some commands that will set up the security
1245 parameters. Right above the ``import detectors`` line, you'll want to insert
1246 these lines::
1248     #
1249     # SECURITY SETTINGS
1250     #
1251     # new permissions for this schema
1252     for cl in 'issue', 'file', 'msg', 'user':
1253         db.security.addPermission(name="Edit", klass=cl,
1254             description="User is allowed to edit "+cl)
1255         db.security.addPermission(name="View", klass=cl,
1256             description="User is allowed to access "+cl)
1258     # Assign the access and edit permissions for issue, file and message
1259     # to regular users now
1260     for cl in 'issue', 'file', 'msg':
1261         p = db.security.getPermission('View', cl)
1262         db.security.addPermissionToRole('User', p)
1263         p = db.security.getPermission('Edit', cl)
1264         db.security.addPermissionToRole('User', p)
1265     # and give the regular users access to the web and email interface
1266     p = db.security.getPermission('Web Access')
1267     db.security.addPermissionToRole('User', p)
1268     p = db.security.getPermission('Email Access')
1269     db.security.addPermissionToRole('User', p)
1271     # May users view other user information? Comment these lines out
1272     # if you don't want them to
1273     p = db.security.getPermission('View', 'user')
1274     db.security.addPermissionToRole('User', p)
1276     # Assign the appropriate permissions to the anonymous user's Anonymous
1277     # Role. Choices here are:
1278     # - Allow anonymous users to register through the web
1279     p = db.security.getPermission('Web Registration')
1280     db.security.addPermissionToRole('Anonymous', p)
1281     # - Allow anonymous (new) users to register through the email gateway
1282     p = db.security.getPermission('Email Registration')
1283     db.security.addPermissionToRole('Anonymous', p)
1284     # - Allow anonymous users access to the "issue" class of data
1285     #   Note: this also grants access to related information like files,
1286     #         messages, statuses etc that are linked to issues
1287     #p = db.security.getPermission('View', 'issue')
1288     #db.security.addPermissionToRole('Anonymous', p)
1289     # - Allow anonymous users access to edit the "issue" class of data
1290     #   Note: this also grants access to create related information like
1291     #         files and messages etc that are linked to issues
1292     #p = db.security.getPermission('Edit', 'issue')
1293     #db.security.addPermissionToRole('Anonymous', p)
1295     # oh, g'wan, let anonymous access the web interface too
1296     p = db.security.getPermission('Web Access')
1297     db.security.addPermissionToRole('Anonymous', p)
1299 Note in the comments there the places where you might change the permissions
1300 to restrict users or grant users more access. If you've created additional
1301 classes that users should be able to edit and view, then you should add them
1302 to the "new permissions for this schema" section at the start of the security
1303 block. Then add them to the "Assign the access and edit permissions" section
1304 too, so people actually have the new Permission you've created.
1306 One final change is needed that finishes off the security system's
1307 initialisation. We need to add a call to ``db.post_init()`` at the end of the
1308 dbinit open() function. Add it like this::
1310     import detectors
1311     detectors.init(db)
1313     # schema is set up - run any post-initialisation
1314     db.post_init()
1315     return db
1317 You may verify the setup of Permissions and Roles using the new
1318 "``roundup-admin security``" command.
1321 0.5.0 User changes
1322 ~~~~~~~~~~~~~~~~~~
1324 To support all those schema changes, you'll need to massage your user database
1325 a little too, to:
1327 1. make sure there's an "anonymous" user - this user is mandatory now and is
1328    the one that unknown users are logged in as.
1329 2. make sure all users have at least one Role.
1331 If you don't have the "anonymous" user, create it now with the command::
1333   roundup-admin create user username=anonymous roles=Anonymous
1335 making sure the capitalisation is the same as above. Once you've done that,
1336 you'll need to set the roles property on all users to a reasonable default.
1337 The admin user should get "Admin", the anonymous user "Anonymous"
1338 and all other users "User". The ``fixroles.py`` script in the tools directory
1339 will do this. Run it like so (where python is your python 2+ binary)::
1341   python tools/fixroles.py -i <tracker home> fixroles
1345 0.5.0 CGI interface changes
1346 ---------------------------
1348 The CGI interface code was completely reorganised and largely rewritten. The
1349 end result is that this section of your tracker interfaces module will need
1350 changing from::
1352  from roundup import cgi_client, mailgw
1353  from roundup.i18n import _
1354  
1355  class Client(cgi_client.Client):
1356      ''' derives basic CGI implementation from the standard module,
1357          with any specific extensions
1358      '''
1359      pass
1361 to::
1363  from roundup import mailgw
1364  from roundup.cgi import client
1365  
1366  class Client(client.Client): 
1367      ''' derives basic CGI implementation from the standard module,
1368          with any specific extensions
1369      '''
1370      pass
1372 You will also need to install the new version of roundup.cgi from the source
1373 cgi-bin directory if you're using it.
1376 0.5.0 HTML templating
1377 ---------------------
1379 You'll want to make a backup of your current tracker html directory. You
1380 should then copy the html directory from the Roundup source "classic" template
1381 and modify it according to your local schema changes.
1383 If you need help with the new templating system, please ask questions on the
1384 roundup-users mailing list (available through the roundup project page on
1385 sourceforge, http://roundup.sf.net/)
1388 0.5.0 Detectors
1389 ---------------
1391 The nosy reactor has been updated to handle the tracker not having an
1392 "assignedto" property on issues. You may want to copy it into your tracker's
1393 detectors directory. Chances are you've already fixed it though :)
1396 Migrating from 0.4.1 to 0.4.2
1397 =============================
1399 0.4.2 Configuration
1400 -------------------
1401 The USER_INDEX definition introduced in 0.4.1 was too restrictive in its
1402 allowing replacement of 'assignedto' with the user's userid. Users must change
1403 the None value of 'assignedto' to 'CURRENT USER' (the string, in quotes) for
1404 the replacement behaviour to occur now.
1406 The new configuration variables are:
1408 - EMAIL_KEEP_QUOTED_TEXT 
1409 - EMAIL_LEAVE_BODY_UNCHANGED
1410 - ADD_RECIPIENTS_TO_NOSY
1412 See the sample configuration files in::
1414  <roundup source>/roundup/templates/classic/instance_config.py
1416 and::
1418  <roundup source>/roundup/templates/extended/instance_config.py
1420 and the `customisation documentation`_ for information on how they're used.
1423 0.4.2 Changes to detectors
1424 --------------------------
1425 You will need to copy the detectors from the distribution into your instance
1426 home "detectors" directory. If you used the classic schema, the detectors
1427 are in::
1429  <roundup source>/roundup/templates/classic/detectors/
1431 If you used the extended schema, the detectors are in::
1433  <roundup source>/roundup/templates/extended/detectors/
1435 The change means that schema-specific code has been removed from the
1436 mail gateway and cgi interface and made into auditors:
1438 - nosyreactor.py has now got an updatenosy auditor which updates the nosy
1439   list with author, recipient and assignedto information.
1440 - statusauditor.py makes the unread or resolved -> chatting changes and
1441   presets the status of an issue to unread.
1443 There's also a bug or two fixed in the nosyreactor code.
1445 0.4.2 HTML templating changes
1446 -----------------------------
1447 The link() htmltemplate function now has a "showid" option for links and
1448 multilinks. When true, it only displays the linked item id as the anchor
1449 text. The link value is displayed as a tooltip using the title anchor
1450 attribute. To use in eg. the superseder field, have something like this::
1452    <td>
1453     <display call="field('superseder', showid=1)">
1454     <display call="classhelp('issue', 'id,title', label='list', width=500)">
1455     <property name="superseder">
1456      <br>View: <display call="link('superseder', showid=1)">
1457     </property>
1458    </td>
1460 The stylesheets have been cleaned up too. You may want to use the newer
1461 versions in::
1463  <roundup source>/roundup/templates/<template>/html/default.css
1467 Migrating from 0.4.0 to 0.4.1
1468 =============================
1470 0.4.1 Files storage
1471 -------------------
1473 Messages and files from newly created issues will be put into subdierectories
1474 in thousands e.g. msg123 will be put into files/msg/0/msg123, file2003
1475 will go into files/file/2/file2003. Previous messages are still found, but
1476 could be put into this structure.
1478 0.4.1 Configuration
1479 -------------------
1481 To allow more fine-grained access control, the variable used to check
1482 permission to auto-register users in the mail gateway is now called
1483 ANONYMOUS_REGISTER_MAIL rather than overloading ANONYMOUS_REGISTER. If the
1484 variable doesn't exist, then ANONYMOUS_REGISTER is tested as before.
1486 Configuring the links in the web header is now easier too. The following
1487 variables have been added to the classic instance_config.py::
1489   HEADER_INDEX_LINKS   - defines the "index" links to be made available
1490   HEADER_ADD_LINKS     - defines the "add" links
1491   DEFAULT_INDEX        - specifies the index view for DEFAULT
1492   UNASSIGNED_INDEX     - specifies the index view for UNASSIGNED
1493   USER_INDEX           - specifies the index view for USER
1495 See the <roundup source>/roundup/templates/classic/instance_config.py for more
1496 information - including how the variables are to be set up. Most users will
1497 just be able to copy the variables from the source to their instance home. If
1498 you've modified the header by changing the source of the interfaces.py file in
1499 the instance home, you'll need to remove that customisation and move it into
1500 the appropriate variables in instance_config.py.
1502 The extended schema has similar variables added too - see the source for more
1503 info.
1505 0.4.1 Alternate E-Mail Addresses
1506 --------------------------------
1508 If you add the property "alternate_addresses" to your user class, your users
1509 will be able to register alternate email addresses that they may use to
1510 communicate with roundup as. All email from roundup will continue to be sent
1511 to their primary address.
1513 If you have not edited the dbinit.py file in your instance home directory,
1514 you may simply copy the new dbinit.py file from the core code. If you used
1515 the classic schema, the interfaces file is in::
1517  <roundup source>/roundup/templates/classic/dbinit.py
1519 If you used the extended schema, the file is in::
1521  <roundup source>/roundup/templates/extended/dbinit.py 
1523 If you have modified your dbinit.py file, you need to edit the dbinit.py
1524 file in your instance home directory. Find the lines which define the user
1525 class::
1527     user = Class(db, "msg",
1528                     username=String(),   password=Password(),
1529                     address=String(),    realname=String(), 
1530                     phone=String(),      organisation=String(),
1531                     alternate_addresses=String())
1533 You will also want to add the property to the user's details page. The
1534 template for this is the "user.item" file in your instance home "html"
1535 directory. Similar to above, you may copy the file from the roundup source if
1536 you haven't modified it. Otherwise, add the following to the template::
1538    <display call="multiline('alternate_addresses')">
1540 with appropriate labelling etc. See the standard template for an idea.
1544 Migrating from 0.3.x to 0.4.0
1545 =============================
1547 0.4.0 Message-ID and In-Reply-To addition
1548 -----------------------------------------
1549 0.4.0 adds the tracking of messages by message-id and allows threading
1550 using in-reply-to. Most e-mail clients support threading using this
1551 feature, and we hope to add support for it to the web gateway. If you
1552 have not edited the dbinit.py file in your instance home directory, you may
1553 simply copy the new dbinit.py file from the core code. If you used the
1554 classic schema, the interfaces file is in::
1556  <roundup source>/roundup/templates/classic/dbinit.py
1558 If you used the extended schema, the file is in::
1560  <roundup source>/roundup/templates/extended/dbinit.py 
1562 If you have modified your dbinit.py file, you need to edit the dbinit.py
1563 file in your instance home directory. Find the lines which define the msg
1564 class::
1566     msg = FileClass(db, "msg",
1567                     author=Link("user"), recipients=Multilink("user"),
1568                     date=Date(),         summary=String(),
1569                     files=Multilink("file"))
1571 and add the messageid and inreplyto properties like so::
1573     msg = FileClass(db, "msg",
1574                     author=Link("user"), recipients=Multilink("user"),
1575                     date=Date(),         summary=String(),
1576                     files=Multilink("file"),
1577                     messageid=String(),  inreplyto=String())
1579 Also, configuration is being cleaned up. This means that your dbinit.py will
1580 also need to be changed in the open function. If you haven't changed your
1581 dbinit.py, the above copy will be enough. If you have, you'll need to change
1582 the line (round line 50)::
1584     db = Database(instance_config.DATABASE, name)
1586 to::
1588     db = Database(instance_config, name)
1591 0.4.0 Configuration
1592 --------------------
1593 ``TRACKER_NAME`` and ``EMAIL_SIGNATURE_POSITION`` have been added to the
1594 instance_config.py. The simplest solution is to copy the default values
1595 from template in the core source.
1597 The mail gateway now checks ``ANONYMOUS_REGISTER`` to see if unknown users
1598 are to be automatically registered with the tracker. If it is set to "deny"
1599 then unknown users will not have access. If it is set to "allow" they will be
1600 automatically registered with the tracker.
1603 0.4.0 CGI script roundup.cgi
1604 ----------------------------
1605 The CGI script has been updated with some features and a bugfix, so you should
1606 copy it from the roundup cgi-bin source directory again. Make sure you update
1607 the ROUNDUP_INSTANCE_HOMES after the copy.
1610 0.4.0 Nosy reactor
1611 ------------------
1612 The nosy reactor has also changed - copy the nosyreactor.py file from the core
1613 source::
1615    <roundup source>/roundup/templates/<template>/detectors/nosyreactor.py
1617 to your instance home "detectors" directory.
1620 0.4.0 HTML templating
1621 ---------------------
1622 The field() function was incorrectly implemented - links and multilinks now
1623 display as text fields when rendered using field(). To display a menu (drop-
1624 down or select box) you need to use the menu() function.
1628 Migrating from 0.2.x to 0.3.x
1629 =============================
1631 0.3.x Cookie Authentication changes
1632 -----------------------------------
1633 0.3.0 introduces cookie authentication - you will need to copy the
1634 interfaces.py file from the roundup source to your instance home to enable
1635 authentication. If you used the classic schema, the interfaces file is in::
1637  <roundup source>/roundup/templates/classic/interfaces.py
1639 If you used the extended schema, the file is in::
1641  <roundup source>/roundup/templates/extended/interfaces.py
1643 If you have modified your interfaces.Client class, you will need to take
1644 note of the login/logout functionality provided in roundup.cgi_client.Client
1645 (classic schema) or roundup.cgi_client.ExtendedClient (extended schema) and
1646 modify your instance code apropriately.
1649 0.3.x Password encoding
1650 -----------------------
1651 This release also introduces encoding of passwords in the database. If you
1652 have not edited the dbinit.py file in your instance home directory, you may
1653 simply copy the new dbinit.py file from the core code. If you used the
1654 classic schema, the interfaces file is in::
1656  <roundup source>/roundup/templates/classic/dbinit.py
1658 If you used the extended schema, the file is in::
1660  <roundup source>/roundup/templates/extended/dbinit.py
1663 If you have modified your dbinit.py file, you may use encoded passwords:
1665 1. Edit the dbinit.py file in your instance home directory
1666    a. At the first code line of the open() function::
1668        from roundup.hyperdb import String, Date, Link, Multilink
1670       alter to include Password, as so::
1672        from roundup.hyperdb import String, Password, Date, Link, Multilink
1674    b. Where the password property is defined (around line 66)::
1676        user = Class(db, "user", 
1677                        username=String(),   password=String(),
1678                        address=String(),    realname=String(), 
1679                        phone=String(),      organisation=String())
1680        user.setkey("username")
1682       alter the "password=String()" to "password=Password()"::
1684        user = Class(db, "user", 
1685                        username=String(),   password=Password(),
1686                        address=String(),    realname=String(), 
1687                        phone=String(),      organisation=String())
1688        user.setkey("username")
1690 2. Any existing passwords in the database will remain cleartext until they
1691    are edited. It is recommended that at a minimum the admin password be
1692    changed immediately::
1694       roundup-admin -i <instance home> set user1 password=<new password>
1697 0.3.x Configuration
1698 -------------------
1699 FILTER_POSITION, ANONYMOUS_ACCESS, ANONYMOUS_REGISTER have been added to
1700 the instance_config.py. Simplest solution is to copy the default values from
1701 template in the core source.
1703 MESSAGES_TO_AUTHOR has been added to the IssueClass in dbinit.py. Set to 'yes'
1704 to send nosy messages to the author. Default behaviour is to not send nosy
1705 messages to the author. You will need to add MESSAGES_TO_AUTHOR to your
1706 dbinit.py in your instance home.
1709 0.3.x CGI script roundup.cgi
1710 ----------------------------
1711 There have been some structural changes to the roundup.cgi script - you will
1712 need to install it again from the cgi-bin directory of the source
1713 distribution. Make sure you update the ROUNDUP_INSTANCE_HOMES after the
1714 copy.
1717 .. _`customisation documentation`: customizing.html
1718 .. _`security documentation`: security.html
1719 .. _`administration guide`: admin_guide.html