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")