From: richard Date: Fri, 26 Mar 2004 04:50:51 +0000 (+0000) Subject: - queries on a per-user basis, and public queries (sf "bug" 891798 :) X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=a1ad36d2123d336983fe7df47f8f7f0aff2ba9c2;p=roundup.git - queries on a per-user basis, and public queries (sf "bug" 891798 :) - EditAction was confused about who "self" was - Edit collision detection was broken for index-page edits git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@2204 57a73879-2fb5-44c3-a270-3262357dd7e2 --- diff --git a/CHANGES.txt b/CHANGES.txt index b00dbb9..952d337 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -10,11 +10,14 @@ Feature: - added Reject exception which may be raised by auditors. This is trapped by mailgw and may be used to veto creation of file attachments or messages. (sf bug 700265) +- queries on a per-user basis, and public queries (sf "bug" 891798 :) Fixed: - Boolean HTML templating was broken - Link HTML templating field() was broken - Fix reporting of test inclusion in postgresql test +- EditAction was confused about who "self" was +- Edit collision detection was broken for index-page edits 2004-03-24 0.7.0b1 diff --git a/doc/upgrading.txt b/doc/upgrading.txt index dbd01ad..ec390de 100644 --- a/doc/upgrading.txt +++ b/doc/upgrading.txt @@ -9,36 +9,76 @@ accordingly. Note that there is information about upgrade procedures in the .. contents:: - -Migrating from 0.7 to 0.8 +Migrating from 0.6 to 0.7 ========================= -0.8.0 Added Dispatcher role ---------------------------- +0.7.0 Saving and sharing of user queries +---------------------------------------- -A new config option has been added. There is a 'role' that can be filled, -that of the 'dispatcher'. This person acts as a central sentinel for issues -coming into the system. You can configure it so that all e-mail error messages -get bounced to them, them and the user in question, or just the user (default). +Due to popular demand, the user query saving mechanisms have been +overhauled. This means that queries remember the user that created them +and they may be marked as being private for a particular user. -To toggle these switches, look at the new classic and minimal config.py's, -specifically: +You *are not required* to make these changes. You only need to make them +if you wish to use the new query editing features. It's highly +recommended, as the effort is minimal. +1. You will need to edit your tracker's ``dbinit.py`` to change the way + queries are stored. Change the lines:: -# The 'dispatcher' is a role that can get notified of new items to the database. -DISPATCHER_EMAIL = ADMIN_EMAIL + query = Class(db, "query", + klass=String(), name=String(), + url=String()) + query.setkey("name") -... + to:: + query = Class(db, "query", + klass=String(), name=String(), + url=String(), private_for=Link('user')) -# Send error messages to the dispatcher, user, or both? -# If 'dispatcher', error message notifications will only be sent to the dispatcher. -# If 'user', error message notifications will only be sent to the user. -# If 'both', error message notifications will be sent to both individuals. -ERROR_MESSAGES_TO = 'user' + That is, add the "private_for" property, and remove the line that says + ``query.setkey("name")``. The latter is the most important edit here. + +2. You will also need to copy the ``query.edit.html`` template page from the + ``templates/classic/html/`` directory of the source to your tracker's + ``html`` directory. + +3. Once you've done that, edit the tracker's ``page.html`` template to + change:: + + +

+ Your Queries
+ + + to:: + + +

+ Your Queries (edit)
+ + + That is, you're removing the ``tal:condition`` and adding a link to the + new edit page. + +4. You might also wish to remove the redundant query editing section from the + ``user.item.html`` page. + + +0.7.0 Added Dispatcher role +--------------------------- + +A new config option has been added that specifies the email address of +a "dispatcher" role. This email address acts as a central sentinel for +issues coming into the system. You can configure it so that all e-mail +error messages get bounced to them, them and the user in question, or +just the user (default). + +To toggle these switches, add the "DISPATCHER_EMAIL" and +"ERROR_MESSAGES_TO" configuration values to your tracker's ``config.py``. +See the `customisation documentation`_ for how to use them. -Migrating from 0.6 to 0.7 -========================= 0.7.0 Added CSV export action ----------------------------- diff --git a/doc/user_guide.txt b/doc/user_guide.txt index cf33487..19f4414 100644 --- a/doc/user_guide.txt +++ b/doc/user_guide.txt @@ -2,7 +2,7 @@ User Guide ========== -:Version: $Revision: 1.25 $ +:Version: $Revision: 1.26 $ .. contents:: @@ -245,6 +245,24 @@ See `entering values in your tracker`_ for an explanation of what you may type into the search form. +Saving queries +~~~~~~~~~~~~~~ + +You may save queries in the tracker by giving the query a name. Each user +may only have one query with a given name - if a subsequent search is +performed with the same query name supplied, then it will edit the +existing query of the same name. + +Queries may be marked as "private". These queries are only visible to the +user that created them. If they're not marked "private" then all other +users may include the query in their list of "Your Queries". Marking it as +private at a later date does not affect users already using the query, nor +does deleting the query. + +If a user subsequently creates or edits a public query, a new personal +version of that query is made, with the same editing rules as described +above. + Under the covers ~~~~~~~~~~~~~~~~ diff --git a/roundup/cgi/actions.py b/roundup/cgi/actions.py index 529bfac..481a971 100755 --- a/roundup/cgi/actions.py +++ b/roundup/cgi/actions.py @@ -1,4 +1,4 @@ -#$Id: actions.py,v 1.16 2004-03-26 00:46:33 richard Exp $ +#$Id: actions.py,v 1.17 2004-03-26 04:50:50 richard Exp $ import re, cgi, StringIO, urllib, Cookie, time, random @@ -134,14 +134,36 @@ class SearchAction(Action): # query string. url = req.indexargs_href('', {})[1:] - # handle editing an existing query - try: - qid = self.db.query.lookup(queryname) - self.db.query.set(qid, klass=self.classname, url=url) - except KeyError: - # create a query - qid = self.db.query.create(name=queryname, - klass=self.classname, url=url) + key = self.db.query.getkey() + if key: + # edit the old way, only one query per name + try: + qid = self.db.query.lookup(queryname) + self.db.query.set(qid, klass=self.classname, url=url) + except KeyError: + # create a query + qid = self.db.query.create(name=queryname, + klass=self.classname, url=url) + else: + # edit the new way, query name not a key any more + # see if we match an existing private query + uid = self.db.getuid() + qids = self.db.query.filter({}, {'name': queryname, + 'private_for': uid}) + if not qids: + # ok, so there's not a private query for the current user + # - see if there's a public one created by them + qids = self.db.query.filter({}, {'name': queryname, + 'private_for': -1, 'creator': uid}) + + if qids: + # edit query + qid = qids[0] + self.db.query.set(qid, klass=self.classname, url=url) + else: + # create a query + qid = self.db.query.create(name=queryname, + klass=self.classname, url=url, private_for=uid) # and add it to the user's query multilink queries = self.db.user.get(self.userid, 'queries') @@ -435,23 +457,21 @@ class _EditAction(Action): return cl.create(**props) class EditItemAction(_EditAction): - def lastUserActivity(self): + def lastUserActvity(self): if self.form.has_key(':lastactivity'): - return date.Date(self.form[':lastactivity'].value) + user_actvity = date.Date(self.form[':lastactivity'].value) elif self.form.has_key('@lastactivity'): - return date.Date(self.form['@lastactivity'].value) + user_actvity = date.Date(self.form['@lastactivity'].value) else: return None def lastNodeActivity(self): cl = getattr(self.client.db, self.classname) - return cl.get(self.nodeid, 'activity') + node_activity = cl.get(self.nodeid, 'activity') - def detectCollision(self, userActivity, nodeActivity): - # Result from lastUserActivity may be None. If it is, assume there's no - # conflict, or at least not one we can detect. - if userActivity: - return userActivity < nodeActivity + def detectCollision(self, user_actvity, node_activity): + if user_activity: + return user_activity < node_activity def handleCollision(self): self.client.template = 'collision' @@ -462,7 +482,9 @@ class EditItemAction(_EditAction): See parsePropsFromForm and _editnodes for special variables. """ - if self.detectCollision(self.lastUserActivity(), self.lastNodeActivity()): + user_activity = self.lastUserActvity() + if user_activity and self.detectCollision(user_activity, + self.lastNodeActivity()): self.handleCollision() return @@ -488,7 +510,7 @@ class EditItemAction(_EditAction): url += '?@ok_message=%s&@template=%s'%(urllib.quote(message), urllib.quote(self.template)) if self.nodeid is None: - req = templating.HTMLRequest(self) + req = templating.HTMLRequest(self.client) url += '&' + req.indexargs_href('', {})[1:] raise Redirect, url diff --git a/roundup/cgi/templating.py b/roundup/cgi/templating.py index ec223d9..da9d29e 100644 --- a/roundup/cgi/templating.py +++ b/roundup/cgi/templating.py @@ -124,7 +124,7 @@ class Templates: raise if self.templates.has_key(src) and \ - stime < self.templates[src].mtime: + stime <= self.templates[src].mtime: # compiled template is up to date return self.templates[src] @@ -134,7 +134,7 @@ class Templates: content_type = mimetypes.guess_type(filename)[0] or 'text/html' pt.pt_edit(open(src).read(), content_type) pt.id = filename - pt.mtime = time.time() + pt.mtime = stime return pt def __getitem__(self, name): @@ -195,6 +195,7 @@ class RoundupPageTemplate(PageTemplate.PageTemplate): 'tracker': client.instance, 'utils': utils(client), 'templates': Templates(client.instance.config.TEMPLATES), + 'template': self, } # add in the item if there is one if client.nodeid: @@ -644,6 +645,10 @@ class HTMLItem(HTMLInputMixin, HTMLPermissions): def designator(self): """Return this item's designator (classname + id).""" return '%s%s'%(self._classname, self._nodeid) + + def is_retired(self): + """Is this item retired?""" + return self._klass.is_retired(self._nodeid) def submit(self, label="Submit Changes"): """Generate a submit button. @@ -1505,6 +1510,7 @@ class MultilinkHTMLProperty(HTMLProperty): ''' Support the "in" operator. We have to make sure the passed-in value is a string first, not a HTMLProperty. ''' + print (self, value, self._value) return str(value) in self._value def reverse(self): diff --git a/templates/classic/dbinit.py b/templates/classic/dbinit.py index 2e8c474..f38dcab 100644 --- a/templates/classic/dbinit.py +++ b/templates/classic/dbinit.py @@ -15,7 +15,7 @@ # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. # -# $Id: dbinit.py,v 1.6 2004-03-15 05:51:23 richard Exp $ +# $Id: dbinit.py,v 1.7 2004-03-26 04:50:50 richard Exp $ import os @@ -54,8 +54,7 @@ def open(name=None): query = Class(db, "query", klass=String(), name=String(), - url=String()) - query.setkey("name") + url=String(), private_for=Link('user')) # add any additional database schema configuration here diff --git a/templates/classic/html/_generic.collision.html b/templates/classic/html/_generic.collision.html index fd2cc2b..34dbece 100644 --- a/templates/classic/html/_generic.collision.html +++ b/templates/classic/html/_generic.collision.html @@ -8,4 +8,5 @@ editing. Please reload the node and review your edits. - \ No newline at end of file + + diff --git a/templates/classic/html/page.html b/templates/classic/html/page.html index 916d35f..cf35212 100644 --- a/templates/classic/html/page.html +++ b/templates/classic/html/page.html @@ -25,8 +25,8 @@ -

- Your Queries
+

+ Your Queries (edit)
link
@@ -149,3 +149,4 @@ tal:attributes="value name; checked python:name == group_on"> + diff --git a/templates/classic/html/query.edit.html b/templates/classic/html/query.edit.html new file mode 100644 index 0000000..c37a89f --- /dev/null +++ b/templates/classic/html/query.edit.html @@ -0,0 +1,105 @@ + + + +<span tal:replace="config/TRACKER_NAME" />: "Your Queries" Editing + + + "Your Queries" Editing + + + + + +You are not allowed to edit queries. + + + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
QueryInclude in "Your Queries"EditPrivate to you? 
query + + + [query is retired]
query + + edit + + + +
query + [not yours to edit]
+ + + +
+ +
+ + diff --git a/templates/classic/html/user.item.html b/templates/classic/html/user.item.html index 2410b2c..dae4b73 100644 --- a/templates/classic/html/user.item.html +++ b/templates/classic/html/user.item.html @@ -78,21 +78,6 @@ You are not allowed to view this page. - - - - - - - - -
Queries
NameActions
- display - - remove -
-
realname