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.2 to 1.4.3
17 =============================
19 If you are using the MySQL backend you will need to replace some indexes
20 that may have been created by version 1.4.2.
22 You should to access your MySQL database directly and remove any indexes
23 with a name ending in "_key_retired_idx". You should then re-add them with
24 the same spec except the key column name needs a size. So an index on
25 "_user (__retired, _name)" should become "_user (__retired, _name(255))".
28 Migrating from 1.4.x to 1.4.2
29 =============================
31 You should run the "roundup-admin migrate" command for your tracker once
32 you've installed the latest codebase.
34 Do this before you use the web, command-line or mail interface and before
35 any users access the tracker.
37 This command will respond with either "Tracker updated" (if you've not
38 previously run it on an RDBMS backend) or "No migration action required"
39 (if you have run it, or have used another interface to the tracker,
40 or are using anydbm).
42 It's safe to run this even if it's not required, so just get into the
43 habit.
46 Migrating from 1.3.3 to 1.4.0
47 =============================
49 Value of the "refwd_re" tracker configuration option (section "mailgw")
50 is treated as UTF-8 string. In previous versions, it was ISO8859-1.
52 If you have running trackers based on the classic template, please
53 update the messagesummary detector as follows::
55 --- detectors/messagesummary.py 17 Apr 2003 03:26:38 -0000 1.1
56 +++ detectors/messagesummary.py 3 Apr 2007 06:47:21 -0000 1.2
57 @@ -8,7 +8,7 @@
58 if newvalues.has_key('summary') or not newvalues.has_key('content'):
59 return
61 - summary, content = parseContent(newvalues['content'], 1, 1)
62 + summary, content = parseContent(newvalues['content'], config=db.config)
63 newvalues['summary'] = summary
65 In the latest version we have added some database indexes to the
66 SQL-backends (mysql, postgresql, sqlite) for speeding up building the
67 roundup-index for full-text search. We recommend that you create the
68 following database indexes on the database by hand::
70 CREATE INDEX words_by_id ON __words (_textid)
71 CREATE UNIQUE INDEX __textids_by_props ON __textids (_class, _itemid, _prop)
73 Migrating from 1.2.x to 1.3.0
74 =============================
76 1.3.0 Web interface changes
77 ---------------------------
79 Some of the HTML files in the "classic" and "minimal" tracker templates
80 were changed to fix some bugs and clean them up. You may wish to compare
81 them to the HTML files in your tracker and apply any changes.
84 Migrating from 1.1.2 to 1.2.0
85 =============================
87 1.2.0 Sorting and grouping by multiple properties
88 -------------------------------------------------
90 Starting with this version, sorting and grouping by multiple properties
91 is possible. This means that request.sort and request.group are now
92 lists. This is reflected in several places:
94 * ``renderWith`` now has list attributes for ``sort`` and ``group``,
95 where you previously wrote::
97 renderWith(... sort=('-', 'activity'), group=('+', 'priority')
99 you write now::
101 renderWith(... sort=[('-', 'activity')], group=[('+', 'priority')]
103 * In templates that permit to edit sorting/grouping, request.sort and
104 request.group are (possibly empty) lists. You can now sort and group
105 by multiple attributes. For an example, see the classic template. You
106 may want search for the variable ``n_sort`` which can be set to the
107 number of sort/group properties.
109 * Templates that diplay new headlines for each group of items with
110 equal group properties can now use the modified ``batch.propchanged``
111 method that can take several properties which are checked for
112 changes. See the example in the classic template which makes use of
113 ``batch.propchanged``.
115 Migrating from 1.1.0 to 1.1.1
116 =============================
118 1.1.1 "Clear this message"
119 --------------------------
121 In 1.1.1, the standard ``page.html`` template includes a "clear this message"
122 link in the green "ok" message bar that appears after a successful edit
123 (or other) action.
125 To include this in your tracker, change the following in your ``page.html``
126 template::
128 <p tal:condition="options/ok_message | nothing" class="ok-message"
129 tal:repeat="m options/ok_message" tal:content="structure m">error</p>
131 to be::
133 <p tal:condition="options/ok_message | nothing" class="ok-message">
134 <span tal:repeat="m options/ok_message"
135 tal:content="structure string:$m <br/ > " />
136 <a class="form-small" tal:attributes="href request/current_url"
137 i18n:translate="">clear this message</a>
138 </p>
141 If you implemented the "clear this message" in your 1.1.0 tracker, then you
142 should change it to the above and it will work much better!
145 Migrating from 1.0.x to 1.1.0
146 =============================
148 1.1 Login "For Session Only"
149 ----------------------------
151 In 1.1, web logins are alive for the length of a session only, *unless* you
152 add the following to the login form in your tracker's ``page.html``::
154 <input type="checkbox" name="remember" id="remember">
155 <label for="remember" i18n:translate="">Remember me?</label><br>
157 See the classic tracker ``page.html`` if you're unsure where this should
158 go.
161 1.1 Query Display Name
162 ----------------------
164 The ``dispname`` web variable has been renamed ``@dispname`` to avoid
165 clashing with other variables of the same name. If you are using the
166 display name feature, you will need to edit your tracker's ``page.html``
167 and ``issue.index.html`` pages to change ``dispname`` to ``@dispname``.
169 A side-effect of this change is that the renderWith method used in the
170 ``home.html`` page may now take a dispname argument.
173 1.1 "Clear this message"
174 ------------------------
176 In 1.1, the standard ``page.html`` template includes a "clear this message"
177 link in the green "ok" message bar that appears after a successful edit
178 (or other) action.
180 To include this in your tracker, change the following in your ``page.html``
181 template::
183 <p tal:condition="options/ok_message | nothing" class="ok-message"
184 tal:repeat="m options/ok_message" tal:content="structure m">error</p>
186 to be::
188 <p tal:condition="options/ok_message | nothing" class="ok-message">
189 <span tal:repeat="m options/ok_message"
190 tal:content="structure string:$m <br/ > " />
191 <a class="form-small" tal:attributes="href string:issue${context/id}"
192 i18n:translate="">clear this message</a>
193 </p>
196 Migrating from 0.8.x to 1.0
197 ===========================
199 1.0 New Query Permissions
200 -------------------------
202 New permissions are defined for query editing and viewing. To include these
203 in your tracker, you need to add these lines to your tracker's
204 ``schema.py``::
206 # Users should be able to edit and view their own queries. They should also
207 # be able to view any marked as not private. They should not be able to
208 # edit others' queries, even if they're not private
209 def view_query(db, userid, itemid):
210 private_for = db.query.get(itemid, 'private_for')
211 if not private_for: return True
212 return userid == private_for
213 def edit_query(db, userid, itemid):
214 return userid == db.query.get(itemid, 'creator')
215 p = db.security.addPermission(name='View', klass='query', check=view_query,
216 description="User is allowed to view their own and public queries")
217 db.security.addPermissionToRole('User', p)
218 p = db.security.addPermission(name='Edit', klass='query', check=edit_query,
219 description="User is allowed to edit their queries")
220 db.security.addPermissionToRole('User', p)
221 p = db.security.addPermission(name='Create', klass='query',
222 description="User is allowed to create queries")
223 db.security.addPermissionToRole('User', p)
225 and then remove 'query' from the line::
227 # Assign the access and edit Permissions for issue, file and message
228 # to regular users now
229 for cl in 'issue', 'file', 'msg', 'query', 'keyword':
231 so it looks like::
233 for cl in 'issue', 'file', 'msg', 'keyword':
236 Migrating from 0.8.0 to 0.8.3
237 =============================
239 0.8.3 Nosy Handling Changes
240 ---------------------------
242 A change was made to fix a bug in the ``nosyreaction.py`` standard
243 detector. To incorporate this fix in your trackers, you will need to copy
244 the ``nosyreaction.py`` file from the ``templates/classic/detectors``
245 directory of the source to your tracker's ``templates`` directory.
247 If you have modified the ``nosyreaction.py`` file from the standard
248 version, you will need to roll your changes into the new file.
251 Migrating from 0.7.1 to 0.8.0
252 =============================
254 You *must* fully uninstall previous Roundup version before installing
255 Roundup 0.8.0. If you don't do that, ``roundup-admin install``
256 command may fail to function properly.
258 0.8.0 Backend changes
259 ---------------------
261 Backends 'bsddb' and 'bsddb3' are removed. If you are using one of these,
262 you *must* migrate to another backend before upgrading.
265 0.8.0 API changes
266 -----------------
268 Class.safeget() was removed from the API. Test your item ids before calling
269 Class.get() instead.
272 0.8.0 New tracker layout
273 ------------------------
275 The ``config.py`` file has been replaced by ``config.ini``. You may use the
276 roundup-admin command "genconfig" to generate a new config file::
278 roundup-admin genconfig <tracker home>/config.ini
280 and modify the values therein based on the contents of your old config.py.
281 In most cases, the names of the config variables are the same.
283 The ``select_db.py`` file has been replaced by a file in the ``db``
284 directory called ``backend_name``. As you might guess, this file contains
285 just the name of the backend. To figure what the contents of yours should
286 be, use the following table:
288 ================================ =========================
289 ``select_db.py`` contents ``backend_name`` contents
290 ================================ =========================
291 from back_anydbm import ... anydbm
292 from back_metakit import ... metakit
293 from back_sqlite import ... sqlite
294 from back_mysql import ... mysql
295 from back_postgresql import ... postgresql
296 ================================ =========================
298 The ``dbinit.py`` file has been split into two new files,
299 ``initial_data.py`` and ``schema.py``. The contents of this file are:
301 ``initial_data.py``
302 You don't need one of these as your tracker is already initialised.
304 ``schema.py``
305 Copy the body of the ``def open(name=None)`` function from your old
306 tracker's ``dbinit.py`` file to this file. As the lines you're copying
307 aren't part of a function definition anymore, one level of indentation
308 needs to be removed (remove only the leading four spaces on each
309 line).
311 The first few lines -- those starting with ``from roundup.hyperdb
312 import ...`` and the ``db = Database(config, name)`` line -- don't
313 need to be copied. Neither do the last few lines -- those starting
314 with ``import detectors``, down to ``return db`` inclusive.
316 You may remove the ``__init__.py`` module from the "detectors" directory as
317 it is no longer used.
319 There's a new way to write extension code for Roundup. If you have code in
320 an ``interfaces.py`` file you should move it. See the `customisation
321 documentation`_ for information about how extensions are now written.
322 Note that some older trackers may use ``interfaces.py`` to customise the
323 mail gateway behaviour. You will need to keep your ``interfaces.py`` file
324 if this is the case.
327 0.8.0 Permissions Changes
328 -------------------------
330 The creation of a new item in the user interfaces is now controlled by the
331 "Create" Permission. You will need to add an assignment of this Permission
332 to your users who are allowed to create items. The most common form of this
333 is the following in your ``schema.py`` added just under the current
334 assignation of the Edit Permission::
336 for cl in 'issue', 'file', 'msg', 'query', 'keyword':
337 p = db.security.getPermission('Create', cl)
338 db.security.addPermissionToRole('User', p)
340 You will need to explicitly let anonymous users access the web interface so
341 that regular users are able to see the login form. Note that almost all
342 trackers will need this Permission. The only situation where it's not
343 required is in a tracker that uses an HTTP Basic Authenticated front-end.
344 It's enabled by adding to your ``schema.py``::
346 p = db.security.getPermission('Web Access')
347 db.security.addPermissionToRole('Anonymous', p)
349 Finally, you will need to enable permission for your users to edit their
350 own details by adding the following to ``schema.py``::
352 # Users should be able to edit their own details. Note that this
353 # permission is limited to only the situation where the Viewed or
354 # Edited item is their own.
355 def own_record(db, userid, itemid):
356 '''Determine whether the userid matches the item being accessed.'''
357 return userid == itemid
358 p = db.security.addPermission(name='View', klass='user', check=own_record,
359 description="User is allowed to view their own user details")
360 p = db.security.addPermission(name='Edit', klass='user', check=own_record,
361 description="User is allowed to edit their own user details")
362 db.security.addPermissionToRole('User', p)
365 0.8.0 Use of TemplatingUtils
366 ----------------------------
368 If you used custom python functions in TemplatingUtils, they must
369 be moved from interfaces.py to a new file in the ``extensions`` directory.
371 Each Function that should be available through TAL needs to be defined
372 as a toplevel function in the newly created file. Furthermore you
373 add an inititialization function, that registers the functions with the
374 tracker.
376 If you find this too tedious, donfu wrote an automatic init function that
377 takes an existing TemplatingUtils class, and registers all class methods
378 that do not start with an underscore. The following hack should be placed
379 in the ``extensions`` directory alongside other extensions::
381 class TemplatingUtils:
382 # copy from interfaces.py
384 def init(tracker):
385 util = TemplatingUtils()
387 def setClient(tu):
388 util.client = tu.client
389 return util
391 def execUtil(name):
392 return lambda tu, *args, **kwargs: \
393 getattr(setClient(tu), name)(*args, **kwargs)
395 for name in dir(util):
396 if callable(getattr(util, name)) and not name.startswith('_'):
397 tracker.registerUtil(name, execUtil(name))
400 0.8.0 Logging Configuration
401 ---------------------------
403 See the `administration guide`_ for information about configuring the new
404 logging implemented in 0.8.0.
407 Migrating from 0.7.2 to 0.7.3
408 =============================
410 0.7.3 Configuration
411 -------------------
413 If you choose, you may specify the directory from which static files are
414 served (those which use the URL component ``@@file``). Currently the
415 directory defaults to the ``TEMPLATES`` configuration variable. You may
416 define a new variable, ``STATIC_FILES`` which overrides this value for
417 static files.
420 Migrating from 0.7.0 to 0.7.2
421 =============================
423 0.7.2 DEFAULT_TIMEZONE is now required
424 --------------------------------------
426 The DEFAULT_TIMEZONE configuration variable is now required. Add the
427 following to your tracker's ``config.py`` file::
429 # You may specify a different default timezone, for use when users do not
430 # choose their own in their settings.
431 DEFAULT_TIMEZONE = 0 # specify as numeric hour offest
434 Migrating from 0.7.0 to 0.7.1
435 =============================
437 0.7.1 Permission assignments
438 ----------------------------
440 If you allow anonymous access to your tracker, you might need to assign
441 some additional View (or Edit if your tracker is that open) permissions
442 to the "anonymous" user. To do so, find the code in your ``dbinit.py`` that
443 says::
445 for cl in 'issue', 'file', 'msg', 'query', 'keyword':
446 p = db.security.getPermission('View', cl)
447 db.security.addPermissionToRole('User', p)
448 p = db.security.getPermission('Edit', cl)
449 db.security.addPermissionToRole('User', p)
450 for cl in 'priority', 'status':
451 p = db.security.getPermission('View', cl)
452 db.security.addPermissionToRole('User', p)
454 Add add a line::
456 db.security.addPermissionToRole('Anonymous', p)
458 next to the existing ``'User'`` lines for the Permissions you wish to
459 assign to the anonymous user.
462 Migrating from 0.6 to 0.7
463 =========================
465 0.7.0 Permission assignments
466 ----------------------------
468 Due to a change in the rendering of web widgets, permissions are now
469 checked on Classes where they previously weren't (this is a good thing).
471 You will need to add some additional Permission assignments for your
472 regular users, or some displays will break. After the following in your
473 tracker's ``dbinit.py``::
475 # Assign the access and edit Permissions for issue, file and message
476 # to regular users now
477 for cl in 'issue', 'file', 'msg', 'query', 'keyword':
478 p = db.security.getPermission('View', cl)
479 db.security.addPermissionToRole('User', p)
480 p = db.security.getPermission('Edit', cl)
481 db.security.addPermissionToRole('User', p)
483 add::
485 for cl in 'priority', 'status':
486 p = db.security.getPermission('View', cl)
487 db.security.addPermissionToRole('User', p)
490 0.7.0 Getting the current user id
491 ---------------------------------
493 The Database.curuserid attribute has been removed.
495 Any code referencing this attribute should be replaced with a
496 call to Database.getuid().
499 0.7.0 ZRoundup changes
500 ----------------------
502 The templates in your tracker's html directory will need updating if you
503 wish to use ZRoundup. If you've not modified those files (or some of them),
504 you may just copy the new versions from the Roundup source in the
505 templates/classic/html directory.
507 If you have modified the html files, then you'll need to manually edit them
508 to change all occurances of special form variables from using the colon ":"
509 special character to the at "@" special character. That is, variables such
510 as::
512 :action :required :template :remove:messages ...
514 should become::
516 @action @required @template @remove@messages ...
518 Note that ``tal:`` statements are unaffected. So are TAL expression type
519 prefixes such as ``python:`` and ``string:``. Please ask on the
520 roundup-users mailing list for help if you're unsure.
523 0.7.0 Edit collision detection
524 ------------------------------
526 Roundup now detects collisions with editing in the web interface (that is,
527 two people editing the same item at the same time).
529 You must copy the ``_generic.collision.html`` file from Roundup source in
530 the ``templates/classic/html`` directory. to your tracker's ``html``
531 directory.
534 Migrating from 0.6.x to 0.6.3
535 =============================
537 0.6.3 Configuration
538 -------------------
540 You will need to copy the file::
542 templates/classic/detectors/__init__.py
544 to your tracker's ``detectors`` directory, replacing the one already there.
545 This fixes a couple of bugs in that file.
549 Migrating from 0.5 to 0.6
550 =========================
553 0.6.0 Configuration
554 -------------------
556 Introduced EMAIL_FROM_TAG config variable. This value is inserted into
557 the From: line of nosy email. If the sending user is "Foo Bar", the
558 From: line is usually::
560 "Foo Bar" <issue_tracker@tracker.example>
562 the EMAIL_FROM_TAG goes inside the "Foo Bar" quotes like so::
564 "Foo Bar EMAIL_FROM_TAG" <issue_tracker@tracker.example>
566 I've altered the mechanism in the detectors __init__.py module so that it
567 doesn't cross-import detectors from other trackers (if you run more than one
568 in a single roundup-server). This change means that you'll need to copy the
569 __init__.py from roundup/templates/classic/detectors/__init__.py to your
570 <tracker home>/detectors/__init__.py. Don't worry, the "classic" __init__ is a
571 one-size-fits-all, so it'll work even if you've added/removed detectors.
573 0.6.0 Templating changes
574 ------------------------
576 The ``user.item`` template (in the tracker home "templates" directory)
577 needs to have the following hidden variable added to its form (between the
578 ``<form...>`` and ``</form>`` tags::
580 <input type="hidden" name=":template" value="item">
583 0.6.0 Form handling changes
584 ---------------------------
586 Roundup's form handling capabilities have been significantly expanded. This
587 should not affect users of 0.5 installations - but if you find you're
588 getting errors from form submissions, please ask for help on the Roundup
589 users mailing list:
591 http://lists.sourceforge.net/lists/listinfo/roundup-users
593 See the customisation doc section on `Form Values`__ for documentation of the
594 new form variables possible.
596 __ customizing.html#form-values
599 0.6.0 Multilingual character set support
600 ----------------------------------------
602 Added internationalization support. This is done via encoding all data
603 stored in roundup database to utf-8 (unicode encoding). To support utf-8 in
604 web interface you should add the folowing line to your tracker's html/page
605 and html/_generic.help files inside <head> tag::
607 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
609 Since latin characters in utf-8 have the same codes as in ASCII table, this
610 modification is optional for users who use only plain latin characters.
612 After this modification, you will be able to see and enter any world
613 character via web interface. Data received via mail interface also converted
614 to utf-8, however only new messages will be converted. If your roundup
615 database contains some of non-ASCII characters in one of 8-bit encoding,
616 they will not be visible in new unicode environment. Some of such data (e.g.
617 user names, keywords, etc) can be edited by administrator, the others
618 (e.g. messages' contents) is not editable via web interface. Currently there
619 is no tool for converting such data, the only solution is to close
620 appropriate old issues and create new ones with the same content.
623 0.6.0 User timezone support
624 ---------------------------
626 From version 0.6.0 roundup supports displaying of Date data in user' local
627 timezone if he/she has provided timezone information. To make it possible
628 some modification to tracker's schema and HTML templates are required.
629 First you must add string property 'timezone' to user class in dbinit.py
630 like this::
632 user = Class(db, "user",
633 username=String(), password=Password(),
634 address=String(), realname=String(),
635 phone=String(), organisation=String(),
636 alternate_addresses=String(),
637 queries=Multilink('query'), roles=String(),
638 timezone=String())
640 And second - html interface. Add following lines to
641 $TRACKER_HOME/html/user.item template::
643 <tr>
644 <th>Timezone</th>
645 <td tal:content="structure context/timezone/field">timezone</td>
646 </tr>
648 After that all users should be able to provide their timezone information.
649 Timezone should be a positive or negative integer - offset from GMT.
651 After providing timezone, roundup will show all dates values, found in web
652 and mail interfaces in local time. It will also accept any Date info in
653 local time, convert and store it in GMT.
656 0.6.0 Search page structure
657 ---------------------------
659 In order to accomodate query editing the search page has been restructured. If
660 you want to provide your users with query editing, you should update your
661 search page using the macros detailed in the customisation doc section
662 `Searching on categories`__.
664 __ customizing.html#searching-on-categories
666 Also, the url field in the query class no longer starts with a '?'. You'll need
667 to remove this question mark from the url field to support queries. There's
668 a script in the "tools" directory called ``migrate-queries.py`` that should
669 automatically change any existing queries for you. As always, make a backup
670 of your database before running such a script.
673 0.6.0 Notes for metakit backend users
674 -------------------------------------
676 Roundup 0.6.0 introduced searching on ranges of dates and intervals. To
677 support it, some modifications to interval storing routine were made. So if
678 your tracker uses metakit backend and your db schema contains intervals
679 property, searches on that property will not be accurate for db items that
680 was stored before roundup' upgrade. However all new records should be
681 searchable on intervals.
683 It is possible to convert your database to new format: you can export and
684 import back all your data (consult "Migrating backends" in "Maintenance"
685 documentation). After this operation all your interval properties should
686 become searchable.
688 Users of backends others than metakit should not worry about this issue.
691 Migrating from 0.4.x to 0.5.0
692 =============================
694 This has been a fairly major revision of Roundup:
696 1. Brand new, much more powerful, flexible, tasty and nutritious templating.
697 Unfortunately, this means all your current templates are useless. Hopefully
698 the new documentation and examples will be enough to help you make the
699 transition. Please don't hesitate to ask on roundup-users for help (or
700 complete conversions if you're completely stuck)!
701 2. The database backed got a lot more flexible, allowing Metakit and SQL
702 databases! The only decent SQL database implemented at present is sqlite,
703 but others shouldn't be a whole lot more work.
704 3. A brand new, highly flexible and much more robust security system including
705 a system of Permissions, Roles and Role assignments to users. You may now
706 define your own Permissions that may be checked in CGI transactions.
707 4. Journalling has been made less storage-hungry, so has been turned on
708 by default *except* for author, recipient and nosy link/unlink events. You
709 are advised to turn it off in your trackers too.
710 5. We've changed the terminology from "instance" to "tracker", to ease the
711 learning curve/impact for new users.
712 6. Because of the above changes, the tracker configuration has seen some
713 major changes. See below for the details.
715 Please, **back up your database** before you start the migration process. This
716 is as simple as copying the "db" directory and all its contents from your
717 tracker to somewhere safe.
720 0.5.0 Configuration
721 -------------------
723 First up, rename your ``instance_config.py`` file to just ``config.py``.
725 Then edit your tracker's ``__init__.py`` module. It'll currently look
726 like this::
728 from instance_config import *
729 try:
730 from dbinit import *
731 except ImportError:
732 pass # in installdir (probably :)
733 from interfaces import *
735 and it needs to be::
737 import config
738 from dbinit import open, init
739 from interfaces import Client, MailGW
741 Due to the new templating having a top-level ``page`` that defines links for
742 searching, indexes, adding items etc, the following variables are no longer
743 used:
745 - HEADER_INDEX_LINKS
746 - HEADER_ADD_LINKS
747 - HEADER_SEARCH_LINKS
748 - SEARCH_FILTERS
749 - DEFAULT_INDEX
750 - UNASSIGNED_INDEX
751 - USER_INDEX
752 - ISSUE_FILTER
754 The new security implementation will require additions to the dbinit module,
755 but also removes the need for the following tracker config variables:
757 - ANONYMOUS_ACCESS
758 - ANONYMOUS_REGISTER
760 but requires two new variables which define the Roles assigned to users who
761 register through the web and e-mail interfaces:
763 - NEW_WEB_USER_ROLES
764 - NEW_EMAIL_USER_ROLES
766 in both cases, 'User' is a good initial setting. To emulate
767 ``ANONYMOUS_ACCESS='deny'``, remove all "View" Permissions from the
768 "Anonymous" Role. To emulate ``ANONYMOUS_REGISTER='deny'``, remove the "Web
769 Registration" and/or the "Email Registration" Permission from the "Anonymous"
770 Role. See the section on customising security in the `customisation
771 documentation`_ for more information.
773 Finally, the following config variables have been renamed to make more sense:
775 - INSTANCE_HOME -> TRACKER_HOME
776 - INSTANCE_NAME -> TRACKER_NAME
777 - ISSUE_TRACKER_WEB -> TRACKER_WEB
778 - ISSUE_TRACKER_EMAIL -> TRACKER_EMAIL
781 0.5.0 Schema Specification
782 --------------------------
784 0.5.0 Database backend changes
785 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
787 Your select_db module in your tracker has changed a fair bit. Where it used
788 to contain::
790 # WARNING: DO NOT EDIT THIS FILE!!!
791 from roundup.backends.back_anydbm import Database
793 it must now contain::
795 # WARNING: DO NOT EDIT THIS FILE!!!
796 from roundup.backends.back_anydbm import Database, Class, FileClass, IssueClass
798 Yes, I realise the irony of the "DO NOT EDIT THIS FILE" statement :)
799 Note the addition of the Class, FileClass, IssueClass imports. These are very
800 important, as they're going to make the next change work too. You now need to
801 modify the top of the dbinit module in your tracker from::
803 import instance_config
804 from roundup import roundupdb
805 from select_db import Database
807 from roundup.roundupdb import Class, FileClass
809 class Database(roundupdb.Database, select_db.Database):
810 ''' Creates a hybrid database from:
811 . the selected database back-end from select_db
812 . the roundup extensions from roundupdb
813 '''
814 pass
816 class IssueClass(roundupdb.IssueClass):
817 ''' issues need the email information
818 '''
819 pass
821 to::
823 import config
824 from select_db import Database, Class, FileClass, IssueClass
826 Yes, remove the Database and IssueClass definitions and those other imports.
827 They're not needed any more!
829 Look for places in dbinit.py where ``instance_config`` is used too, and
830 rename them ``config``.
833 0.5.0 Journalling changes
834 ~~~~~~~~~~~~~~~~~~~~~~~~~
836 Journalling has been optimised for storage. Journalling of links has been
837 turned back on by default. If your tracker has a large user base, you may wish
838 to turn off journalling of nosy list, message author and message recipient
839 link and unlink events. You do this by adding ``do_journal='no'`` to the Class
840 initialisation in your dbinit. For example, your *msg* class initialisation
841 probably looks like this::
843 msg = FileClass(db, "msg",
844 author=Link("user"), recipients=Multilink("user"),
845 date=Date(), summary=String(),
846 files=Multilink("file"),
847 messageid=String(), inreplyto=String())
849 to turn off journalling of author and recipient link events, add
850 ``do_journal='no'`` to the ``author=Link("user")`` part of the statement,
851 like so::
853 msg = FileClass(db, "msg",
854 author=Link("user", do_journal='no'),
855 recipients=Multilink("user", do_journal='no'),
856 date=Date(), summary=String(),
857 files=Multilink("file"),
858 messageid=String(), inreplyto=String())
860 Nosy list link event journalling is actually turned off by default now. If you
861 want to turn it on, change to your issue class' nosy list, change its
862 definition from::
864 issue = IssueClass(db, "issue",
865 assignedto=Link("user"), topic=Multilink("keyword"),
866 priority=Link("priority"), status=Link("status"))
868 to::
870 issue = IssueClass(db, "issue", nosy=Multilink("user", do_journal='yes'),
871 assignedto=Link("user"), topic=Multilink("keyword"),
872 priority=Link("priority"), status=Link("status"))
874 noting that your definition of the nosy Multilink will override the normal one.
877 0.5.0 User schema changes
878 ~~~~~~~~~~~~~~~~~~~~~~~~~
880 Users have two more properties, "queries" and "roles". You'll have something
881 like this in your dbinit module now::
883 user = Class(db, "user",
884 username=String(), password=Password(),
885 address=String(), realname=String(),
886 phone=String(), organisation=String(),
887 alternate_addresses=String())
888 user.setkey("username")
890 and you'll need to add the new properties and the new "query" class to it
891 like so::
893 query = Class(db, "query",
894 klass=String(), name=String(),
895 url=String())
896 query.setkey("name")
898 # Note: roles is a comma-separated string of Role names
899 user = Class(db, "user",
900 username=String(), password=Password(),
901 address=String(), realname=String(),
902 phone=String(), organisation=String(),
903 alternate_addresses=String(),
904 queries=Multilink('query'), roles=String())
905 user.setkey("username")
907 The "queries" property is used to store off the user's favourite database
908 queries. The "roles" property is explained below in `0.5.0 Security
909 Settings`_.
912 0.5.0 Security Settings
913 ~~~~~~~~~~~~~~~~~~~~~~~
915 See the `security documentation`_ for an explanation of how the new security
916 system works. In a nutshell though, the security is handled as a four step
917 process:
919 1. Permissions are defined as having a name and optionally a hyperdb class
920 they're specific to,
921 2. Roles are defined that have one or more Permissions,
922 3. Users are assigned Roles in their "roles" property, and finally
923 4. Roundup checks that users have appropriate Permissions at appropriate times
924 (like editing issues).
926 Your tracker dbinit module's *open* function now has to define any
927 Permissions that are specific to your tracker, and also the assignment
928 of Permissions to Roles. At the moment, your open function
929 ends with::
931 import detectors
932 detectors.init(db)
934 return db
936 and what we need to do is insert some commands that will set up the security
937 parameters. Right above the ``import detectors`` line, you'll want to insert
938 these lines::
940 #
941 # SECURITY SETTINGS
942 #
943 # new permissions for this schema
944 for cl in 'issue', 'file', 'msg', 'user':
945 db.security.addPermission(name="Edit", klass=cl,
946 description="User is allowed to edit "+cl)
947 db.security.addPermission(name="View", klass=cl,
948 description="User is allowed to access "+cl)
950 # Assign the access and edit permissions for issue, file and message
951 # to regular users now
952 for cl in 'issue', 'file', 'msg':
953 p = db.security.getPermission('View', cl)
954 db.security.addPermissionToRole('User', p)
955 p = db.security.getPermission('Edit', cl)
956 db.security.addPermissionToRole('User', p)
957 # and give the regular users access to the web and email interface
958 p = db.security.getPermission('Web Access')
959 db.security.addPermissionToRole('User', p)
960 p = db.security.getPermission('Email Access')
961 db.security.addPermissionToRole('User', p)
963 # May users view other user information? Comment these lines out
964 # if you don't want them to
965 p = db.security.getPermission('View', 'user')
966 db.security.addPermissionToRole('User', p)
968 # Assign the appropriate permissions to the anonymous user's Anonymous
969 # Role. Choices here are:
970 # - Allow anonymous users to register through the web
971 p = db.security.getPermission('Web Registration')
972 db.security.addPermissionToRole('Anonymous', p)
973 # - Allow anonymous (new) users to register through the email gateway
974 p = db.security.getPermission('Email Registration')
975 db.security.addPermissionToRole('Anonymous', p)
976 # - Allow anonymous users access to the "issue" class of data
977 # Note: this also grants access to related information like files,
978 # messages, statuses etc that are linked to issues
979 #p = db.security.getPermission('View', 'issue')
980 #db.security.addPermissionToRole('Anonymous', p)
981 # - Allow anonymous users access to edit the "issue" class of data
982 # Note: this also grants access to create related information like
983 # files and messages etc that are linked to issues
984 #p = db.security.getPermission('Edit', 'issue')
985 #db.security.addPermissionToRole('Anonymous', p)
987 # oh, g'wan, let anonymous access the web interface too
988 p = db.security.getPermission('Web Access')
989 db.security.addPermissionToRole('Anonymous', p)
991 Note in the comments there the places where you might change the permissions
992 to restrict users or grant users more access. If you've created additional
993 classes that users should be able to edit and view, then you should add them
994 to the "new permissions for this schema" section at the start of the security
995 block. Then add them to the "Assign the access and edit permissions" section
996 too, so people actually have the new Permission you've created.
998 One final change is needed that finishes off the security system's
999 initialisation. We need to add a call to ``db.post_init()`` at the end of the
1000 dbinit open() function. Add it like this::
1002 import detectors
1003 detectors.init(db)
1005 # schema is set up - run any post-initialisation
1006 db.post_init()
1007 return db
1009 You may verify the setup of Permissions and Roles using the new
1010 "``roundup-admin security``" command.
1013 0.5.0 User changes
1014 ~~~~~~~~~~~~~~~~~~
1016 To support all those schema changes, you'll need to massage your user database
1017 a little too, to:
1019 1. make sure there's an "anonymous" user - this user is mandatory now and is
1020 the one that unknown users are logged in as.
1021 2. make sure all users have at least one Role.
1023 If you don't have the "anonymous" user, create it now with the command::
1025 roundup-admin create user username=anonymous roles=Anonymous
1027 making sure the capitalisation is the same as above. Once you've done that,
1028 you'll need to set the roles property on all users to a reasonable default.
1029 The admin user should get "Admin", the anonymous user "Anonymous"
1030 and all other users "User". The ``fixroles.py`` script in the tools directory
1031 will do this. Run it like so (where python is your python 2+ binary)::
1033 python tools/fixroles.py -i <tracker home> fixroles
1037 0.5.0 CGI interface changes
1038 ---------------------------
1040 The CGI interface code was completely reorganised and largely rewritten. The
1041 end result is that this section of your tracker interfaces module will need
1042 changing from::
1044 from roundup import cgi_client, mailgw
1045 from roundup.i18n import _
1047 class Client(cgi_client.Client):
1048 ''' derives basic CGI implementation from the standard module,
1049 with any specific extensions
1050 '''
1051 pass
1053 to::
1055 from roundup import mailgw
1056 from roundup.cgi import client
1058 class Client(client.Client):
1059 ''' derives basic CGI implementation from the standard module,
1060 with any specific extensions
1061 '''
1062 pass
1064 You will also need to install the new version of roundup.cgi from the source
1065 cgi-bin directory if you're using it.
1068 0.5.0 HTML templating
1069 ---------------------
1071 You'll want to make a backup of your current tracker html directory. You
1072 should then copy the html directory from the Roundup source "classic" template
1073 and modify it according to your local schema changes.
1075 If you need help with the new templating system, please ask questions on the
1076 roundup-users mailing list (available through the roundup project page on
1077 sourceforge, http://roundup.sf.net/)
1080 0.5.0 Detectors
1081 ---------------
1083 The nosy reactor has been updated to handle the tracker not having an
1084 "assignedto" property on issues. You may want to copy it into your tracker's
1085 detectors directory. Chances are you've already fixed it though :)
1088 Migrating from 0.4.1 to 0.4.2
1089 =============================
1091 0.4.2 Configuration
1092 -------------------
1093 The USER_INDEX definition introduced in 0.4.1 was too restrictive in its
1094 allowing replacement of 'assignedto' with the user's userid. Users must change
1095 the None value of 'assignedto' to 'CURRENT USER' (the string, in quotes) for
1096 the replacement behaviour to occur now.
1098 The new configuration variables are:
1100 - EMAIL_KEEP_QUOTED_TEXT
1101 - EMAIL_LEAVE_BODY_UNCHANGED
1102 - ADD_RECIPIENTS_TO_NOSY
1104 See the sample configuration files in::
1106 <roundup source>/roundup/templates/classic/instance_config.py
1108 and::
1110 <roundup source>/roundup/templates/extended/instance_config.py
1112 and the `customisation documentation`_ for information on how they're used.
1115 0.4.2 Changes to detectors
1116 --------------------------
1117 You will need to copy the detectors from the distribution into your instance
1118 home "detectors" directory. If you used the classic schema, the detectors
1119 are in::
1121 <roundup source>/roundup/templates/classic/detectors/
1123 If you used the extended schema, the detectors are in::
1125 <roundup source>/roundup/templates/extended/detectors/
1127 The change means that schema-specific code has been removed from the
1128 mail gateway and cgi interface and made into auditors:
1130 - nosyreactor.py has now got an updatenosy auditor which updates the nosy
1131 list with author, recipient and assignedto information.
1132 - statusauditor.py makes the unread or resolved -> chatting changes and
1133 presets the status of an issue to unread.
1135 There's also a bug or two fixed in the nosyreactor code.
1137 0.4.2 HTML templating changes
1138 -----------------------------
1139 The link() htmltemplate function now has a "showid" option for links and
1140 multilinks. When true, it only displays the linked item id as the anchor
1141 text. The link value is displayed as a tooltip using the title anchor
1142 attribute. To use in eg. the superseder field, have something like this::
1144 <td>
1145 <display call="field('superseder', showid=1)">
1146 <display call="classhelp('issue', 'id,title', label='list', width=500)">
1147 <property name="superseder">
1148 <br>View: <display call="link('superseder', showid=1)">
1149 </property>
1150 </td>
1152 The stylesheets have been cleaned up too. You may want to use the newer
1153 versions in::
1155 <roundup source>/roundup/templates/<template>/html/default.css
1159 Migrating from 0.4.0 to 0.4.1
1160 =============================
1162 0.4.1 Files storage
1163 -------------------
1165 Messages and files from newly created issues will be put into subdierectories
1166 in thousands e.g. msg123 will be put into files/msg/0/msg123, file2003
1167 will go into files/file/2/file2003. Previous messages are still found, but
1168 could be put into this structure.
1170 0.4.1 Configuration
1171 -------------------
1173 To allow more fine-grained access control, the variable used to check
1174 permission to auto-register users in the mail gateway is now called
1175 ANONYMOUS_REGISTER_MAIL rather than overloading ANONYMOUS_REGISTER. If the
1176 variable doesn't exist, then ANONYMOUS_REGISTER is tested as before.
1178 Configuring the links in the web header is now easier too. The following
1179 variables have been added to the classic instance_config.py::
1181 HEADER_INDEX_LINKS - defines the "index" links to be made available
1182 HEADER_ADD_LINKS - defines the "add" links
1183 DEFAULT_INDEX - specifies the index view for DEFAULT
1184 UNASSIGNED_INDEX - specifies the index view for UNASSIGNED
1185 USER_INDEX - specifies the index view for USER
1187 See the <roundup source>/roundup/templates/classic/instance_config.py for more
1188 information - including how the variables are to be set up. Most users will
1189 just be able to copy the variables from the source to their instance home. If
1190 you've modified the header by changing the source of the interfaces.py file in
1191 the instance home, you'll need to remove that customisation and move it into
1192 the appropriate variables in instance_config.py.
1194 The extended schema has similar variables added too - see the source for more
1195 info.
1197 0.4.1 Alternate E-Mail Addresses
1198 --------------------------------
1200 If you add the property "alternate_addresses" to your user class, your users
1201 will be able to register alternate email addresses that they may use to
1202 communicate with roundup as. All email from roundup will continue to be sent
1203 to their primary address.
1205 If you have not edited the dbinit.py file in your instance home directory,
1206 you may simply copy the new dbinit.py file from the core code. If you used
1207 the classic schema, the interfaces file is in::
1209 <roundup source>/roundup/templates/classic/dbinit.py
1211 If you used the extended schema, the file is in::
1213 <roundup source>/roundup/templates/extended/dbinit.py
1215 If you have modified your dbinit.py file, you need to edit the dbinit.py
1216 file in your instance home directory. Find the lines which define the user
1217 class::
1219 user = Class(db, "msg",
1220 username=String(), password=Password(),
1221 address=String(), realname=String(),
1222 phone=String(), organisation=String(),
1223 alternate_addresses=String())
1225 You will also want to add the property to the user's details page. The
1226 template for this is the "user.item" file in your instance home "html"
1227 directory. Similar to above, you may copy the file from the roundup source if
1228 you haven't modified it. Otherwise, add the following to the template::
1230 <display call="multiline('alternate_addresses')">
1232 with appropriate labelling etc. See the standard template for an idea.
1236 Migrating from 0.3.x to 0.4.0
1237 =============================
1239 0.4.0 Message-ID and In-Reply-To addition
1240 -----------------------------------------
1241 0.4.0 adds the tracking of messages by message-id and allows threading
1242 using in-reply-to. Most e-mail clients support threading using this
1243 feature, and we hope to add support for it to the web gateway. If you
1244 have not edited the dbinit.py file in your instance home directory, you may
1245 simply copy the new dbinit.py file from the core code. If you used the
1246 classic schema, the interfaces file is in::
1248 <roundup source>/roundup/templates/classic/dbinit.py
1250 If you used the extended schema, the file is in::
1252 <roundup source>/roundup/templates/extended/dbinit.py
1254 If you have modified your dbinit.py file, you need to edit the dbinit.py
1255 file in your instance home directory. Find the lines which define the msg
1256 class::
1258 msg = FileClass(db, "msg",
1259 author=Link("user"), recipients=Multilink("user"),
1260 date=Date(), summary=String(),
1261 files=Multilink("file"))
1263 and add the messageid and inreplyto properties like so::
1265 msg = FileClass(db, "msg",
1266 author=Link("user"), recipients=Multilink("user"),
1267 date=Date(), summary=String(),
1268 files=Multilink("file"),
1269 messageid=String(), inreplyto=String())
1271 Also, configuration is being cleaned up. This means that your dbinit.py will
1272 also need to be changed in the open function. If you haven't changed your
1273 dbinit.py, the above copy will be enough. If you have, you'll need to change
1274 the line (round line 50)::
1276 db = Database(instance_config.DATABASE, name)
1278 to::
1280 db = Database(instance_config, name)
1283 0.4.0 Configuration
1284 --------------------
1285 ``TRACKER_NAME`` and ``EMAIL_SIGNATURE_POSITION`` have been added to the
1286 instance_config.py. The simplest solution is to copy the default values
1287 from template in the core source.
1289 The mail gateway now checks ``ANONYMOUS_REGISTER`` to see if unknown users
1290 are to be automatically registered with the tracker. If it is set to "deny"
1291 then unknown users will not have access. If it is set to "allow" they will be
1292 automatically registered with the tracker.
1295 0.4.0 CGI script roundup.cgi
1296 ----------------------------
1297 The CGI script has been updated with some features and a bugfix, so you should
1298 copy it from the roundup cgi-bin source directory again. Make sure you update
1299 the ROUNDUP_INSTANCE_HOMES after the copy.
1302 0.4.0 Nosy reactor
1303 ------------------
1304 The nosy reactor has also changed - copy the nosyreactor.py file from the core
1305 source::
1307 <roundup source>/roundup/templates/<template>/detectors/nosyreactor.py
1309 to your instance home "detectors" directory.
1312 0.4.0 HTML templating
1313 ---------------------
1314 The field() function was incorrectly implemented - links and multilinks now
1315 display as text fields when rendered using field(). To display a menu (drop-
1316 down or select box) you need to use the menu() function.
1320 Migrating from 0.2.x to 0.3.x
1321 =============================
1323 0.3.x Cookie Authentication changes
1324 -----------------------------------
1325 0.3.0 introduces cookie authentication - you will need to copy the
1326 interfaces.py file from the roundup source to your instance home to enable
1327 authentication. If you used the classic schema, the interfaces file is in::
1329 <roundup source>/roundup/templates/classic/interfaces.py
1331 If you used the extended schema, the file is in::
1333 <roundup source>/roundup/templates/extended/interfaces.py
1335 If you have modified your interfaces.Client class, you will need to take
1336 note of the login/logout functionality provided in roundup.cgi_client.Client
1337 (classic schema) or roundup.cgi_client.ExtendedClient (extended schema) and
1338 modify your instance code apropriately.
1341 0.3.x Password encoding
1342 -----------------------
1343 This release also introduces encoding of passwords in the database. If you
1344 have not edited the dbinit.py file in your instance home directory, you may
1345 simply copy the new dbinit.py file from the core code. If you used the
1346 classic schema, the interfaces file is in::
1348 <roundup source>/roundup/templates/classic/dbinit.py
1350 If you used the extended schema, the file is in::
1352 <roundup source>/roundup/templates/extended/dbinit.py
1355 If you have modified your dbinit.py file, you may use encoded passwords:
1357 1. Edit the dbinit.py file in your instance home directory
1358 a. At the first code line of the open() function::
1360 from roundup.hyperdb import String, Date, Link, Multilink
1362 alter to include Password, as so::
1364 from roundup.hyperdb import String, Password, Date, Link, Multilink
1366 b. Where the password property is defined (around line 66)::
1368 user = Class(db, "user",
1369 username=String(), password=String(),
1370 address=String(), realname=String(),
1371 phone=String(), organisation=String())
1372 user.setkey("username")
1374 alter the "password=String()" to "password=Password()"::
1376 user = Class(db, "user",
1377 username=String(), password=Password(),
1378 address=String(), realname=String(),
1379 phone=String(), organisation=String())
1380 user.setkey("username")
1382 2. Any existing passwords in the database will remain cleartext until they
1383 are edited. It is recommended that at a minimum the admin password be
1384 changed immediately::
1386 roundup-admin -i <instance home> set user1 password=<new password>
1389 0.3.x Configuration
1390 -------------------
1391 FILTER_POSITION, ANONYMOUS_ACCESS, ANONYMOUS_REGISTER have been added to
1392 the instance_config.py. Simplest solution is to copy the default values from
1393 template in the core source.
1395 MESSAGES_TO_AUTHOR has been added to the IssueClass in dbinit.py. Set to 'yes'
1396 to send nosy messages to the author. Default behaviour is to not send nosy
1397 messages to the author. You will need to add MESSAGES_TO_AUTHOR to your
1398 dbinit.py in your instance home.
1401 0.3.x CGI script roundup.cgi
1402 ----------------------------
1403 There have been some structural changes to the roundup.cgi script - you will
1404 need to install it again from the cgi-bin directory of the source
1405 distribution. Make sure you update the ROUNDUP_INSTANCE_HOMES after the
1406 copy.
1409 .. _`customisation documentation`: customizing.html
1410 .. _`security documentation`: security.html
1411 .. _`administration guide`: admin_guide.html