Mercurial > p > roundup > code
changeset 3904:91008ec8f9a0
retire "topic" usage
"Topic" still appears in the locale files. I'm sure we need to support
that for existing trackers. I *think* they don't care about any of the other
changes that have been made.
I also left Ka-Ping Yee's original design document unchanged.
This takes care of sf feature request [SF#953161]
| author | Justus Pendleton <jpend@users.sourceforge.net> |
|---|---|
| date | Sun, 16 Sep 2007 02:45:11 +0000 |
| parents | a90fa2e08a0a |
| children | 6733a7cce7f4 |
| files | doc/customizing.txt doc/design.txt doc/overview.txt doc/user_guide.txt roundup/roundupdb.py scripts/import_sf.py templates/classic/html/help_controls.js templates/classic/html/issue.index.html templates/classic/html/issue.item.html templates/classic/html/issue.search.html templates/classic/schema.py templates/minimal/html/help_controls.js test/test_cgi.py |
| diffstat | 13 files changed, 97 insertions(+), 98 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/customizing.txt Fri Sep 14 15:55:25 2007 +0000 +++ b/doc/customizing.txt Sun Sep 16 02:45:11 2007 +0000 @@ -2,7 +2,7 @@ Customising Roundup =================== -:Version: $Revision: 1.220 $ +:Version: $Revision: 1.221 $ .. This document borrows from the ZopeBook section on ZPT. The original is at: http://www.zope.org/Documentation/Books/ZopeBook/current/ZPT.stx @@ -445,7 +445,7 @@ file = FileClass(db, "file", name=String()) - issue = IssueClass(db, "issue", topic=Multilink("keyword"), + issue = IssueClass(db, "issue", keyword=Multilink("keyword"), status=Link("status"), assignedto=Link("user"), priority=Link("priority")) issue.setkey('title') @@ -2481,10 +2481,10 @@ been added for clarity):: /issue?status=unread,in-progress,resolved& - topic=security,ui& + keyword=security,ui& @group=priority,-status& @sort=-activity& - @filters=status,topic& + @filters=status,keyword& @columns=title,status,fixer The index view is determined by two parts of the specifier: the layout @@ -2503,11 +2503,11 @@ The example specifies an index of "issue" items. Only items with a "status" of either "unread" or "in-progress" or "resolved" are -displayed, and only items with "topic" values including both "security" +displayed, and only items with "keyword" values including both "security" and "ui" are displayed. The items are grouped by priority arranged in ascending order and in descending order by status; and within groups, sorted by activity, arranged in descending order. The filter -section shows filters for the "status" and "topic" properties, and the +section shows filters for the "status" and "keyword" properties, and the table includes columns for the "title", "status", and "fixer" properties. @@ -2904,7 +2904,7 @@ 1. Modify the ``schema.py``:: issue = IssueClass(db, "issue", - assignedto=Link("user"), topic=Multilink("keyword"), + assignedto=Link("user"), keyword=Multilink("keyword"), priority=Link("priority"), status=Link("status"), due_date=Date()) @@ -3398,7 +3398,7 @@ ``schema.py``):: issue = IssueClass(db, "issue", - assignedto=Link("user"), topic=Multilink("keyword"), + assignedto=Link("user"), keyword=Multilink("keyword"), priority=Link("priority"), status=Link("status"), times=Multilink("timelog")) @@ -3571,7 +3571,7 @@ # store issues related to those systems support = IssueClass(db, "support", - assignedto=Link("user"), topic=Multilink("keyword"), + assignedto=Link("user"), keyword=Multilink("keyword"), status=Link("status"), deadline=Date(), affects=Multilink("system")) @@ -4055,14 +4055,14 @@ this class in your tracker's ``schema.py`` file. Change this:: issue = IssueClass(db, "issue", - assignedto=Link("user"), topic=Multilink("keyword"), + assignedto=Link("user"), keyword=Multilink("keyword"), priority=Link("priority"), status=Link("status")) to this, adding the blockers entry:: issue = IssueClass(db, "issue", blockers=Multilink("issue"), - assignedto=Link("user"), topic=Multilink("keyword"), + assignedto=Link("user"), keyword=Multilink("keyword"), priority=Link("priority"), status=Link("status")) 2. Add the new ``blockers`` property to the ``issue.item.html`` edit @@ -4204,33 +4204,32 @@ history at the bottom of the issue page - look for a "link" event to another issue's "blockers" property. -Add users to the nosy list based on the topic -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Add users to the nosy list based on the keyword +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Let's say we need the ability to automatically add users to the nosy list based -on the occurance of a topic. Every user should be allowed to edit their -own list of topics for which they want to be added to the nosy list. +on the occurance of a keyword. Every user should be allowed to edit their +own list of keywords for which they want to be added to the nosy list. Below, we'll show that this change can be done with minimal understanding of the Roundup system, using only copy and paste. This requires three changes to the tracker: a change in the database to -allow per-user recording of the lists of topics for which he wants to +allow per-user recording of the lists of keywords for which he wants to be put on the nosy list, a change in the user view allowing them to edit -this list of topics, and addition of an auditor which updates the nosy -list when a topic is set. - -Adding the nosy topic list -:::::::::::::::::::::::::: - -The change to make in the database, is that for any user there should be -a list of topics for which he wants to be put on the nosy list. Adding -a ``Multilink`` of ``keyword`` seems to fullfill this (note that within -the code, topics are called ``keywords``.) As such, all that has to be -done is to add a new field to the definition of ``user`` within the -file ``schema.py``. We will call this new field ``nosy_keywords``, and -the updated definition of user will be:: +this list of keywords, and addition of an auditor which updates the nosy +list when a keyword is set. + +Adding the nosy keyword list +:::::::::::::::::::::::::::: + +The change to make in the database, is that for any user there should be a list +of keywords for which he wants to be put on the nosy list. Adding a +``Multilink`` of ``keyword`` seems to fullfill this. As such, all that has to +be done is to add a new field to the definition of ``user`` within the file +``schema.py``. We will call this new field ``nosy_keywords``, and the updated +definition of user will be:: user = Class(db, "user", username=String(), password=Password(), @@ -4241,22 +4240,22 @@ timezone=String(), nosy_keywords=Multilink('keyword')) -Changing the user view to allow changing the nosy topic list -:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: - -We want any user to be able to change the list of topics for which +Changing the user view to allow changing the nosy keyword list +:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +We want any user to be able to change the list of keywords for which he will by default be added to the nosy list. We choose to add this to the user view, as is generated by the file ``html/user.item.html``. We can easily -see that the topic field in the issue view has very similar editing -requirements as our nosy topics, both being lists of topics. As -such, we look for Topics in ``issue.item.html``, and extract the +see that the keyword field in the issue view has very similar editing +requirements as our nosy keywords, both being lists of keywords. As +such, we look for Keywords in ``issue.item.html``, and extract the associated parts from there. We add this to ``user.item.html`` at the bottom of the list of viewed items (i.e. just below the 'Alternate E-mail addresses' in the classic template):: <tr> - <th>Nosy Topics</th> + <th>Nosy Keywords</th> <td> <span tal:replace="structure context/nosy_keywords/field" /> <span tal:replace="structure python:db.keyword.classhelp(property='nosy_keywords')" /> @@ -4269,7 +4268,7 @@ The more difficult part is the logic to add the users to the nosy list when required. -We choose to perform this action whenever the topics on an +We choose to perform this action whenever the keywords on an item are set (this includes the creation of items). Here we choose to start out with a copy of the ``detectors/nosyreaction.py`` detector, which we copy to the file @@ -4290,8 +4289,8 @@ code, which handled adding the assignedto user(s) to the nosy list in ``updatenosy``, should be replaced by a block of code to add the interested users to the nosy list. We choose here to loop over all -new topics, than looping over all users, -and assign the user to the nosy list when the topic occurs in the user's +new keywords, than looping over all users, +and assign the user to the nosy list when the keyword occurs in the user's ``nosy_keywords``. The next part in ``updatenosy`` -- adding the author and/or recipients of a message to the nosy list -- is obviously not relevant here and is thus deleted from the new auditor. The last @@ -4299,7 +4298,7 @@ This results in the following function:: def update_kw_nosy(db, cl, nodeid, newvalues): - '''Update the nosy list for changes to the topics + '''Update the nosy list for changes to the keywords ''' # nodeid will be None if this is a new node current = {} @@ -4324,17 +4323,17 @@ if not current.has_key(value): current[value] = 1 - # add users with topic in nosy_keywords to the nosy list - if newvalues.has_key('topic') and newvalues['topic'] is not None: - topic_ids = newvalues['topic'] - for topic in topic_ids: + # add users with keyword in nosy_keywords to the nosy list + if newvalues.has_key('keyword') and newvalues['keyword'] is not None: + keyword_ids = newvalues['keyword'] + for keyword in keyword_ids: # loop over all users, - # and assign user to nosy when topic in nosy_keywords + # and assign user to nosy when keyword in nosy_keywords for user_id in db.user.list(): nosy_kw = db.user.get(user_id, "nosy_keywords") found = 0 for kw in nosy_kw: - if kw == topic: + if kw == keyword: found = 1 if found: current[user_id] = 1 @@ -4354,10 +4353,10 @@ Multiple additions When a user, after automatic selection, is manually removed from the nosy list, he is added to the nosy list again when the - topic list of the issue is updated. A better design might be - to only check which topics are new compared to the old list - of topics, and only add users when they have indicated - interest on a new topic. + keyword list of the issue is updated. A better design might be + to only check which keywords are new compared to the old list + of keywords, and only add users when they have indicated + interest on a new keyword. The code could also be changed to only trigger on the ``create()`` event, rather than also on the ``set()`` event, thus only setting @@ -4367,8 +4366,8 @@ In the auditor, there is a loop over all users. For a site with only few users this will pose no serious problem; however, with many users this will be a serious performance bottleneck. - A way out would be to link from the topics to the users who - selected these topics as nosy topics. This will eliminate the + A way out would be to link from the keywords to the users who + selected these keywords as nosy keywords. This will eliminate the loop over all users. Changes to Security and Permissions
--- a/doc/design.txt Fri Sep 14 15:55:25 2007 +0000 +++ b/doc/design.txt Sun Sep 16 02:45:11 2007 +0000 @@ -819,7 +819,7 @@ Class(db, "keyword", name=hyperdb.String()) Class(db, "issue", fixer=hyperdb.Multilink("user"), - topic=hyperdb.Multilink("keyword"), + keyword=hyperdb.Multilink("keyword"), priority=hyperdb.Link("priority"), status=hyperdb.Link("status")) @@ -1250,10 +1250,10 @@ clarity):: /issue?status=unread,in-progress,resolved& - topic=security,ui& + keyword=security,ui& :group=priority,-status& :sort=-activity& - :filters=status,topic& + :filters=status,keyword& :columns=title,status,fixer @@ -1274,11 +1274,11 @@ The example specifies an index of "issue" items. Only issues with a "status" of either "unread" or "in-progres" or "resolved" are displayed, -and only issues with "topic" values including both "security" and "ui" +and only issues with "keyword" values including both "security" and "ui" are displayed. The items are grouped by priority arranged in ascending order and in descending order by status; and within groups, sorted by activity, arranged in descending order. The filter section shows -filters for the "status" and "topic" properties, and the table includes +filters for the "status" and "keyword" properties, and the table includes columns for the "title", "status", and "fixer" properties. Associated with each issue class is a default layout specifier. The
--- a/doc/overview.txt Fri Sep 14 15:55:25 2007 +0000 +++ b/doc/overview.txt Sun Sep 16 02:45:11 2007 +0000 @@ -147,7 +147,7 @@ only sometimes fall into one category; often, a piece of information may be related to several concepts. -For example, forcing each item into a single topic +For example, forcing each item into a single keyword category is not just suboptimal but counterproductive: seekers of that item may expect to find it in a different category @@ -245,7 +245,7 @@ The *multilink* type is for a list of links to any number of other items in the in the database. A *multilink* property, for example, can be used to refer to related items -or topic categories relevant to an item. +or keyword categories relevant to an item. For Roundup, all items have four properties that are not customizable: @@ -314,13 +314,13 @@ # superseder = Multilink("issue") # (it also gets the Class properties creation, activity and creator) issue = IssueClass(db, "issue", - assignedto=Link("user"), topic=Multilink("keyword"), + assignedto=Link("user"), keyword=Multilink("keyword"), priority=Link("priority"), status=Link("status")) The **assignedto** property assigns responsibility for an item to a person or a list of people. -The **topic** property places the -item in an arbitrary number of relevant topic sets (see +The **keyword** property places the +item in an arbitrary number of relevant keyword sets (see the section on `Browsing and Searching`_). The **prority** and **status** values are initially: @@ -449,11 +449,11 @@ messages they might have missed. We can take this a step further and -permit users to monitor particular topics or classifications of items +permit users to monitor particular keywords or classifications of items by allowing other kinds of items to also have their own nosy lists. For example, a manager could be on the nosy list of the priority value item for "critical", or a -developer could be on the nosy list of the topic value item for "security". +developer could be on the nosy list of the keyword value item for "security". The recipients are then determined by the union of the nosy lists on the item and all the items it links to. @@ -552,7 +552,7 @@ (the filter selects the *intersection* of the sets of items associated with the active options) -For a *multilink* property like **topic**, +For a *multilink* property like **keyword**, one possibility is to show, as hyperlinks, the keywords whose sets have non-empty intersections with the currently displayed set of items. Sorting the keywords by popularity seems
--- a/doc/user_guide.txt Fri Sep 14 15:55:25 2007 +0000 +++ b/doc/user_guide.txt Sun Sep 16 02:45:11 2007 +0000 @@ -2,7 +2,7 @@ User Guide ========== -:Version: $Revision: 1.36 $ +:Version: $Revision: 1.37 $ .. contents:: @@ -112,7 +112,7 @@ Constrained (link and multilink) properties ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Fields like "Assigned To" and "Topics" hold references to items in other +Fields like "Assigned To" and "Keywords" hold references to items in other classes ("user" and "keyword" in those two cases.) Sometimes, the selection is done through a menu, like in the "Assigned @@ -130,13 +130,13 @@ match issues that are not assigned to a user. ``assignedto=2,3,40`` match issues that are assigned to users 2, 3 or 40. -``topic=user interface`` - match issues with the keyword "user interface" in their topic list -``topic=web interface,e-mail interface`` +``keyword=user interface`` + match issues with the keyword "user interface" in their keyword list +``keyword=web interface,e-mail interface`` match issues with the keyword "web interface" or "e-mail interface" in - their topic list -``topic=-1`` - match issues with no topics set + their keyword list +``keyword=-1`` + match issues with no keywords set Date properties @@ -350,10 +350,10 @@ (whitespace has been added for clarity):: /issue?status=unread,in-progress,resolved& - topic=security,ui& + keyword=security,ui& @group=priority,-status& @sort=-activity& - @filters=status,topic& + @filters=status,keyword& @columns=title,status,fixer
--- a/roundup/roundupdb.py Fri Sep 14 15:55:25 2007 +0000 +++ b/roundup/roundupdb.py Sun Sep 16 02:45:11 2007 +0000 @@ -16,7 +16,7 @@ # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. # -# $Id: roundupdb.py,v 1.132 2007-09-10 19:18:31 forsberg Exp $ +# $Id: roundupdb.py,v 1.133 2007-09-16 02:45:11 jpend Exp $ """Extending hyperdb with types specific to issue-tracking. """ @@ -142,10 +142,10 @@ # # Note that this list also includes properties # defined in the classic template: - # assignedto, topic, priority, status. + # assignedto, keyword, priority, status. ( ''"title", ''"messages", ''"files", ''"nosy", ''"superseder", - ''"assignedto", ''"topic", ''"priority", ''"status", + ''"assignedto", ''"keyword", ''"priority", ''"status", # following properties are common for all hyperdb classes # they are listed here to keep things in one place ''"actor", ''"activity", ''"creator", ''"creation",
--- a/scripts/import_sf.py Fri Sep 14 15:55:25 2007 +0000 +++ b/scripts/import_sf.py Sun Sep 16 02:45:11 2007 +0000 @@ -224,7 +224,7 @@ d['creator'] = users[artifact['submitted_by']] actor = d['creator'] if categories[artifact['category']]: - d['topic'] = [categories[artifact['category']]] + d['keyword'] = [categories[artifact['category']]] issue_journal.append(( d['id'], d['creation'].get_tuple(), d['creator'], "'create'", {} ))
--- a/templates/classic/html/help_controls.js Fri Sep 14 15:55:25 2007 +0000 +++ b/templates/classic/html/help_controls.js Sun Sep 16 02:45:11 2007 +0000 @@ -1,4 +1,4 @@ -// initial values for either Nosy, Superseder, Topic and Waiting On, +// initial values for either Nosy, Superseder, Keyword and Waiting On, // depending on which has called original_field = form[field].value;
--- a/templates/classic/html/issue.index.html Fri Sep 14 15:55:25 2007 +0000 +++ b/templates/classic/html/issue.index.html Sun Sep 16 02:45:11 2007 +0000 @@ -1,4 +1,4 @@ -<!-- $Id: issue.index.html,v 1.27 2006-11-09 01:26:28 richard Exp $ --> +<!-- $Id: issue.index.html,v 1.28 2007-09-16 02:45:11 jpend Exp $ --> <tal:block metal:use-macro="templates/page/macros/icing"> <title metal:fill-slot="head_title" > <span tal:omit-tag="true" i18n:translate="" >List of issues</span> @@ -29,7 +29,7 @@ <th tal:condition="request/show/creation" i18n:translate="">Creation</th> <th tal:condition="request/show/activity" i18n:translate="">Activity</th> <th tal:condition="request/show/actor" i18n:translate="">Actor</th> - <th tal:condition="request/show/topic" i18n:translate="">Topic</th> + <th tal:condition="request/show/keyword" i18n:translate="">Keyword</th> <th tal:condition="request/show/title" i18n:translate="">Title</th> <th tal:condition="request/show/status" i18n:translate="">Status</th> <th tal:condition="request/show/creator" i18n:translate="">Creator</th> @@ -55,8 +55,8 @@ tal:content="i/activity/reldate"> </td> <td class="date" tal:condition="request/show/actor" tal:content="python:i.actor.plain() or default"> </td> - <td tal:condition="request/show/topic" - tal:content="python:i.topic.plain() or default"> </td> + <td tal:condition="request/show/keyword" + tal:content="python:i.keyword.plain() or default"> </td> <td tal:condition="request/show/title"> <a tal:attributes="href string:issue${i/id}" tal:content="python:str(i.title.plain(hyperlink=0)) or '[no title]'">title</a>
--- a/templates/classic/html/issue.item.html Fri Sep 14 15:55:25 2007 +0000 +++ b/templates/classic/html/issue.item.html Sun Sep 16 02:45:11 2007 +0000 @@ -75,10 +75,10 @@ <tr> <th i18n:translate="">Assigned To</th> <td tal:content="structure context/assignedto/menu">assignedto menu</td> - <th i18n:translate="">Topics</th> + <th i18n:translate="">Keywords</th> <td> - <span tal:replace="structure context/topic/field" /> - <span tal:condition="context/is_edit_ok" tal:replace="structure python:db.keyword.classhelp(property='topic')" /> + <span tal:replace="structure context/keyword/field" /> + <span tal:condition="context/is_edit_ok" tal:replace="structure python:db.keyword.classhelp(property='keyword')" /> </td> </tr>
--- a/templates/classic/html/issue.search.html Fri Sep 14 15:55:25 2007 +0000 +++ b/templates/classic/html/issue.search.html Sun Sep 16 02:45:11 2007 +0000 @@ -50,10 +50,10 @@ <td> </td> </tr> -<tr tal:define="name string:topic; +<tr tal:define="name string:keyword; db_klass string:keyword; db_content string:name;"> - <th i18n:translate="">Topic:</th> + <th i18n:translate="">Keyword:</th> <td metal:use-macro="search_select"> <option metal:fill-slot="extra_options" value="-1" i18n:translate="" tal:attributes="selected python:value == '-1'">not selected</option>
--- a/templates/classic/schema.py Fri Sep 14 15:55:25 2007 +0000 +++ b/templates/classic/schema.py Sun Sep 16 02:45:11 2007 +0000 @@ -71,7 +71,7 @@ # superseder = Multilink("issue") issue = IssueClass(db, "issue", assignedto=Link("user"), - topic=Multilink("keyword"), + keyword=Multilink("keyword"), priority=Link("priority"), status=Link("status"))
--- a/templates/minimal/html/help_controls.js Fri Sep 14 15:55:25 2007 +0000 +++ b/templates/minimal/html/help_controls.js Sun Sep 16 02:45:11 2007 +0000 @@ -1,4 +1,4 @@ -// initial values for either Nosy, Superseder, Topic and Waiting On, +// initial values for either Nosy, Superseder, Keyword and Waiting On, // depending on which has called original_field = form[field].value;
--- a/test/test_cgi.py Fri Sep 14 15:55:25 2007 +0000 +++ b/test/test_cgi.py Sun Sep 16 02:45:11 2007 +0000 @@ -8,7 +8,7 @@ # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # -# $Id: test_cgi.py,v 1.31 2007-09-12 21:11:14 jpend Exp $ +# $Id: test_cgi.py,v 1.32 2007-09-16 02:45:11 jpend Exp $ import unittest, os, shutil, errno, sys, difflib, cgi, re @@ -213,8 +213,8 @@ self.assertEqual(id,'1') id = self.db.keyword.create(name='1') self.assertEqual(id,'2') - issue = self.db.issue.create(title='i1-status1', topic=['1']) - self.assertEqual(self.db.issue.get(issue,'topic'),['1']) + issue = self.db.issue.create(title='i1-status1', keyword=['1']) + self.assertEqual(self.db.issue.get(issue,'keyword'),['1']) self.assertEqual(self.db.keyword.lookup('1'),'2') self.assertEqual(self.db.keyword.lookup('2'),'1') form = cgi.FieldStorage() @@ -224,9 +224,9 @@ cl.db = self.db cl.userid = '1' item = HTMLItem(cl, 'issue', issue) - for topic in item.topic: - self.assertEqual(topic.id, '1') - self.assertEqual(topic.name, '2') + for keyword in item.keyword: + self.assertEqual(keyword.id, '1') + self.assertEqual(keyword.name, '2') def testFileUpload(self): file = FileUpload('foo', 'foo.txt')
