Welcome to WebUndo’s documentation!

This module implements Gmail’s undo/cancel features, using Pylons or some other web frameworks.

Here is a sample Pylons controller (called ‘th’, who knows why):

from pylons import request, response, session, tmpl_context as c
from YOURPROJECT.lib.base import BaseController, render
from routes import url_for

import webundo

class ThController(BaseController):
    def index(self):
        return render('th.mako')

    def save(self):
        # save the thing
        req = request
        def save():
            print "Writing to file..."
            open('/tmp/dump.txt', 'w').write(req.params.get('stuff'))
        c.key = webundo.launch_cancelable_job(save, 3)
        return render('saving.mako')
    def cancel(self, id):
        if webundo.cancel_job(id):
            return "Thread cancelled successfully"
        else:
            return "Too late, thread finished already."

    def publish(self):
        req = request
        def unpublish():
            print "Oops, let's unpublish", req.params.get('stuff')
            return "We're done"
        c.key = webundo.launch_undoable_job(unpublish, 10)
        c.published = request.params.get('stuff')
        print "Published stuff", c.published
        return render('publishing.mako')

    def undo(self, id):
        try:
            ret = undo_job(id)
        except webundo.ThreadLostError, e:
            return "Thread was lost already"
        return "Undone: %s" % ret

With th.mako being:

<p>Save something, with cancel support:</p>
<form action="${h.url_for(controller='th', action='save')}" id="" method="post">
  <input type="text" name="stuff" value="somevalue" />
  <input type="submit" name="" value="SEND" />
</form>

<p>Publish something, with undo support:</p>
<form action="${h.url_for(controller='th', action='publish')}" id="" method="post">
  <input type="text" name="stuff" value="somevalue" />
  <input type="submit" name="" value="SEND" />
</form>

This shows off a cancelable job and an undoable job. See the original blog post for more details.

webundo.unproxy_closure(func)

Rewrite function with resolved closure references to proxy objects.

It works with objects like StackedObjectProxy from Paste, which have a _current_obj() method.

It could be extended to other frameworks or objects.

This function is called automatically by launch_cancelable_job and launch_undoable_job if the unproxy parameter is True.

webundo.launch_cancelable_job(func, timeout, unproxy=True)

Launch a new cancellable thread, and execute only after the timeout.

This means, if someone calls cancel_job, the function will never be executed.

If you’re using Pylons, it’s safer to keep unproxy to True, in case you close-in Pylons’ globals variables (request, response, app_globals, etc.). For other frameworks, it won’t hurt to leave it on, it’s a tiny overhead.

Parameters:
  • func – timed function to execute after timeout
  • timeout – timeout in seconds
  • unproxy – whether to clean up the func of closed-in proxy objects
Returns:

UUID-key for the launched job, use when calling cancel_job

webundo.launch_undoable_job(func, timeout, unproxy=True)

Launch a thread with an undo function. The function will be called only on request through a call to undo_job(), otherwise, it will vanish.

See notes on unproxy in doc. for launch_cancelable_job. Same applies here.

Parameters:
  • func – called if undo_job() is called for this job’s key.
  • timeout – timeout in seconds
  • unproxy – whether to clean up the func of closed-in proxy objects
Returns:

UUID-key of this job, use when calling undo_job.

webundo.cancel_job(key)

Cancel a job launched with launch_cancelable_job

Parameter:key – uuid returned by a previous call to launch_cancelable_job
Returns:True if we could cancel the job, False if you were too late
webundo.undo_job(key, timeout=None)

Launch the undo function waiting in the thread associated with key``and wait for that function's return value for ``timeout seconds.

If the other thread was timed out, the undo function will not be available to trigger anymore, and a ThreadLostError exception will be raised.

Parameters:
  • key – uuid-key returned by launch_undoable_job. Can’t be mixed with cancelable jobs.
  • timeout – timeout in seconds.
Returns:

value returned by the function passed to launch_undoable_job.

Raises ThreadLostError:
 

if the timeout was elapsed, meaning you couldn’t undo anymore.

Contents:

Indices and tables

Table Of Contents

This Page