From b78cacf7adbe799581db77bcc913801029d8e48d Mon Sep 17 00:00:00 2001 From: richard Date: Fri, 12 Sep 2003 04:29:35 +0000 Subject: [PATCH] new example and some more installation docs git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@1875 57a73879-2fb5-44c3-a270-3262357dd7e2 --- doc/customizing.txt | 168 ++++++++++++++++++++++++++++++++++++++++++- doc/installation.txt | 19 ++++- 2 files changed, 185 insertions(+), 2 deletions(-) diff --git a/doc/customizing.txt b/doc/customizing.txt index 120eaff..7142592 100644 --- a/doc/customizing.txt +++ b/doc/customizing.txt @@ -2,7 +2,7 @@ Customising Roundup =================== -:Version: $Revision: 1.97 $ +:Version: $Revision: 1.98 $ .. This document borrows from the ZopeBook section on ZPT. The original is at: http://www.zope.org/Documentation/Books/ZopeBook/current/ZPT.stx @@ -3349,6 +3349,172 @@ on it (i.e. it's in their blockers list) you can look at the journal 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 +--------------------------------------------- + +We need the ability to automatically add users to the nosy list based +on the occurence of a topic. Every user should be allowed to edit his +own list of topics for which he wants to be added to the nosy list. + +Below will be showed that such a change can be performed with only +minimal understanding of the roundup system, but with clever use +of 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 +be put on the nosy list, a change in the user view allowing 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 in the database to make 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`` seem to fullfill this (note that within +the code topics are called ``keywords``.) As such, all what has to be +done is to add a new field to the definition of ``user`` within the +file ``dbinit.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(), + address=String(), realname=String(), + phone=String(), organisation=String(), + alternate_addresses=String(), + queries=Multilink('query'), roles=String(), + 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 +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 easily can +see that the topic field in the issue view has very similar editting +requirements as our nosy topics, both being a list of topics. As +such, we search for Topics 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):: + + + Nosy Topics + + + + + + + +Addition of an auditor to update the nosy list +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The more difficult part is the addition of the logic to actually +at the users to the nosy list when it is required. +The choice is made to perform this action when the topics on an +item are set, including when an item is created. +Here we choose to start out with a copy of the +``detectors/nosyreaction.py`` detector, which we copy to the file +``detectors/nosy_keyword_reaction.py``. +This looks like a good start as it also adds users +to the nosy list. A look through the code reveals that the +``nosyreaction`` function actually is sending the e-mail, which +we do not need. As such, we can change the init function to:: + + def init(db): + db.issue.audit('create', update_kw_nosy) + db.issue.audit('set', update_kw_nosy) + +After that we rename the ``updatenosy`` function to ``update_kw_nosy``. +The first two blocks of code in that function relate to settings +``current`` to a combination of the old and new nosy lists. This +functionality is left in the new auditor. The following block of +code, which in ``updatenosy`` handled adding the assignedto user(s) +to the nosy list, 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 loop over all users, +and assign the user to the nosy list when the topic in the user's +nosy_keywords. The next part in ``updatenosy``, adding the author +and/or recipients of a message to the nosy list, obviously is not +relevant here and thus is deleted from the new auditor. The last +part, copying the new nosy list to newvalues, does not have to be changed. +This brings the following function:: + + def update_kw_nosy(db, cl, nodeid, newvalues): + '''Update the nosy list for changes to the topics + ''' + # nodeid will be None if this is a new node + current = {} + if nodeid is None: + ok = ('new', 'yes') + else: + ok = ('yes',) + # old node, get the current values from the node if they haven't + # changed + if not newvalues.has_key('nosy'): + nosy = cl.get(nodeid, 'nosy') + for value in nosy: + if not current.has_key(value): + current[value] = 1 + + # if the nosy list changed in this transaction, init from the new value + if newvalues.has_key('nosy'): + nosy = newvalues.get('nosy', []) + for value in nosy: + if not db.hasnode('user', value): + continue + 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: + # loop over all users, + # and assign user to nosy when topic 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: + found = 1 + if found: + current[user_id] = 1 + + # that's it, save off the new nosy list + newvalues['nosy'] = current.keys() + +and these two function are the only ones needed in the file. + +TODO: update this example to use the find() Class method. + +Caveats +~~~~~~~ + +A few problems with the design here can be noted: + +Multiple additions + When a user, after automatic selection, is manually removed + from the nosy list, he again is added to the nosy list 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. + + The code could also be changed to only trigger on the create() event, + rather than also on the set() event, thus only setting the nosy list + when the issue is created. + +Scalability + 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 will be to link from the topics to the users which + selected these topics a nosy topics. This will eliminate the + loop over all users. ------------------- diff --git a/doc/installation.txt b/doc/installation.txt index ff3c053..17442e4 100644 --- a/doc/installation.txt +++ b/doc/installation.txt @@ -2,7 +2,7 @@ Installing Roundup ================== -:Version: $Revision: 1.57 $ +:Version: $Revision: 1.58 $ .. contents:: @@ -326,6 +326,23 @@ name=home values on the command-line after all the other options. To make the server run in the background, use the "-d" option, specifying the name of a file to write the server process id (pid) to. +To run the server proxied through apache (to take advantage of SSL or other +apache features), use the following configuration lines:: + + LoadModule proxy_module libexec/apache2/mod_proxy.so + LoadModule proxy_connect_module libexec/apache2/mod_proxy_connect.so + LoadModule proxy_http_module libexec/apache2/mod_proxy_http.so + + + ProxyPass http://192.168.1.2:9090/roundup/ + AuthType Basic + AuthName Roundup + AuthUserFile /some/place/htpasswd + Require valid-user + + +Changing the ProxyPass line to point to the server you're running. + Zope Product - ZRoundup ~~~~~~~~~~~~~~~~~~~~~~~ -- 2.30.2