1 ======================================
2 Upgrading to newer versions of Roundup
3 ======================================
5 Please read each section carefully and edit your tracker home files
6 accordingly. Note that there is information about upgrade procedures in the
7 `administration guide`_.
9 If a specific version transition isn't mentioned here (eg. 0.6.7 to 0.6.8)
10 then you don't need to do anything. If you're upgrading from 0.5.6 to
11 0.6.8 though, you'll need to check the "0.5 to 0.6" and "0.6.x to 0.6.3"
12 steps.
14 .. contents::
16 Migrating from 1.4.x to 1.4.12
17 ==============================
19 Item creation now checks the "Create" permission instead of the "Edit"
20 permission for individual properties. If you have modified your tracker
21 permissions from the default distribution, you should check that
22 "Create" permissions exist for all properties you want users to be able
23 to create.
25 Migrating from 1.4.x to 1.4.11
26 ==============================
28 Close poential security hole
29 ----------------------------
31 If your tracker has untrusted users you should examine its ``schema.py``
32 file and look for the section granting the "Edit" permission to your users.
33 This should look something like::
35 p = db.security.addPermission(name='Edit', klass='user', check=own_record,
36 description="User is allowed to edit their own user details")
38 and should be modified to restrict the list of properties they are allowed
39 to edit by adding the ``properties=`` section like::
41 p = db.security.addPermission(name='Edit', klass='user', check=own_record,
42 properties=('username', 'password', 'address', 'realname', 'phone',
43 'organisation', 'alternate_addresses', 'queries', 'timezone'),
44 description="User is allowed to edit their own user details")
46 Most importantly the "roles" property should not be editable - thus not
47 appear in that list of properties.
50 Grant the "Register" permission to the Anonymous role
51 -----------------------------------------------------
53 A separate "Register" permission has been introduced to allow
54 anonymous users to register. This means you will need to add the
55 following to your tracker's ``schema.py`` to add the permission and
56 assign it to the Anonymous role (replacing any previously assigned
57 "Create user" permission for the Anonymous role):
59 +db.security.addPermission(name='Register', klass='user',
60 + description='User is allowed to register new user')
62 # Assign the appropriate permissions to the anonymous user's Anonymous
63 # Role. Choices here are:
64 # - Allow anonymous users to register
65 -db.security.addPermissionToRole('Anonymous', 'Create', 'user')
66 +db.security.addPermissionToRole('Anonymous', 'Register', 'user')
68 The lines marked "+" should be added and lines marked "-" should be
69 deleted (minus the "+"/"-" signs).
72 Migrating from 1.4.x to 1.4.9
73 =============================
75 Customized MailGW Class
76 -----------------------
78 If you have customized the MailGW class in your tracker: The new MailGW
79 class opens the database for each message in the method handle_message
80 (instance.open) instead of passing the opened database as a parameter to
81 the MailGW constructor. The old handle_message has been renamed to
82 _handle_message. The new method opens the database and wraps the call to
83 the old method into a try/finally.
85 Your customized MailGW class needs to mirror this behavior.
87 Fix the "remove" button in issue files and messages lists
88 ---------------------------------------------------------
90 The "remove" button(s) in the issue messages list needs to be altered. Find
91 the following in your tracker's ``html/issue.item.html`` template::
93 <td>
94 <form style="padding:0" tal:condition="context/is_edit_ok"
95 tal:attributes="action string:issue${context/id}">
96 <input type="hidden" name="@remove@files" tal:attributes="value file/id">
98 and add ``method="POST"`` as shown below::
100 <td>
101 <form style="padding:0" method="POST" tal:condition="context/is_edit_ok"
102 tal:attributes="action string:issue${context/id}">
103 <input type="hidden" name="@remove@files" tal:attributes="value file/id">
105 Then also find::
107 <td>
108 <form style="padding:0" tal:condition="context/is_edit_ok"
109 tal:attributes="action string:issue${context/id}">
110 <input type="hidden" name="@remove@messages" tal:attributes="value msg/id">
112 and add ``method="POST"`` as shown below::
114 <td>
115 <form style="padding:0" method="POST" tal:condition="context/is_edit_ok"
116 tal:attributes="action string:issue${context/id}">
117 <input type="hidden" name="@remove@messages" tal:attributes="value msg/id">
120 Fixing the "retire" button in user management list
121 --------------------------------------------------
123 If you made the change to the "reture" link in the user management list as
124 listed below in `Migrating from 1.4.x to 1.4.7`_ then you'll need to fix that
125 change by adding ``method="POST"`` to the ``<form>`` tag::
127 <form style="padding:0" method="POST"
128 tal:attributes="action string:user${user/id}">
129 <input type="hidden" name="@template" value="index">
130 <input type="hidden" name="@action" value="retire">
131 <input type="submit" value="retire" i18n:attributes="value">
132 </form>
135 Migrating from 1.4.x to 1.4.7
136 =============================
138 Several security issues were addressed in this release. Some aspects of your
139 trackers may no longer function depending on your local customisations. Core
140 functionality that will need to be modified:
142 Grant the "retire" permission to users for their queries
143 --------------------------------------------------------
145 Users will no longer be able to retire their own queries. To remedy this you
146 will need to add the following to your tracker's ``schema.py`` just under the
147 line that grants them permission to edit their own queries::
149 p = db.security.addPermission(name='Edit', klass='query', check=edit_query,
150 description="User is allowed to edit their queries")
151 db.security.addPermissionToRole('User', p)
152 + p = db.security.addPermission(name='Retire', klass='query', check=edit_query,
153 + description="User is allowed to retire their queries")
154 + db.security.addPermissionToRole('User', p)
155 p = db.security.addPermission(name='Create', klass='query',
156 description="User is allowed to create queries")
157 db.security.addPermissionToRole('User', p)
159 The lines marked "+" should be added, minus the "+" sign.
162 Fix the "retire" link in the users list for admin users
163 -------------------------------------------------------
165 The "retire" link found in the file ``html/users.index.html``::
167 <td tal:condition="context/is_edit_ok">
168 <a tal:attributes="href string:user${user/id}?@action=retire&@template=index"
169 i18n:translate="">retire</a>
171 Should be replaced with::
173 <td tal:condition="context/is_retire_ok">
174 <form style="padding:0" method="POST"
175 tal:attributes="action string:user${user/id}">
176 <input type="hidden" name="@template" value="index">
177 <input type="hidden" name="@action" value="retire">
178 <input type="submit" value="retire" i18n:attributes="value">
179 </form>
182 Fix for Python 2.6+ users
183 -------------------------
185 If you use Python 2.6 you should edit your tracker's
186 ``detectors/nosyreaction.py`` file to change::
188 import sets
190 at the top to::
192 from roundup.anypy.sets_ import set
194 and then all instances of ``sets.Set()`` to ``set()`` in the later code.
198 Trackers currently allowing HTML file uploading
199 -----------------------------------------------
201 Trackers which wish to continue to allow uploading of HTML content against issues
202 will need to set a new configuration variable in the ``[web]`` section of the
203 tracker's ``config.ini`` file:
205 # Setting this option enables Roundup to serve uploaded HTML
206 # file content *as HTML*. This is a potential security risk
207 # and is therefore disabled by default. Set to 'yes' if you
208 # trust *all* users uploading content to your tracker.
209 # Allowed values: yes, no
210 # Default: no
211 allow_html_file = no
215 Migrating from 1.4.2 to 1.4.3
216 =============================
218 If you are using the MySQL backend you will need to replace some indexes
219 that may have been created by version 1.4.2.
221 You should to access your MySQL database directly and remove any indexes
222 with a name ending in "_key_retired_idx". You should then re-add them with
223 the same spec except the key column name needs a size. So an index on
224 "_user (__retired, _name)" should become "_user (__retired, _name(255))".
227 Migrating from 1.4.x to 1.4.2
228 =============================
230 You should run the "roundup-admin migrate" command for your tracker once
231 you've installed the latest codebase.
233 Do this before you use the web, command-line or mail interface and before
234 any users access the tracker.
236 This command will respond with either "Tracker updated" (if you've not
237 previously run it on an RDBMS backend) or "No migration action required"
238 (if you have run it, or have used another interface to the tracker,
239 or are using anydbm).
241 It's safe to run this even if it's not required, so just get into the
242 habit.
245 Migrating from 1.3.3 to 1.4.0
246 =============================
248 Value of the "refwd_re" tracker configuration option (section "mailgw")
249 is treated as UTF-8 string. In previous versions, it was ISO8859-1.
251 If you have running trackers based on the classic template, please
252 update the messagesummary detector as follows::
254 --- detectors/messagesummary.py 17 Apr 2003 03:26:38 -0000 1.1
255 +++ detectors/messagesummary.py 3 Apr 2007 06:47:21 -0000 1.2
256 @@ -8,7 +8,7 @@
257 if newvalues.has_key('summary') or not newvalues.has_key('content'):
258 return
260 - summary, content = parseContent(newvalues['content'], 1, 1)
261 + summary, content = parseContent(newvalues['content'], config=db.config)
262 newvalues['summary'] = summary
264 In the latest version we have added some database indexes to the
265 SQL-backends (mysql, postgresql, sqlite) for speeding up building the
266 roundup-index for full-text search. We recommend that you create the
267 following database indexes on the database by hand::
269 CREATE INDEX words_by_id ON __words (_textid)
270 CREATE UNIQUE INDEX __textids_by_props ON __textids (_class, _itemid, _prop)
272 Migrating from 1.2.x to 1.3.0
273 =============================
275 1.3.0 Web interface changes
276 ---------------------------
278 Some of the HTML files in the "classic" and "minimal" tracker templates
279 were changed to fix some bugs and clean them up. You may wish to compare
280 them to the HTML files in your tracker and apply any changes.
283 Migrating from 1.1.2 to 1.2.0
284 =============================
286 1.2.0 Sorting and grouping by multiple properties
287 -------------------------------------------------
289 Starting with this version, sorting and grouping by multiple properties
290 is possible. This means that request.sort and request.group are now
291 lists. This is reflected in several places:
293 * ``renderWith`` now has list attributes for ``sort`` and ``group``,
294 where you previously wrote::
296 renderWith(... sort=('-', 'activity'), group=('+', 'priority')
298 you write now::
300 renderWith(... sort=[('-', 'activity')], group=[('+', 'priority')]
302 * In templates that permit to edit sorting/grouping, request.sort and
303 request.group are (possibly empty) lists. You can now sort and group
304 by multiple attributes. For an example, see the classic template. You
305 may want search for the variable ``n_sort`` which can be set to the
306 number of sort/group properties.
308 * Templates that diplay new headlines for each group of items with
309 equal group properties can now use the modified ``batch.propchanged``
310 method that can take several properties which are checked for
311 changes. See the example in the classic template which makes use of
312 ``batch.propchanged``.
314 Migrating from 1.1.0 to 1.1.1
315 =============================
317 1.1.1 "Clear this message"
318 --------------------------
320 In 1.1.1, the standard ``page.html`` template includes a "clear this message"
321 link in the green "ok" message bar that appears after a successful edit
322 (or other) action.
324 To include this in your tracker, change the following in your ``page.html``
325 template::
327 <p tal:condition="options/ok_message | nothing" class="ok-message"
328 tal:repeat="m options/ok_message" tal:content="structure m">error</p>
330 to be::
332 <p tal:condition="options/ok_message | nothing" class="ok-message">
333 <span tal:repeat="m options/ok_message"
334 tal:content="structure string:$m <br/ > " />
335 <a class="form-small" tal:attributes="href request/current_url"
336 i18n:translate="">clear this message</a>
337 </p>
340 If you implemented the "clear this message" in your 1.1.0 tracker, then you
341 should change it to the above and it will work much better!
344 Migrating from 1.0.x to 1.1.0
345 =============================
347 1.1 Login "For Session Only"
348 ----------------------------
350 In 1.1, web logins are alive for the length of a session only, *unless* you
351 add the following to the login form in your tracker's ``page.html``::
353 <input type="checkbox" name="remember" id="remember">
354 <label for="remember" i18n:translate="">Remember me?</label><br>
356 See the classic tracker ``page.html`` if you're unsure where this should
357 go.
360 1.1 Query Display Name
361 ----------------------
363 The ``dispname`` web variable has been renamed ``@dispname`` to avoid
364 clashing with other variables of the same name. If you are using the
365 display name feature, you will need to edit your tracker's ``page.html``
366 and ``issue.index.html`` pages to change ``dispname`` to ``@dispname``.
368 A side-effect of this change is that the renderWith method used in the
369 ``home.html`` page may now take a dispname argument.
372 1.1 "Clear this message"
373 ------------------------
375 In 1.1, the standard ``page.html`` template includes a "clear this message"
376 link in the green "ok" message bar that appears after a successful edit
377 (or other) action.
379 To include this in your tracker, change the following in your ``page.html``
380 template::
382 <p tal:condition="options/ok_message | nothing" class="ok-message"
383 tal:repeat="m options/ok_message" tal:content="structure m">error</p>
385 to be::
387 <p tal:condition="options/ok_message | nothing" class="ok-message">
388 <span tal:repeat="m options/ok_message"
389 tal:content="structure string:$m <br/ > " />
390 <a class="form-small" tal:attributes="href string:issue${context/id}"
391 i18n:translate="">clear this message</a>
392 </p>
395 Migrating from 0.8.x to 1.0
396 ===========================
398 1.0 New Query Permissions
399 -------------------------
401 New permissions are defined for query editing and viewing. To include these
402 in your tracker, you need to add these lines to your tracker's
403 ``schema.py``::
405 # Users should be able to edit and view their own queries. They should also
406 # be able to view any marked as not private. They should not be able to
407 # edit others' queries, even if they're not private
408 def view_query(db, userid, itemid):
409 private_for = db.query.get(itemid, 'private_for')
410 if not private_for: return True
411 return userid == private_for
412 def edit_query(db, userid, itemid):
413 return userid == db.query.get(itemid, 'creator')
414 p = db.security.addPermission(name='View', klass='query', check=view_query,
415 description="User is allowed to view their own and public queries")
416 db.security.addPermissionToRole('User', p)
417 p = db.security.addPermission(name='Edit', klass='query', check=edit_query,
418 description="User is allowed to edit their queries")
419 db.security.addPermissionToRole('User', p)
420 p = db.security.addPermission(name='Create', klass='query',
421 description="User is allowed to create queries")
422 db.security.addPermissionToRole('User', p)
424 and then remove 'query' from the line::
426 # Assign the access and edit Permissions for issue, file and message
427 # to regular users now
428 for cl in 'issue', 'file', 'msg', 'query', 'keyword':
430 so it looks like::
432 for cl in 'issue', 'file', 'msg', 'keyword':
435 Migrating from 0.8.0 to 0.8.3
436 =============================
438 0.8.3 Nosy Handling Changes
439 ---------------------------
441 A change was made to fix a bug in the ``nosyreaction.py`` standard
442 detector. To incorporate this fix in your trackers, you will need to copy
443 the ``nosyreaction.py`` file from the ``templates/classic/detectors``
444 directory of the source to your tracker's ``templates`` directory.
446 If you have modified the ``nosyreaction.py`` file from the standard
447 version, you will need to roll your changes into the new file.
450 Migrating from 0.7.1 to 0.8.0
451 =============================
453 You *must* fully uninstall previous Roundup version before installing
454 Roundup 0.8.0. If you don't do that, ``roundup-admin install``
455 command may fail to function properly.
457 0.8.0 Backend changes
458 ---------------------
460 Backends 'bsddb' and 'bsddb3' are removed. If you are using one of these,
461 you *must* migrate to another backend before upgrading.
464 0.8.0 API changes
465 -----------------
467 Class.safeget() was removed from the API. Test your item ids before calling
468 Class.get() instead.
471 0.8.0 New tracker layout
472 ------------------------
474 The ``config.py`` file has been replaced by ``config.ini``. You may use the
475 roundup-admin command "genconfig" to generate a new config file::
477 roundup-admin genconfig <tracker home>/config.ini
479 and modify the values therein based on the contents of your old config.py.
480 In most cases, the names of the config variables are the same.
482 The ``select_db.py`` file has been replaced by a file in the ``db``
483 directory called ``backend_name``. As you might guess, this file contains
484 just the name of the backend. To figure what the contents of yours should
485 be, use the following table:
487 ================================ =========================
488 ``select_db.py`` contents ``backend_name`` contents
489 ================================ =========================
490 from back_anydbm import ... anydbm
491 from back_metakit import ... metakit
492 from back_sqlite import ... sqlite
493 from back_mysql import ... mysql
494 from back_postgresql import ... postgresql
495 ================================ =========================
497 The ``dbinit.py`` file has been split into two new files,
498 ``initial_data.py`` and ``schema.py``. The contents of this file are:
500 ``initial_data.py``
501 You don't need one of these as your tracker is already initialised.
503 ``schema.py``
504 Copy the body of the ``def open(name=None)`` function from your old
505 tracker's ``dbinit.py`` file to this file. As the lines you're copying
506 aren't part of a function definition anymore, one level of indentation
507 needs to be removed (remove only the leading four spaces on each
508 line).
510 The first few lines -- those starting with ``from roundup.hyperdb
511 import ...`` and the ``db = Database(config, name)`` line -- don't
512 need to be copied. Neither do the last few lines -- those starting
513 with ``import detectors``, down to ``return db`` inclusive.
515 You may remove the ``__init__.py`` module from the "detectors" directory as
516 it is no longer used.
518 There's a new way to write extension code for Roundup. If you have code in
519 an ``interfaces.py`` file you should move it. See the `customisation
520 documentation`_ for information about how extensions are now written.
521 Note that some older trackers may use ``interfaces.py`` to customise the
522 mail gateway behaviour. You will need to keep your ``interfaces.py`` file
523 if this is the case.
526 0.8.0 Permissions Changes
527 -------------------------
529 The creation of a new item in the user interfaces is now controlled by the
530 "Create" Permission. You will need to add an assignment of this Permission
531 to your users who are allowed to create items. The most common form of this
532 is the following in your ``schema.py`` added just under the current
533 assignation of the Edit Permission::
535 for cl in 'issue', 'file', 'msg', 'query', 'keyword':
536 p = db.security.getPermission('Create', cl)
537 db.security.addPermissionToRole('User', p)
539 You will need to explicitly let anonymous users access the web interface so
540 that regular users are able to see the login form. Note that almost all
541 trackers will need this Permission. The only situation where it's not
542 required is in a tracker that uses an HTTP Basic Authenticated front-end.
543 It's enabled by adding to your ``schema.py``::
545 p = db.security.getPermission('Web Access')
546 db.security.addPermissionToRole('Anonymous', p)
548 Finally, you will need to enable permission for your users to edit their
549 own details by adding the following to ``schema.py``::
551 # Users should be able to edit their own details. Note that this
552 # permission is limited to only the situation where the Viewed or
553 # Edited item is their own.
554 def own_record(db, userid, itemid):
555 '''Determine whether the userid matches the item being accessed.'''
556 return userid == itemid
557 p = db.security.addPermission(name='View', klass='user', check=own_record,
558 description="User is allowed to view their own user details")
559 p = db.security.addPermission(name='Edit', klass='user', check=own_record,
560 description="User is allowed to edit their own user details")
561 db.security.addPermissionToRole('User', p)
564 0.8.0 Use of TemplatingUtils
565 ----------------------------
567 If you used custom python functions in TemplatingUtils, they must
568 be moved from interfaces.py to a new file in the ``extensions`` directory.
570 Each Function that should be available through TAL needs to be defined
571 as a toplevel function in the newly created file. Furthermore you
572 add an inititialization function, that registers the functions with the
573 tracker.
575 If you find this too tedious, donfu wrote an automatic init function that
576 takes an existing TemplatingUtils class, and registers all class methods
577 that do not start with an underscore. The following hack should be placed
578 in the ``extensions`` directory alongside other extensions::
580 class TemplatingUtils:
581 # copy from interfaces.py
583 def init(tracker):
584 util = TemplatingUtils()
586 def setClient(tu):
587 util.client = tu.client
588 return util
590 def execUtil(name):
591 return lambda tu, *args, **kwargs: \
592 getattr(setClient(tu), name)(*args, **kwargs)
594 for name in dir(util):
595 if callable(getattr(util, name)) and not name.startswith('_'):
596 tracker.registerUtil(name, execUtil(name))
599 0.8.0 Logging Configuration
600 ---------------------------
602 See the `administration guide`_ for information about configuring the new
603 logging implemented in 0.8.0.
606 Migrating from 0.7.2 to 0.7.3
607 =============================
609 0.7.3 Configuration
610 -------------------
612 If you choose, you may specify the directory from which static files are
613 served (those which use the URL component ``@@file``). Currently the
614 directory defaults to the ``TEMPLATES`` configuration variable. You may
615 define a new variable, ``STATIC_FILES`` which overrides this value for
616 static files.
619 Migrating from 0.7.0 to 0.7.2
620 =============================
622 0.7.2 DEFAULT_TIMEZONE is now required
623 --------------------------------------
625 The DEFAULT_TIMEZONE configuration variable is now required. Add the
626 following to your tracker's ``config.py`` file::
628 # You may specify a different default timezone, for use when users do not
629 # choose their own in their settings.
630 DEFAULT_TIMEZONE = 0 # specify as numeric hour offest
633 Migrating from 0.7.0 to 0.7.1
634 =============================
636 0.7.1 Permission assignments
637 ----------------------------
639 If you allow anonymous access to your tracker, you might need to assign
640 some additional View (or Edit if your tracker is that open) permissions
641 to the "anonymous" user. To do so, find the code in your ``dbinit.py`` that
642 says::
644 for cl in 'issue', 'file', 'msg', 'query', 'keyword':
645 p = db.security.getPermission('View', cl)
646 db.security.addPermissionToRole('User', p)
647 p = db.security.getPermission('Edit', cl)
648 db.security.addPermissionToRole('User', p)
649 for cl in 'priority', 'status':
650 p = db.security.getPermission('View', cl)
651 db.security.addPermissionToRole('User', p)
653 Add add a line::
655 db.security.addPermissionToRole('Anonymous', p)
657 next to the existing ``'User'`` lines for the Permissions you wish to
658 assign to the anonymous user.
661 Migrating from 0.6 to 0.7
662 =========================
664 0.7.0 Permission assignments
665 ----------------------------
667 Due to a change in the rendering of web widgets, permissions are now
668 checked on Classes where they previously weren't (this is a good thing).
670 You will need to add some additional Permission assignments for your
671 regular users, or some displays will break. After the following in your
672 tracker's ``dbinit.py``::
674 # Assign the access and edit Permissions for issue, file and message
675 # to regular users now
676 for cl in 'issue', 'file', 'msg', 'query', 'keyword':
677 p = db.security.getPermission('View', cl)
678 db.security.addPermissionToRole('User', p)
679 p = db.security.getPermission('Edit', cl)
680 db.security.addPermissionToRole('User', p)
682 add::
684 for cl in 'priority', 'status':
685 p = db.security.getPermission('View', cl)
686 db.security.addPermissionToRole('User', p)
689 0.7.0 Getting the current user id
690 ---------------------------------
692 The Database.curuserid attribute has been removed.
694 Any code referencing this attribute should be replaced with a
695 call to Database.getuid().
698 0.7.0 ZRoundup changes
699 ----------------------
701 The templates in your tracker's html directory will need updating if you
702 wish to use ZRoundup. If you've not modified those files (or some of them),
703 you may just copy the new versions from the Roundup source in the
704 templates/classic/html directory.
706 If you have modified the html files, then you'll need to manually edit them
707 to change all occurances of special form variables from using the colon ":"
708 special character to the at "@" special character. That is, variables such
709 as::
711 :action :required :template :remove:messages ...
713 should become::
715 @action @required @template @remove@messages ...
717 Note that ``tal:`` statements are unaffected. So are TAL expression type
718 prefixes such as ``python:`` and ``string:``. Please ask on the
719 roundup-users mailing list for help if you're unsure.
722 0.7.0 Edit collision detection
723 ------------------------------
725 Roundup now detects collisions with editing in the web interface (that is,
726 two people editing the same item at the same time).
728 You must copy the ``_generic.collision.html`` file from Roundup source in
729 the ``templates/classic/html`` directory. to your tracker's ``html``
730 directory.
733 Migrating from 0.6.x to 0.6.3
734 =============================
736 0.6.3 Configuration
737 -------------------
739 You will need to copy the file::
741 templates/classic/detectors/__init__.py
743 to your tracker's ``detectors`` directory, replacing the one already there.
744 This fixes a couple of bugs in that file.
748 Migrating from 0.5 to 0.6
749 =========================
752 0.6.0 Configuration
753 -------------------
755 Introduced EMAIL_FROM_TAG config variable. This value is inserted into
756 the From: line of nosy email. If the sending user is "Foo Bar", the
757 From: line is usually::
759 "Foo Bar" <issue_tracker@tracker.example>
761 the EMAIL_FROM_TAG goes inside the "Foo Bar" quotes like so::
763 "Foo Bar EMAIL_FROM_TAG" <issue_tracker@tracker.example>
765 I've altered the mechanism in the detectors __init__.py module so that it
766 doesn't cross-import detectors from other trackers (if you run more than one
767 in a single roundup-server). This change means that you'll need to copy the
768 __init__.py from roundup/templates/classic/detectors/__init__.py to your
769 <tracker home>/detectors/__init__.py. Don't worry, the "classic" __init__ is a
770 one-size-fits-all, so it'll work even if you've added/removed detectors.
772 0.6.0 Templating changes
773 ------------------------
775 The ``user.item`` template (in the tracker home "templates" directory)
776 needs to have the following hidden variable added to its form (between the
777 ``<form...>`` and ``</form>`` tags::
779 <input type="hidden" name=":template" value="item">
782 0.6.0 Form handling changes
783 ---------------------------
785 Roundup's form handling capabilities have been significantly expanded. This
786 should not affect users of 0.5 installations - but if you find you're
787 getting errors from form submissions, please ask for help on the Roundup
788 users mailing list:
790 http://lists.sourceforge.net/lists/listinfo/roundup-users
792 See the customisation doc section on `Form Values`__ for documentation of the
793 new form variables possible.
795 __ customizing.html#form-values
798 0.6.0 Multilingual character set support
799 ----------------------------------------
801 Added internationalization support. This is done via encoding all data
802 stored in roundup database to utf-8 (unicode encoding). To support utf-8 in
803 web interface you should add the folowing line to your tracker's html/page
804 and html/_generic.help files inside <head> tag::
806 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
808 Since latin characters in utf-8 have the same codes as in ASCII table, this
809 modification is optional for users who use only plain latin characters.
811 After this modification, you will be able to see and enter any world
812 character via web interface. Data received via mail interface also converted
813 to utf-8, however only new messages will be converted. If your roundup
814 database contains some of non-ASCII characters in one of 8-bit encoding,
815 they will not be visible in new unicode environment. Some of such data (e.g.
816 user names, keywords, etc) can be edited by administrator, the others
817 (e.g. messages' contents) is not editable via web interface. Currently there
818 is no tool for converting such data, the only solution is to close
819 appropriate old issues and create new ones with the same content.
822 0.6.0 User timezone support
823 ---------------------------
825 From version 0.6.0 roundup supports displaying of Date data in user' local
826 timezone if he/she has provided timezone information. To make it possible
827 some modification to tracker's schema and HTML templates are required.
828 First you must add string property 'timezone' to user class in dbinit.py
829 like this::
831 user = Class(db, "user",
832 username=String(), password=Password(),
833 address=String(), realname=String(),
834 phone=String(), organisation=String(),
835 alternate_addresses=String(),
836 queries=Multilink('query'), roles=String(),
837 timezone=String())
839 And second - html interface. Add following lines to
840 $TRACKER_HOME/html/user.item template::
842 <tr>
843 <th>Timezone</th>
844 <td tal:content="structure context/timezone/field">timezone</td>
845 </tr>
847 After that all users should be able to provide their timezone information.
848 Timezone should be a positive or negative integer - offset from GMT.
850 After providing timezone, roundup will show all dates values, found in web
851 and mail interfaces in local time. It will also accept any Date info in
852 local time, convert and store it in GMT.
855 0.6.0 Search page structure
856 ---------------------------
858 In order to accomodate query editing the search page has been restructured. If
859 you want to provide your users with query editing, you should update your
860 search page using the macros detailed in the customisation doc section
861 `Searching on categories`__.
863 __ customizing.html#searching-on-categories
865 Also, the url field in the query class no longer starts with a '?'. You'll need
866 to remove this question mark from the url field to support queries. There's
867 a script in the "tools" directory called ``migrate-queries.py`` that should
868 automatically change any existing queries for you. As always, make a backup
869 of your database before running such a script.
872 0.6.0 Notes for metakit backend users
873 -------------------------------------
875 Roundup 0.6.0 introduced searching on ranges of dates and intervals. To
876 support it, some modifications to interval storing routine were made. So if
877 your tracker uses metakit backend and your db schema contains intervals
878 property, searches on that property will not be accurate for db items that
879 was stored before roundup' upgrade. However all new records should be
880 searchable on intervals.
882 It is possible to convert your database to new format: you can export and
883 import back all your data (consult "Migrating backends" in "Maintenance"
884 documentation). After this operation all your interval properties should
885 become searchable.
887 Users of backends others than metakit should not worry about this issue.
890 Migrating from 0.4.x to 0.5.0
891 =============================
893 This has been a fairly major revision of Roundup:
895 1. Brand new, much more powerful, flexible, tasty and nutritious templating.
896 Unfortunately, this means all your current templates are useless. Hopefully
897 the new documentation and examples will be enough to help you make the
898 transition. Please don't hesitate to ask on roundup-users for help (or
899 complete conversions if you're completely stuck)!
900 2. The database backed got a lot more flexible, allowing Metakit and SQL
901 databases! The only decent SQL database implemented at present is sqlite,
902 but others shouldn't be a whole lot more work.
903 3. A brand new, highly flexible and much more robust security system including
904 a system of Permissions, Roles and Role assignments to users. You may now
905 define your own Permissions that may be checked in CGI transactions.
906 4. Journalling has been made less storage-hungry, so has been turned on
907 by default *except* for author, recipient and nosy link/unlink events. You
908 are advised to turn it off in your trackers too.
909 5. We've changed the terminology from "instance" to "tracker", to ease the
910 learning curve/impact for new users.
911 6. Because of the above changes, the tracker configuration has seen some
912 major changes. See below for the details.
914 Please, **back up your database** before you start the migration process. This
915 is as simple as copying the "db" directory and all its contents from your
916 tracker to somewhere safe.
919 0.5.0 Configuration
920 -------------------
922 First up, rename your ``instance_config.py`` file to just ``config.py``.
924 Then edit your tracker's ``__init__.py`` module. It'll currently look
925 like this::
927 from instance_config import *
928 try:
929 from dbinit import *
930 except ImportError:
931 pass # in installdir (probably :)
932 from interfaces import *
934 and it needs to be::
936 import config
937 from dbinit import open, init
938 from interfaces import Client, MailGW
940 Due to the new templating having a top-level ``page`` that defines links for
941 searching, indexes, adding items etc, the following variables are no longer
942 used:
944 - HEADER_INDEX_LINKS
945 - HEADER_ADD_LINKS
946 - HEADER_SEARCH_LINKS
947 - SEARCH_FILTERS
948 - DEFAULT_INDEX
949 - UNASSIGNED_INDEX
950 - USER_INDEX
951 - ISSUE_FILTER
953 The new security implementation will require additions to the dbinit module,
954 but also removes the need for the following tracker config variables:
956 - ANONYMOUS_ACCESS
957 - ANONYMOUS_REGISTER
959 but requires two new variables which define the Roles assigned to users who
960 register through the web and e-mail interfaces:
962 - NEW_WEB_USER_ROLES
963 - NEW_EMAIL_USER_ROLES
965 in both cases, 'User' is a good initial setting. To emulate
966 ``ANONYMOUS_ACCESS='deny'``, remove all "View" Permissions from the
967 "Anonymous" Role. To emulate ``ANONYMOUS_REGISTER='deny'``, remove the "Web
968 Registration" and/or the "Email Registration" Permission from the "Anonymous"
969 Role. See the section on customising security in the `customisation
970 documentation`_ for more information.
972 Finally, the following config variables have been renamed to make more sense:
974 - INSTANCE_HOME -> TRACKER_HOME
975 - INSTANCE_NAME -> TRACKER_NAME
976 - ISSUE_TRACKER_WEB -> TRACKER_WEB
977 - ISSUE_TRACKER_EMAIL -> TRACKER_EMAIL
980 0.5.0 Schema Specification
981 --------------------------
983 0.5.0 Database backend changes
984 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
986 Your select_db module in your tracker has changed a fair bit. Where it used
987 to contain::
989 # WARNING: DO NOT EDIT THIS FILE!!!
990 from roundup.backends.back_anydbm import Database
992 it must now contain::
994 # WARNING: DO NOT EDIT THIS FILE!!!
995 from roundup.backends.back_anydbm import Database, Class, FileClass, IssueClass
997 Yes, I realise the irony of the "DO NOT EDIT THIS FILE" statement :)
998 Note the addition of the Class, FileClass, IssueClass imports. These are very
999 important, as they're going to make the next change work too. You now need to
1000 modify the top of the dbinit module in your tracker from::
1002 import instance_config
1003 from roundup import roundupdb
1004 from select_db import Database
1006 from roundup.roundupdb import Class, FileClass
1008 class Database(roundupdb.Database, select_db.Database):
1009 ''' Creates a hybrid database from:
1010 . the selected database back-end from select_db
1011 . the roundup extensions from roundupdb
1012 '''
1013 pass
1015 class IssueClass(roundupdb.IssueClass):
1016 ''' issues need the email information
1017 '''
1018 pass
1020 to::
1022 import config
1023 from select_db import Database, Class, FileClass, IssueClass
1025 Yes, remove the Database and IssueClass definitions and those other imports.
1026 They're not needed any more!
1028 Look for places in dbinit.py where ``instance_config`` is used too, and
1029 rename them ``config``.
1032 0.5.0 Journalling changes
1033 ~~~~~~~~~~~~~~~~~~~~~~~~~
1035 Journalling has been optimised for storage. Journalling of links has been
1036 turned back on by default. If your tracker has a large user base, you may wish
1037 to turn off journalling of nosy list, message author and message recipient
1038 link and unlink events. You do this by adding ``do_journal='no'`` to the Class
1039 initialisation in your dbinit. For example, your *msg* class initialisation
1040 probably looks like this::
1042 msg = FileClass(db, "msg",
1043 author=Link("user"), recipients=Multilink("user"),
1044 date=Date(), summary=String(),
1045 files=Multilink("file"),
1046 messageid=String(), inreplyto=String())
1048 to turn off journalling of author and recipient link events, add
1049 ``do_journal='no'`` to the ``author=Link("user")`` part of the statement,
1050 like so::
1052 msg = FileClass(db, "msg",
1053 author=Link("user", do_journal='no'),
1054 recipients=Multilink("user", do_journal='no'),
1055 date=Date(), summary=String(),
1056 files=Multilink("file"),
1057 messageid=String(), inreplyto=String())
1059 Nosy list link event journalling is actually turned off by default now. If you
1060 want to turn it on, change to your issue class' nosy list, change its
1061 definition from::
1063 issue = IssueClass(db, "issue",
1064 assignedto=Link("user"), topic=Multilink("keyword"),
1065 priority=Link("priority"), status=Link("status"))
1067 to::
1069 issue = IssueClass(db, "issue", nosy=Multilink("user", do_journal='yes'),
1070 assignedto=Link("user"), topic=Multilink("keyword"),
1071 priority=Link("priority"), status=Link("status"))
1073 noting that your definition of the nosy Multilink will override the normal one.
1076 0.5.0 User schema changes
1077 ~~~~~~~~~~~~~~~~~~~~~~~~~
1079 Users have two more properties, "queries" and "roles". You'll have something
1080 like this in your dbinit module now::
1082 user = Class(db, "user",
1083 username=String(), password=Password(),
1084 address=String(), realname=String(),
1085 phone=String(), organisation=String(),
1086 alternate_addresses=String())
1087 user.setkey("username")
1089 and you'll need to add the new properties and the new "query" class to it
1090 like so::
1092 query = Class(db, "query",
1093 klass=String(), name=String(),
1094 url=String())
1095 query.setkey("name")
1097 # Note: roles is a comma-separated string of Role names
1098 user = Class(db, "user",
1099 username=String(), password=Password(),
1100 address=String(), realname=String(),
1101 phone=String(), organisation=String(),
1102 alternate_addresses=String(),
1103 queries=Multilink('query'), roles=String())
1104 user.setkey("username")
1106 The "queries" property is used to store off the user's favourite database
1107 queries. The "roles" property is explained below in `0.5.0 Security
1108 Settings`_.
1111 0.5.0 Security Settings
1112 ~~~~~~~~~~~~~~~~~~~~~~~
1114 See the `security documentation`_ for an explanation of how the new security
1115 system works. In a nutshell though, the security is handled as a four step
1116 process:
1118 1. Permissions are defined as having a name and optionally a hyperdb class
1119 they're specific to,
1120 2. Roles are defined that have one or more Permissions,
1121 3. Users are assigned Roles in their "roles" property, and finally
1122 4. Roundup checks that users have appropriate Permissions at appropriate times
1123 (like editing issues).
1125 Your tracker dbinit module's *open* function now has to define any
1126 Permissions that are specific to your tracker, and also the assignment
1127 of Permissions to Roles. At the moment, your open function
1128 ends with::
1130 import detectors
1131 detectors.init(db)
1133 return db
1135 and what we need to do is insert some commands that will set up the security
1136 parameters. Right above the ``import detectors`` line, you'll want to insert
1137 these lines::
1139 #
1140 # SECURITY SETTINGS
1141 #
1142 # new permissions for this schema
1143 for cl in 'issue', 'file', 'msg', 'user':
1144 db.security.addPermission(name="Edit", klass=cl,
1145 description="User is allowed to edit "+cl)
1146 db.security.addPermission(name="View", klass=cl,
1147 description="User is allowed to access "+cl)
1149 # Assign the access and edit permissions for issue, file and message
1150 # to regular users now
1151 for cl in 'issue', 'file', 'msg':
1152 p = db.security.getPermission('View', cl)
1153 db.security.addPermissionToRole('User', p)
1154 p = db.security.getPermission('Edit', cl)
1155 db.security.addPermissionToRole('User', p)
1156 # and give the regular users access to the web and email interface
1157 p = db.security.getPermission('Web Access')
1158 db.security.addPermissionToRole('User', p)
1159 p = db.security.getPermission('Email Access')
1160 db.security.addPermissionToRole('User', p)
1162 # May users view other user information? Comment these lines out
1163 # if you don't want them to
1164 p = db.security.getPermission('View', 'user')
1165 db.security.addPermissionToRole('User', p)
1167 # Assign the appropriate permissions to the anonymous user's Anonymous
1168 # Role. Choices here are:
1169 # - Allow anonymous users to register through the web
1170 p = db.security.getPermission('Web Registration')
1171 db.security.addPermissionToRole('Anonymous', p)
1172 # - Allow anonymous (new) users to register through the email gateway
1173 p = db.security.getPermission('Email Registration')
1174 db.security.addPermissionToRole('Anonymous', p)
1175 # - Allow anonymous users access to the "issue" class of data
1176 # Note: this also grants access to related information like files,
1177 # messages, statuses etc that are linked to issues
1178 #p = db.security.getPermission('View', 'issue')
1179 #db.security.addPermissionToRole('Anonymous', p)
1180 # - Allow anonymous users access to edit the "issue" class of data
1181 # Note: this also grants access to create related information like
1182 # files and messages etc that are linked to issues
1183 #p = db.security.getPermission('Edit', 'issue')
1184 #db.security.addPermissionToRole('Anonymous', p)
1186 # oh, g'wan, let anonymous access the web interface too
1187 p = db.security.getPermission('Web Access')
1188 db.security.addPermissionToRole('Anonymous', p)
1190 Note in the comments there the places where you might change the permissions
1191 to restrict users or grant users more access. If you've created additional
1192 classes that users should be able to edit and view, then you should add them
1193 to the "new permissions for this schema" section at the start of the security
1194 block. Then add them to the "Assign the access and edit permissions" section
1195 too, so people actually have the new Permission you've created.
1197 One final change is needed that finishes off the security system's
1198 initialisation. We need to add a call to ``db.post_init()`` at the end of the
1199 dbinit open() function. Add it like this::
1201 import detectors
1202 detectors.init(db)
1204 # schema is set up - run any post-initialisation
1205 db.post_init()
1206 return db
1208 You may verify the setup of Permissions and Roles using the new
1209 "``roundup-admin security``" command.
1212 0.5.0 User changes
1213 ~~~~~~~~~~~~~~~~~~
1215 To support all those schema changes, you'll need to massage your user database
1216 a little too, to:
1218 1. make sure there's an "anonymous" user - this user is mandatory now and is
1219 the one that unknown users are logged in as.
1220 2. make sure all users have at least one Role.
1222 If you don't have the "anonymous" user, create it now with the command::
1224 roundup-admin create user username=anonymous roles=Anonymous
1226 making sure the capitalisation is the same as above. Once you've done that,
1227 you'll need to set the roles property on all users to a reasonable default.
1228 The admin user should get "Admin", the anonymous user "Anonymous"
1229 and all other users "User". The ``fixroles.py`` script in the tools directory
1230 will do this. Run it like so (where python is your python 2+ binary)::
1232 python tools/fixroles.py -i <tracker home> fixroles
1236 0.5.0 CGI interface changes
1237 ---------------------------
1239 The CGI interface code was completely reorganised and largely rewritten. The
1240 end result is that this section of your tracker interfaces module will need
1241 changing from::
1243 from roundup import cgi_client, mailgw
1244 from roundup.i18n import _
1246 class Client(cgi_client.Client):
1247 ''' derives basic CGI implementation from the standard module,
1248 with any specific extensions
1249 '''
1250 pass
1252 to::
1254 from roundup import mailgw
1255 from roundup.cgi import client
1257 class Client(client.Client):
1258 ''' derives basic CGI implementation from the standard module,
1259 with any specific extensions
1260 '''
1261 pass
1263 You will also need to install the new version of roundup.cgi from the source
1264 cgi-bin directory if you're using it.
1267 0.5.0 HTML templating
1268 ---------------------
1270 You'll want to make a backup of your current tracker html directory. You
1271 should then copy the html directory from the Roundup source "classic" template
1272 and modify it according to your local schema changes.
1274 If you need help with the new templating system, please ask questions on the
1275 roundup-users mailing list (available through the roundup project page on
1276 sourceforge, http://roundup.sf.net/)
1279 0.5.0 Detectors
1280 ---------------
1282 The nosy reactor has been updated to handle the tracker not having an
1283 "assignedto" property on issues. You may want to copy it into your tracker's
1284 detectors directory. Chances are you've already fixed it though :)
1287 Migrating from 0.4.1 to 0.4.2
1288 =============================
1290 0.4.2 Configuration
1291 -------------------
1292 The USER_INDEX definition introduced in 0.4.1 was too restrictive in its
1293 allowing replacement of 'assignedto' with the user's userid. Users must change
1294 the None value of 'assignedto' to 'CURRENT USER' (the string, in quotes) for
1295 the replacement behaviour to occur now.
1297 The new configuration variables are:
1299 - EMAIL_KEEP_QUOTED_TEXT
1300 - EMAIL_LEAVE_BODY_UNCHANGED
1301 - ADD_RECIPIENTS_TO_NOSY
1303 See the sample configuration files in::
1305 <roundup source>/roundup/templates/classic/instance_config.py
1307 and::
1309 <roundup source>/roundup/templates/extended/instance_config.py
1311 and the `customisation documentation`_ for information on how they're used.
1314 0.4.2 Changes to detectors
1315 --------------------------
1316 You will need to copy the detectors from the distribution into your instance
1317 home "detectors" directory. If you used the classic schema, the detectors
1318 are in::
1320 <roundup source>/roundup/templates/classic/detectors/
1322 If you used the extended schema, the detectors are in::
1324 <roundup source>/roundup/templates/extended/detectors/
1326 The change means that schema-specific code has been removed from the
1327 mail gateway and cgi interface and made into auditors:
1329 - nosyreactor.py has now got an updatenosy auditor which updates the nosy
1330 list with author, recipient and assignedto information.
1331 - statusauditor.py makes the unread or resolved -> chatting changes and
1332 presets the status of an issue to unread.
1334 There's also a bug or two fixed in the nosyreactor code.
1336 0.4.2 HTML templating changes
1337 -----------------------------
1338 The link() htmltemplate function now has a "showid" option for links and
1339 multilinks. When true, it only displays the linked item id as the anchor
1340 text. The link value is displayed as a tooltip using the title anchor
1341 attribute. To use in eg. the superseder field, have something like this::
1343 <td>
1344 <display call="field('superseder', showid=1)">
1345 <display call="classhelp('issue', 'id,title', label='list', width=500)">
1346 <property name="superseder">
1347 <br>View: <display call="link('superseder', showid=1)">
1348 </property>
1349 </td>
1351 The stylesheets have been cleaned up too. You may want to use the newer
1352 versions in::
1354 <roundup source>/roundup/templates/<template>/html/default.css
1358 Migrating from 0.4.0 to 0.4.1
1359 =============================
1361 0.4.1 Files storage
1362 -------------------
1364 Messages and files from newly created issues will be put into subdierectories
1365 in thousands e.g. msg123 will be put into files/msg/0/msg123, file2003
1366 will go into files/file/2/file2003. Previous messages are still found, but
1367 could be put into this structure.
1369 0.4.1 Configuration
1370 -------------------
1372 To allow more fine-grained access control, the variable used to check
1373 permission to auto-register users in the mail gateway is now called
1374 ANONYMOUS_REGISTER_MAIL rather than overloading ANONYMOUS_REGISTER. If the
1375 variable doesn't exist, then ANONYMOUS_REGISTER is tested as before.
1377 Configuring the links in the web header is now easier too. The following
1378 variables have been added to the classic instance_config.py::
1380 HEADER_INDEX_LINKS - defines the "index" links to be made available
1381 HEADER_ADD_LINKS - defines the "add" links
1382 DEFAULT_INDEX - specifies the index view for DEFAULT
1383 UNASSIGNED_INDEX - specifies the index view for UNASSIGNED
1384 USER_INDEX - specifies the index view for USER
1386 See the <roundup source>/roundup/templates/classic/instance_config.py for more
1387 information - including how the variables are to be set up. Most users will
1388 just be able to copy the variables from the source to their instance home. If
1389 you've modified the header by changing the source of the interfaces.py file in
1390 the instance home, you'll need to remove that customisation and move it into
1391 the appropriate variables in instance_config.py.
1393 The extended schema has similar variables added too - see the source for more
1394 info.
1396 0.4.1 Alternate E-Mail Addresses
1397 --------------------------------
1399 If you add the property "alternate_addresses" to your user class, your users
1400 will be able to register alternate email addresses that they may use to
1401 communicate with roundup as. All email from roundup will continue to be sent
1402 to their primary address.
1404 If you have not edited the dbinit.py file in your instance home directory,
1405 you may simply copy the new dbinit.py file from the core code. If you used
1406 the classic schema, the interfaces file is in::
1408 <roundup source>/roundup/templates/classic/dbinit.py
1410 If you used the extended schema, the file is in::
1412 <roundup source>/roundup/templates/extended/dbinit.py
1414 If you have modified your dbinit.py file, you need to edit the dbinit.py
1415 file in your instance home directory. Find the lines which define the user
1416 class::
1418 user = Class(db, "msg",
1419 username=String(), password=Password(),
1420 address=String(), realname=String(),
1421 phone=String(), organisation=String(),
1422 alternate_addresses=String())
1424 You will also want to add the property to the user's details page. The
1425 template for this is the "user.item" file in your instance home "html"
1426 directory. Similar to above, you may copy the file from the roundup source if
1427 you haven't modified it. Otherwise, add the following to the template::
1429 <display call="multiline('alternate_addresses')">
1431 with appropriate labelling etc. See the standard template for an idea.
1435 Migrating from 0.3.x to 0.4.0
1436 =============================
1438 0.4.0 Message-ID and In-Reply-To addition
1439 -----------------------------------------
1440 0.4.0 adds the tracking of messages by message-id and allows threading
1441 using in-reply-to. Most e-mail clients support threading using this
1442 feature, and we hope to add support for it to the web gateway. If you
1443 have not edited the dbinit.py file in your instance home directory, you may
1444 simply copy the new dbinit.py file from the core code. If you used the
1445 classic schema, the interfaces file is in::
1447 <roundup source>/roundup/templates/classic/dbinit.py
1449 If you used the extended schema, the file is in::
1451 <roundup source>/roundup/templates/extended/dbinit.py
1453 If you have modified your dbinit.py file, you need to edit the dbinit.py
1454 file in your instance home directory. Find the lines which define the msg
1455 class::
1457 msg = FileClass(db, "msg",
1458 author=Link("user"), recipients=Multilink("user"),
1459 date=Date(), summary=String(),
1460 files=Multilink("file"))
1462 and add the messageid and inreplyto properties like so::
1464 msg = FileClass(db, "msg",
1465 author=Link("user"), recipients=Multilink("user"),
1466 date=Date(), summary=String(),
1467 files=Multilink("file"),
1468 messageid=String(), inreplyto=String())
1470 Also, configuration is being cleaned up. This means that your dbinit.py will
1471 also need to be changed in the open function. If you haven't changed your
1472 dbinit.py, the above copy will be enough. If you have, you'll need to change
1473 the line (round line 50)::
1475 db = Database(instance_config.DATABASE, name)
1477 to::
1479 db = Database(instance_config, name)
1482 0.4.0 Configuration
1483 --------------------
1484 ``TRACKER_NAME`` and ``EMAIL_SIGNATURE_POSITION`` have been added to the
1485 instance_config.py. The simplest solution is to copy the default values
1486 from template in the core source.
1488 The mail gateway now checks ``ANONYMOUS_REGISTER`` to see if unknown users
1489 are to be automatically registered with the tracker. If it is set to "deny"
1490 then unknown users will not have access. If it is set to "allow" they will be
1491 automatically registered with the tracker.
1494 0.4.0 CGI script roundup.cgi
1495 ----------------------------
1496 The CGI script has been updated with some features and a bugfix, so you should
1497 copy it from the roundup cgi-bin source directory again. Make sure you update
1498 the ROUNDUP_INSTANCE_HOMES after the copy.
1501 0.4.0 Nosy reactor
1502 ------------------
1503 The nosy reactor has also changed - copy the nosyreactor.py file from the core
1504 source::
1506 <roundup source>/roundup/templates/<template>/detectors/nosyreactor.py
1508 to your instance home "detectors" directory.
1511 0.4.0 HTML templating
1512 ---------------------
1513 The field() function was incorrectly implemented - links and multilinks now
1514 display as text fields when rendered using field(). To display a menu (drop-
1515 down or select box) you need to use the menu() function.
1519 Migrating from 0.2.x to 0.3.x
1520 =============================
1522 0.3.x Cookie Authentication changes
1523 -----------------------------------
1524 0.3.0 introduces cookie authentication - you will need to copy the
1525 interfaces.py file from the roundup source to your instance home to enable
1526 authentication. If you used the classic schema, the interfaces file is in::
1528 <roundup source>/roundup/templates/classic/interfaces.py
1530 If you used the extended schema, the file is in::
1532 <roundup source>/roundup/templates/extended/interfaces.py
1534 If you have modified your interfaces.Client class, you will need to take
1535 note of the login/logout functionality provided in roundup.cgi_client.Client
1536 (classic schema) or roundup.cgi_client.ExtendedClient (extended schema) and
1537 modify your instance code apropriately.
1540 0.3.x Password encoding
1541 -----------------------
1542 This release also introduces encoding of passwords in the database. If you
1543 have not edited the dbinit.py file in your instance home directory, you may
1544 simply copy the new dbinit.py file from the core code. If you used the
1545 classic schema, the interfaces file is in::
1547 <roundup source>/roundup/templates/classic/dbinit.py
1549 If you used the extended schema, the file is in::
1551 <roundup source>/roundup/templates/extended/dbinit.py
1554 If you have modified your dbinit.py file, you may use encoded passwords:
1556 1. Edit the dbinit.py file in your instance home directory
1557 a. At the first code line of the open() function::
1559 from roundup.hyperdb import String, Date, Link, Multilink
1561 alter to include Password, as so::
1563 from roundup.hyperdb import String, Password, Date, Link, Multilink
1565 b. Where the password property is defined (around line 66)::
1567 user = Class(db, "user",
1568 username=String(), password=String(),
1569 address=String(), realname=String(),
1570 phone=String(), organisation=String())
1571 user.setkey("username")
1573 alter the "password=String()" to "password=Password()"::
1575 user = Class(db, "user",
1576 username=String(), password=Password(),
1577 address=String(), realname=String(),
1578 phone=String(), organisation=String())
1579 user.setkey("username")
1581 2. Any existing passwords in the database will remain cleartext until they
1582 are edited. It is recommended that at a minimum the admin password be
1583 changed immediately::
1585 roundup-admin -i <instance home> set user1 password=<new password>
1588 0.3.x Configuration
1589 -------------------
1590 FILTER_POSITION, ANONYMOUS_ACCESS, ANONYMOUS_REGISTER have been added to
1591 the instance_config.py. Simplest solution is to copy the default values from
1592 template in the core source.
1594 MESSAGES_TO_AUTHOR has been added to the IssueClass in dbinit.py. Set to 'yes'
1595 to send nosy messages to the author. Default behaviour is to not send nosy
1596 messages to the author. You will need to add MESSAGES_TO_AUTHOR to your
1597 dbinit.py in your instance home.
1600 0.3.x CGI script roundup.cgi
1601 ----------------------------
1602 There have been some structural changes to the roundup.cgi script - you will
1603 need to install it again from the cgi-bin directory of the source
1604 distribution. Make sure you update the ROUNDUP_INSTANCE_HOMES after the
1605 copy.
1608 .. _`customisation documentation`: customizing.html
1609 .. _`security documentation`: security.html
1610 .. _`administration guide`: admin_guide.html