On Dec 12, 2005, at 10:48 AM, Lee McFadden wrote:

Basically I want/need three urls for each unique file.

/pickup/<id> - The basic starting point.
/pickup/<id>/recipient - A page for the user to enter their email address
/pickup/<id>/download - The method that streams the download

I can't get that working.  I have to settle for:

/pickup/<id>
/pickup/recipient/<id>
/pickup/download/<id>

Am I just being too picky with my URLs?  It works better in my brain
the first way around.

I have a post yesterday that describes how to get the url scheme you list above: http://tinyurl.com/b833k

It takes writing the 'default' method for your controller and is a modification of a cherrypy recipe at < http://www.cherrypy.org/wiki/ RestfulResource >. We're using it here at work and it works like a charm. Though, I found a slight bug in it since posting, so I've posted the full solution again below.

But, seeing that CherryPy 2.2 will have this turned on by default might make it a moot point...

--Tracy


#
# controllers.py
#

import turbogears
import cherrypy
from resource import Resource  # see the resource.py code below...

class Pages(Resource):
     db_modelname = 'pages'

     @turbogears.expose(html="...path to template...")
     def show(self, obj):
         return dict(ID=obj.id, name=obj.name)  # etc

     @turbogears.expose()
     def add(self, obj, **kw):
         if cherrypy.request.method != 'POST':
             raise cherrypy.HTTPError(500, "No you don't...")
         # do your pages-specific add work here...
         return dict(success=True)  # or whatever you want

class Root(controllers.Root):
     pages = Pages()

#
# resource.py
#

from sqlobject import SQLObjectNotFound
import turbogears
from turbogears import controllers
import model

class Resource(controllers.Root):
     db_modelname = ''  # override this in child resources

     @turbogears.expose()
     def default(self, *vpath, **params):
         if not vpath:
             return self.index(**params)
         # Make a copy of vpath in a list
         vpath = list(vpath)
         atom = vpath.pop(0)

         # See if the first virtual path member is a container action
         method = getattr(self, atom, None)
         if method and getattr(method, "exposed"):
             return method(*vpath, **params)

         # Not a container action; the URI atom must be an existing ID
         # Coerce the ID to the correct db type
         ID = int(atom)
         try:
             obj = getattr(model, self.db_modelname).get(ID)
         except SQLObjectNotFound:
             raise cherrypy.NotFound

         # There may be further virtual path components.
         # Try to map them to methods in this class.
         if vpath:
             method = getattr(self, vpath[0], None)
             if method and getattr(method, "exposed"):
                 return method(obj, *vpath[1:], **params)
             else:
                 raise cherrypy.NotFound

         # No further known vpath components. Call a default handler.
         return self.show(obj, *vpath, **params)

     @turbogears.expose()
     def show(self, obj):
         raise NotImplemented("you must define your own 'show' method")




Reply via email to