[TurboGears] Re: Adding transactions to @expose

2005-11-17 Thread Sean Cazzell

On Wed, 2005-11-16 at 13:45 -0500, Jonathan LaCour wrote:
 Given that this is also possible, it seems like there are several  
 different ways to do this off the top of my head:
 
1. WSGI middleware (I think)
2. CherryPy filters
3. SQLObject modifications
4. Decorators
5. Some mixture of the above


1. Unfortunately, CherryPy really only has very basic WSGI support - I
don't know of any reasonable way to hook WSGI middleware up to Cherrypy
at this point (maybe in a future release).

2. Filters in CherryPy won't work either, they don't allow you to wrap
the request and I don't think there is any way to guarantee that they
are actually run - especially if an exception occurs.

3. SQLObject modifications would be great, but until they are done we'll
need to have an interim solution.

4. Which leaves decorators.  My plan now is to implement a transaction
decorator which will look something like:

def in_transaction(func):
hub = AutoConnectHub()
def newfunc(*args, **kw):
hub.begin()
try:
func(*args, **kw)
except cherrypy.HTTPRedirect:
hub.commit()
raise
except:
hub.rollback()
raise
else:
hub.commit()
newfunc.func_name = func.func_name
newfunc.func_doc = func.func_doc
return newfunc

The expose decorator will check the config / it's parameters and if a
transaction is desired it will wrap itself in the in_transaction
decorator.

This doesn't give us strict per-request transactions if you have
database code in your cherrypy filters.  But I think any database code
in filters would probably mostly be doing reads, so this doesn't seem to
be a huge issue.  It is probably possible to monkeypatch CherryPy to
give us true per-request transactions if we really need them.

The AutoConnectHub.begin method checks to see if we're already in a
transaction, so calling one transaction-wrapped method from another will
result in them both running in one transaction.  I think this is the
desired default behavior.

If you need more transaction stuff beyond this, you can always write
your own decorators to do things like nested transactions.  And if there
is enough demand we can add support for such things to TG in the future.

Of course, if you want you can disable all of this automatic transaction
stuff in the config and handle transactions yourself or not use
transactions / database at all.


Sean Cazzell






[TurboGears] Re: validation_error is going away right?

2005-11-17 Thread Sean Cazzell

JW,

That is in SVN now - if your method has a has_errors var it will get
called instead of validate_error.


Sean Cazzell

On Thu, 2005-11-17 at 17:02 +, [EMAIL PROTECTED] wrote:
 I read in a post that validation_error was going away.
 
 Kevin said, That's a good point. If we deprecate validation_error,
 then the method
 can just be called directly and you can check form_errors to see if
 there's a problem. I think this also means that an invalid exception
 would never be raised.
 
 It simplifies the code, but it does also eliminate a visual reminder
 to check for errors. Maybe that's not so bad, though. 
 
 The idea being that the method being called would receive a has_errors
 argument.  The example Kevin gave is below:
 
 @turbogears.expose(input_form=myform)
 def save(self, name, address, age, has_errors):
 if has_errors:
 return self.index()
 
 Did this change ever make it into turbo-gears?  I've been playing with
 validators and have really grown to not like the validation_error
 method of dealing with problems :).
 
 I'd really like to know what the new-method will be, if there is going
 to be one.
 
 Thanks,
 jw
 



[TurboGears] Re: Wonky internet

2005-11-17 Thread Sean Cazzell

Speaking of internet connections - I am going to be out of town until
Sunday, on vacation at a place with *no* internet connection, so I'll
have to get caught up on the list Sunday night.

I'm pretty close to having something ready to commit on the new expose
decorator front.  Things will be fully backwards compatible (expose will
still accept and process validators and inputform args).  The big
changes are splitting the validators and inputform stuff out of expose
into other decorators and adding implicit transaction support to expose.

I'll throw up some docs on the wiki prior to committing.

Have a nice weekend everyone.


Sean Cazzell




On Thu, 2005-11-17 at 09:15 -0500, Kevin Dangoor wrote:
 My internet connection is acting up, and they wont be able to get a
 tech out until tomorrow (Friday) morning. That means email from me
 will be extra sporadic.
 
 Also, next week my email availability will be very spotty.
 
 I'm going to try to spot and reply to messages about 0.9 development
 as top priority.
 
 Kevin
 
 --
 Kevin Dangoor
 Author of the Zesty News RSS newsreader
 
 email: [EMAIL PROTECTED]
 company: http://www.BlazingThings.com
 blog: http://www.BlueSkyOnMars.com



[TurboGears] Re: Adding transactions to @expose

2005-11-17 Thread Sean Cazzell

On Thu, 2005-11-17 at 12:28 -0500, Kevin Dangoor wrote:
 Unfortunately, it really needs to use the hub that's in use by the
 model classes... from a random model.py:
 
 __connection__ = AutoConnectHub()
 # (or PackageHub)
 
 class Foo(SQLObject):
 ...
 
 In a multi-application world, it'll be possible to have different
 parts of a site going to different databases. that won't be the common
 case, though.
 
 Sticking to the common case, we just need a nice way to get ahold of
 the hub in question. There are probably a small handful of ways we
 could find the model module and get the hub from it. Unfortunately,
 I'm out of time for exploring that now, and I'll be offline for a
 while. I hope I'll be able to get back online at least briefly later
 today...

Kevin, I was worried that I might have to get the hub from the model.  I
would definitely like to support the multiple-apps case if at all
possible.

I have to take off as well, I'll look into this more Sunday when I get
home.


Sean




[TurboGears] Adding transactions to @expose

2005-11-15 Thread Sean Cazzell

There has been a lot of interest on the list of having a way to
automatically wrap a request in a transaction.  The most obvious way to
do this is to add it into expose.  Michele has done a great job putting
together the relevant information (with suggestions from Ian Bicking) on
ticket #80 here:

http://trac.turbogears.org/turbogears/ticket/80

Since I am already doing some hacking on expose (moving the validator
and inputform functionality out to separate decorators) I thought I'd
pick this one up.

My question is - do we want this on by default, or do we want to
explicitly enable it with a parameter to expose?

Enabled by default (must explicitly disable):
@expose(transaction=False)

Disabled by default (must explicitly enable):
@expose(transaction=True)

Obviously the latter is backwards compatible, but if everyone is going
to want a transaction for all of their controller methods, maybe it
should be enabled by default?


Sean 



[TurboGears] Re: Adding transactions to @expose

2005-11-15 Thread Sean Cazzell

On Tue, 2005-11-15 at 17:31 -0500, Jonathan LaCour wrote:
 Maybe this could be handled sort of like validators?
 
  @turbogears.expose(transaction=True,
 err_map={Exception : 'generic msg',
  SQLObjectNotFound : 'specific msg'}
  def my_method(self):
  frob = frobbler.frobble()
  return dict(frob=frob)
 
 On an exception being raised, the transaction would automatically be  
 rolled back, and the appropriate error message would be flashed on  
 the page.  Just thinking out loud, and this obviously isn't perfect.   
 But, its an important wrinkle to figure out.

I would recommend you put this in a separate decorator like this:

@turbogears.expose(...)
@exception_flash({Exception: 'generic msg'})
def mymethod(self):
   ... etc ...

It may be cool to have an exception_flash decorator built in to
turbogears.  Though I really wish cherrypy had an event system or better
filtering system so we didn't have to push all of this functionality
into decorators.


Sean



[TurboGears] Re: Adding transactions to @expose

2005-11-15 Thread Sean Cazzell

On Tue, 2005-11-15 at 16:34 -0600, Ian Bicking wrote:
 I think expected exceptions (including redirects) should not roll back 
 the transaction.  Unexcepted exceptions (everything else should). 
 However, you should be able to explicitly roll back or commit the 
 transaction if the decorator doesn't do what you want.

See, I knew I was forgetting something.  I wonder what a reasonable list
of expected exceptions that we don't rollback on is?  It should
probably be short, I don't want to not rollback if someone is expecting
it.  I agree with Ian on:

cherrypy.HTTPRedirect

What about:

cherrypy.NotFound
cherrypy.HTTPError
cherrypy.InternalRedirect

I think we should include InternalRedirect and not the other two.  The
list of cherrypy errors can be found in _cperror.py.


Sean Cazzell



[TurboGears] Re: The Feed object

2005-11-12 Thread Sean Cazzell

Evelind,

Looks great!  I am +1 on Michele's suggestion to call it FeedController.
Also, Entrys should probably be Entries?

What do you think about making the title, link, description and such
attributes like:

class MyFeed(Feed):
title = My Simple Feed
link = http://www.example.com/feed;
description = This is my really simple feed.

def items(self):
# ... return list of feed entry dict's here


My only reason to suggest this is to break up get_feed_data into logical
parts so you don't have one monolithic function to generate a feed.  If
anyone needs to run code to determine the feed title / link / etc at
runtime, they can use properties.


Sean Cazzell






On Sat, 2005-11-12 at 10:32 +0100, Elvelind Grandin wrote:
 With version 0.9 turbogears will support easy generating of rss/atom feeds.
 There still some stuff to add like knowledge of wich elements are valid etc.
 But here is a quicklook at how it looks like now.
 http://trac.turbogears.org/turbogears/wiki/FeedObject#preview
 
 Any suggestions on features or syntax are more than welcome
 
 
 --
 cheers
 elvelind grandin



[TurboGears] Re: TurboGears books update

2005-11-12 Thread Sean Cazzell

Kevin,

Thanks for the update!  

Is there any possibility of any of these books being published for free
on the web?  I have co-authored a couple books (one was even
published :P) so I appreciate the work that goes into it (and the need
to get paid for all of that time), but an online book could be a great
resource.


Sean Cazzell


On Sat, 2005-11-12 at 08:15 -0500, Kevin Dangoor wrote:
 There was a lot of discussion last week about a TurboGears book, so
 clearly there's a lot of interest in it. There's nothing official to
 announce, but I wanted to let people know that things are afoot.
 
 Mark Ramm and Tim Lesher have some independent ideas for TurboGears
 books, so we may actually have a couple of book projects underway
 soon. We're coordinating so that the books will serve different
 purposes.
 
 I was contacted directly by two publishers, Apress and Prentice Hall,
 this week about doing a TurboGears book. It's a good sign when
 publishers are coming to you, so it looks very favorable that a
 TurboGears book will be published. There hasn't been any word from
 O'Reilly yet.
 
 An important thing to note here: writing a book is a big project. It's
 going to be a number of months before a book comes out. Not to worry,
 though. The documentation will continue to improve and people have
 submitted quite a lot of documentation to the wiki.
 
 Kevin
 
 --
 Kevin Dangoor
 Author of the Zesty News RSS newsreader
 
 email: [EMAIL PROTECTED]
 company: http://www.BlazingThings.com
 blog: http://www.BlueSkyOnMars.com



[TurboGears] Re: Breaking up @expose

2005-11-12 Thread Sean Cazzell

On Sat, 2005-11-12 at 14:24 -0500, Kevin Dangoor wrote:
 Hi Sean,
 
 Nothing like a proposal that includes a patch :)
 
 I do agree that the monolithic, growing expose is not ideal, and I do
 want to make it possible (and easy!) to use other decorators, because
 they can be quite useful.
 
 Just to confirm my hunch (without actually looking at your patch :):
 
 @turbogears.expose(html=my.template)
 def save(self, name, address):
 ...do something...
 return dict(foo=bar)
 
 This will still work just as before.

Yep!

 So the main bit that your patch does is break out any input related
 behavior and expose parameters into a new decorator. It's not really
 any more verbose, it's just moving them to a new home. Seems like a
 good idea on the surface.

Correct, all the patch does is move the validator and forminput stuff to
a new decorator called unpack.  Unpack will always have to be the first
decorator on your methods (currently, expose has to be first):

@turbogears.expose(html=my.template)
... other decorators can now go here and work! ...
@turbogears.unpack(validators={...}, forminput=...)
def save(self, name, address):
...do something...
return dict(foo=bar)


I am hacking on my Paginator class and adding a decorator to it, but
need these changes to expose to enable my decorator to work (it needs to
be able to get at the method's return dict before it becomes HTML!).


Sean



 Kevin
 
 On 11/12/05, Sean Cazzell [EMAIL PROTECTED] wrote:
 
  I have opened a ticket for this and submitted a patch (diff of
  controllers.py only) that splits expose into expose and unpack.  Perhaps
  unpack should be called something else (validate)?
 
  http://trac.turbogears.org/turbogears/ticket/113
 
 
 
  Sean
 
 
 
 
 --
 Kevin Dangoor
 Author of the Zesty News RSS newsreader
 
 email: [EMAIL PROTECTED]
 company: http://www.BlazingThings.com
 blog: http://www.BlueSkyOnMars.com



[TurboGears] Re: Breaking up @expose

2005-11-12 Thread Sean Cazzell

Yep, I contributed some fixes to the Wareweb unpack (in SVN) and now am
hacking on TurboGears unpack.  I stole the name for lack of better ideas
(and thoughts of making TG unpack a bit more like Wareweb unpack).

I think it is probably a good idea to use Wareweb-style coercers instead
of FormEncode validators in turbogears.unpack and would be willing to
submit a patch if Kevin is interested in making the switch.

Wareweb and Paste is awesome, I hope to do what I can to get TG using
more of it!  I have been kicking around the idea of porting CherryPy to
Paste (as Ian has done with Webware) so we could run TurboGears
completely on top of Paste and take advantage of all the great code Ian
has in there (the debugging webcast on Ian's blog should convince
anyone).


Sean Cazzell



On Sat, 2005-11-12 at 13:31 -0600, Ian Bicking wrote:
 Sean Cazzell wrote:
  @expose(template=myproject.templates.foo)
  @unpack(... validators and inputform stuff here ...)
  def foo(bar):
  ...
 
 Anyway, just because @unpack looks so familiar to me, I thought I'd note
 a decorator I wrote for unpacking fields and doing some conversions.
 It's simpler than validators, for cases when you are getting
 server-generated content back and don't expect errors.
 
 http://svn.pythonpaste.org/Paste/Wareweb/trunk/wareweb/packing.py
 http://pythonpaste.org/wareweb/module-wareweb.packing.html#unpack
 



[TurboGears] Re: Breaking up @expose

2005-11-12 Thread Sean Cazzell

On Sat, 2005-11-12 at 14:49 -0600, Ian Bicking wrote:
 Sean Cazzell wrote:
  I think it is probably a good idea to use Wareweb-style coercers instead
  of FormEncode validators in turbogears.unpack and would be willing to
  submit a patch if Kevin is interested in making the switch.
 
 I think validators are much better for form validation.  However,
 there's lots of cases when there's a security requirement to validate
 input (or at least a convenience requirement), but the user shouldn't be
 editing those values and you don't need to provide nice errors when they
 are invalid.  But, to reiterate, I don't think these should ever be used
 for user input; if you want to be sloppy to start (which is fine) it is
 better to do the validation manually (e.g., coerce to int manually)
 because that will look more like what the un-sloppy validation will look
 like later.
 
 variabledecode probably fits in there somewhere as well; it overlaps a
 little with unpack, but also should be complimentary.

Ian in which cases would you recommend the use of the coercers then?  I
understand you are saying for passing information back that came from
the server.

I was using them in Wareweb (just experimenting) with URLs like:

/viewdoc/43/

@public
@unpack
def viewdoc(self, doc_id_int):
  .. do something ..

Obviously, doc_id_int is supplied by the user on the URL not from the
server - am I not using things in the intended way here?


  Wareweb and Paste is awesome, I hope to do what I can to get TG using
  more of it!  I have been kicking around the idea of porting CherryPy to
  Paste (as Ian has done with Webware) so we could run TurboGears
  completely on top of Paste and take advantage of all the great code Ian
  has in there (the debugging webcast on Ian's blog should convince
  anyone).
 
 I'd love to see CherryPy run nicely under Paste as well, so if you hit
 any problems be sure to ping me and I'll try to help.

Thanks, I appreciate the encouragement and will take you up on your
offer I am sure :)


Sean Cazzell



[TurboGears] Re: Paged result set with TG?

2005-11-10 Thread Sean Cazzell

Roman,

Here is the solution I am currently using.  First, I have a Paginator
class like:

class Paginator(object):
def __init__(self, results, per_page, page=0, total=None):
if not total:
total = results.count()
if total  per_page*page:
raise NotFound
self.pages = int(ceil(total / float(per_page)))
self.total, self.results = total, results
self.per_page, self.page = per_page, page
self.has_previous = self.page  0
self.has_next = self.pages-1  self.page

def items(self):
offset = self.per_page * self.page
end = offset + self.per_page
return list(self.results[offset:end])

def page_range(self, range=10):
if self.page-range  1:
start = 1
else:
start = self.page-range
if page+range  self.pages:
end = self.pages
else:
end = self.page+range
return range(start-1, end)

(Note that this needs to be hacked a bit for efficiency - it should
probably use properties and lazy-load total from results.count())


I use it like this in a controller (say to paginate a list of blog
comments):

posts = Post.select(Post.q.blogID == topic.id, orderBy=id)
paginator = Paginator(posts, per_page=25, page=page)
return dict(paginator=paginator, blog=blog, posts=paginator.items())


Now in your kid template you have paginator.has_next,
paginator.has_previous, etc.  The paginator.page_range function will let
you do lists of available pages like gooogle does on large search
results :)

I stole this idea from Django - I have actually ported/stolen a lot of
things from Django (some generic views, get_object_or_404, timesince,
etc) to TurboGears.



Sean Cazzell



On Thu, 2005-11-10 at 12:12 -0800, Roman wrote:
 
 Hi
 
 A piece of code often needed is that which lets you present a large
 database result set that spans across several HTML pages (that the user
 can navigate). As in Gooogle.
 
 Does TG (or SQLObject) somehow have native support for this?
 (or will it in the future?)
 
 If not, where should I start when using TG, SQLObject and
 MySQLPagedResultSet?
 
 Cheers,
 Roman
 



[TurboGears] Re: Error in svn checkout for kid

2005-11-08 Thread Sean Cazzell

I can confirm this.  It looks like someone may be trying to do something
evil (the ../../passwd thing) - but really, who doesn't use shadowed
passwd's these days?


Sean Cazzell

On Tue, 2005-11-08 at 12:31 -0800, [EMAIL PROTECTED] wrote:
 When running svn co http://www.turbogears.org/svn/turbogears/trunk
 turbogears, I'm getting this error:
 
 svn: Can't open config file '/var/projects/svn/kid/conf/../../passwd'
 
 I'm assuming this is an upstream problem?
 
 Thanks
 Chad
 



[TurboGears] Re: Indentity: flash when login fails ?

2005-11-07 Thread Sean Cazzell

William,

This is related to ticked #30:

http://trac.turbogears.org/turbogears/ticket/30

The patch to get_flash that I have posted there should fix the flash
comes 1 page too late problem you describe without the need for an
extra page load.


Sean Cazzell


On Mon, 2005-11-07 at 01:07 -0800, william wrote:
 I would just add a turboflash in case of failed login (wrong userid or
 passwd)
 
 Thus, In my Provider I've put the folowing code:
 if (user.passwd!=passwd):
 turbogears.flash('invalid userid or password')
 return None
 
 But the message does not appears on the page where I'm redirected,
 except if I click on one of the link there ;-(.
 Thus the flash comes 1 page too late.
 
 Problem come from redirect (I think) wich use (probably) HTTP code 304.
 
 How can I says to the browser to refresh the page after a failed login?
 
 Thanks
 
 William
 
 ---
 http://www.opensource4you.com
 



[TurboGears] Re: Identity: delete cookie on browser close

2005-11-06 Thread Sean Cazzell

No, you haven't missed anything - it isn't possible right now without
changes to the identity code.  The good news is the identity code is
still under heavy development and this sort of thing will be easy to do
in the near future (by 1.0 for sure).

For now, you could delete this line in
identity.filter.send_identity_cookie:

cookies[self.provider.identity_cookie]['expires']= timeout


Sean Cazzell

On Sun, 2005-11-06 at 08:05 -0800, [EMAIL PROTECTED] wrote:
 Hi,
 
 I'm just playing with the identity part of TurboGears and found that I
 don't know how to set the identity cookie to last only until the
 browser is closed.
 
 Reading some code I found identity.session.timeout, but setting this to
 0 just invalidates the login cookie inmediately.
 
 Have I missed some obvious way to do this?
 



[TurboGears] Re: unicode parameters

2005-11-06 Thread Sean Cazzell

I don't believe you need to enable the EncodingFilter as TG should
encode the output for you.  And rather than using _cpFilterList in your
class, try putting 

decodingFilter.on = True

in your dev.cfg file. Hopefully this works!


Sean Cazzell

On Sun, 2005-11-06 at 14:39 -0800, jak137 wrote:
 Thank you for links.  DecodingFilter from CherryPy would probably solve
 the problem, but I do not use CherryPy directly. My class inherits from
 turbogears.controllers.Root and when I try to add to it filters in the
 way it is done in http://www.cherrypy.org/wiki/UnicodeAware:
 
 from turbogears import controllers
 class Root(controllers.Root):
 _cpFilterList = [DecodingFilter('utf-8'), EncodingFilter('utf-8')]
 
 an exception is a result:
 
 Traceback (most recent call last):
   File pren1-start.py, line 20, in ?
 from pren1.controllers import Root
   File /home/jak/pren1/pren1/controllers.py, line 15, in ?
 class Root(controllers.Root):
   File /home/jak/pren1/pren1/controllers.py, line 17, in Root
 _cpFilterList = [DecodingFilter('utf-8'), EncodingFilter('utf-8')]
 TypeError: default __new__ takes no parameters
 
 So, is it possible to enable decoding in TurboGears without modifying
 the module's source code?
 



[TurboGears] Re: Identity: delete cookie on browser close

2005-11-06 Thread Sean Cazzell

Jeff,

I think I see where you are going with the separate timeouts - that way
the login expires when the browser is closed or the session times out. 

What do you think about resetting the session timeout on each request?
That way the timeout really becomes an idle timeout.  This is how banks
handle sessions and it seems to strike the right balance between
security and convenience.

Can we also add a checkbox to the login form along the lines of
remember my login and then adjust the timeout accordingly?

I would like to be able to set things up so logins expire after ~10
minutes of idle time (or when the browser is closed) if remember login
isn't checked, and expire after some really long period if it is.


Sean Cazzell

On Sun, 2005-11-06 at 17:29 -0500, Jeff Watkins wrote:
 This raises an interesting point: I think the Identity framework  
 should have separate time-out values for the cookie and the identity  
 session. I think the cookie should default to not having a time out,  
 hence it will be deleted when the browser quits. The identity session  
 will still have a 20 minute lifetime.
 
 There are a number of other little tweaks I want to add to the  
 Identity framework's:
 
 * Ability to specify the host and path for the cookie
 * Ability to tie a session cookie to the visitor's IP address
 * Adding the current identity to the variable provider for template  
 access
 
 I got distracted with other work this weekend, but I'd like to get  
 these features included in the next few days.
 
 On 6 Nov, 2005, at 4:39 pm, Sean Cazzell wrote:
 
 
  No, you haven't missed anything - it isn't possible right now without
  changes to the identity code.  The good news is the identity code is
  still under heavy development and this sort of thing will be easy  
  to do
  in the near future (by 1.0 for sure).
 
  For now, you could delete this line in
  identity.filter.send_identity_cookie:
 
  cookies[self.provider.identity_cookie]['expires']= timeout
 
 
  Sean Cazzell
 
  On Sun, 2005-11-06 at 08:05 -0800, [EMAIL PROTECTED] wrote:
  Hi,
 
  I'm just playing with the identity part of TurboGears and found  
  that I
  don't know how to set the identity cookie to last only until the
  browser is closed.
 
  Reading some code I found identity.session.timeout, but setting  
  this to
  0 just invalidates the login cookie inmediately.
 
  Have I missed some obvious way to do this?
 
 
 
 --
 Jeff Watkins
 http://newburyportion.com/
 
 Not everything that can be counted counts, and not everything that  
 counts can be counted.
 -- Albert Einstein
 
 



[TurboGears] Re: TurboGears, or why I chose it over Django and Ruby on Rails

2005-11-05 Thread Sean Cazzell

On Sat, 2005-11-05 at 09:16 -0500, Kevin Dangoor wrote:
 People don't realize this, but CherryPy's system is a lot more
 flexible than people give it credit for, and I like how CP does not
 require a separate configuration for URLs. Your example here can be
 handled fairly simply:
 
 class Blog:
 @turbogears.expose()
 def default(self, slug):
 ...do something...
 
 class Root(controllers.Root):
 blog = Blog()
 
 Also, CP 2.2 is going to add back positional parameters handling for
 methods. There's a ticket open to do this in TurboGears, and I may
 just do that as an interim measure until CP 2.2 is out. So, that adds
 this option:
 
 class Root(controllers.Root):
 @turbogears.expose()
 def blog(self, slug):
 ...do something...
 
 This would actually allow either of these URLs to work:
 /blog/slug
 
 /blog?slug=slug


Kevin, adding back positional params will be awesome.  I know you can
currently use default, but you are going to have to create a separate
class for every exposed method or put some sort of dispatch logic into
your Root.default.  I do agree that not having to maintain a separate
URL mapping file is nice and DRY.

Also turbogears.expose validators do not work with positional
parameters.  I've toyed with various fixes to this - my initial thought
was to do introspection on the decorated method, but I think that breaks
when you have stacked decorators like

@turbogears.expose()
@require_group(Admin)
def blog(self, slug):
...

Maybe we could require that expose always decorate the method directly?
It makes things a little more fragile, but it would allow expose to
introspect the method it is decorating to get the names of positional
parameters.

We could allow validators to be specified as either a list or a dict,
but what if you want a url like:

http://www.example.com/blog/my_slug_here/?page=2

I'm not sure how you are going to specify the validator list for your
method:

@turbogears.expose()
def blog(self, slug, page=0)
... do something here ...

Maybe just have a separate positional_validators argument to expose?



Kind Regards,

Sean Cazzell



[TurboGears] Re: Returning a 404 response

2005-11-04 Thread Sean Cazzell

I think this is the way to do it:

http://www.cherrypy.org/trunk/docs/book/chunk/ch03.html#id3221100
http://www.cherrypy.org/wiki/HandleErrors



Kind Regards,

Sean Cazzell


On Fri, 2005-11-04 at 09:46 +, Lee McFadden wrote:
 I haven't really tried this myself yet, but I looked into it and the
 only thing I could find that may be useful is cherrypy.headerMap[1]. 
 Using this you may be able to alter the response code of the page
 given certain criteria.
 
 - Lee
 
 [1] http://www.cherrypy.org/wiki/ReturnVsYield - See the code snippet
 near the bottom of the page.
 
 On 04/11/05, Jeff Grimmett [EMAIL PROTECTED] wrote:
  I'm a little confused on error handling in TG versus CherryPy itself. The CP
  site has a few examples of how to ensure that a 404 response is sent for a
  page that does not exist, but it looks like it would conflict with the use
  of Kid templates to generate a 'custom' 404 page.
 
  Currently, I have a 'default' defined for my Root class; if someone requests
  a page that does not exist, it falls through to this method and it then uses
  my 404.kid template to generate a custom not-found page.
 
  That's cool so far, but shouldn't a 404 error be sent in the response? When
  using the 'default' method, I'm sending a '200' response (page found), which
  is not very useful to crawlers, etc.
 
  What's the best way to handle this? Dispose of default() and use the CP
  error handler instead?
 
  --
  Things fall apart. The Center cannot hold.
- Life as a QA geek, in a nutshell.
 
  Best,
 
  Jeff
 



[TurboGears] Coding style question

2005-11-04 Thread Sean Cazzell

The TurboGears site suggests PEP 8 style be used but I have noticed
CherryPy, SQLObject and TG mostly use mixedCase style for method names.
So is the official recommendation PEP 8 but mixedCase methods?


Kind Regards,

Sean Cazzell



[TurboGears] Re: I broke my TG install :D

2005-11-03 Thread Sean Cazzell

Jeremy,

I ran into the same issue - there may be an easier way to fix it, but I
edited my tg-admin script and commented out the 

__requires__ = 'TurboGears==0.8a4'

line and changed the load_entry_point call to:

load_entry_point('TurboGears', 'console_scripts', 'tg-admin')()

It worked for me!  Does anyone know how to generate the tg-admin script
from a SVN tree?  I tried python setup.py install_scripts but I get
the following error:

error: cannot copy tree 'build/scripts-2.4': not a directory


Kind Regards,

Sean Cazzell


On Thu, 2005-11-03 at 13:35 -0800, Jeremy wrote:
 Ok.. So I tried to upgrade to the svn version of turbogears...
 
 I installed svn.
 
 Then I downloaded the turbogears latest version by running:
 svn co http://www.turbogears.org/svn/turbogears/trunk turbogears
 
 Then I ran:
 easy_install RuleDispatch
 
 After that:
 python setup.py develop
 
 Now, whenever I run tg-admin, I get:
 asimov:~/turbogears jeremy$ tg-admin
 /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/setuptools-0.6a7-py2.4.egg/pkg_resources.py:1943:
 UserWarning: Module paste was already imported from
 /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/PasteDeploy-0.3-py2.4.egg/paste/__init__.pyc,
 but
 /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/Paste-0.3-py2.4.egg
 is being added to sys.path
   warn(
 Traceback (most recent call last):
   File /usr/local/bin/tg-admin, line 7, in ?
 sys.exit(
   File
 /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/setuptools-0.6a7-py2.4.egg/pkg_resources.py,
 line 236, in load_entry_point
 return get_distribution(dist).load_entry_point(group, name)
   File
 /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/setuptools-0.6a7-py2.4.egg/pkg_resources.py,
 line 229, in get_distribution
 if isinstance(dist,Requirement): dist = get_provider(dist)
   File
 /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/setuptools-0.6a7-py2.4.egg/pkg_resources.py,
 line 115, in get_provider
 return working_set.find(moduleOrReq) or
 require(str(moduleOrReq))[0]
   File
 /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/setuptools-0.6a7-py2.4.egg/pkg_resources.py,
 line 382, in find
 raise VersionConflict(dist,req) # XXX add more info
 pkg_resources.VersionConflict: (TurboGears 0.9a0dev-r136
 (/Users/jeremy/turbogears), Requirement.parse('TurboGears==0.8a3'))
 
 
 Aparently, there is a version conflict, but I do not know how to
 resolve this.
 
 Thanks!
 
 Jeremy
 



[TurboGears] Re: TurboGears using Microsoft SQL Server?

2005-11-03 Thread Sean Cazzell

Randall,

I think MS SQL support is currently only in SQLObject CVS.  See:

http://www.sqlobject.org/News.html#sqlobject-0-8-0


Sean Cazzell

On Thu, 2005-11-03 at 16:49 -0800, [EMAIL PROTECTED] wrote:
 SQL Object's documentation says they support Microsoft SQL Server.
 However, I haven't seen how to test that-I did test the underlying
 components they said were necessary.
 
 When working through the tutorial I got this message:
 
 cd /d/wwwroot/turbogears/wiki20
  tg-admin.exe sql create
 Using database URI mssql://rjb:[EMAIL PROTECTED]:1433/turbogears
 Traceback (most recent call last):
   File c:\python24\Scripts\tg-admin-script.py, line 7, in ?
 sys.exit(
   File
 c:\python24\lib\site-packages\TurboGears-0.8a4-py2.4.egg\turbogears\comm
 and\__init__.py, line 186, in main
 command.run()
   File
 c:\python24\lib\site-packages\TurboGears-0.8a4-py2.4.egg\turbogears\comm
 and\__init__.py, line 106, in run
 command.the_runner.run(sys.argv)
   File
 c:\python24\lib\site-packages\SQLObject-0.7.0-py2.4.egg\sqlobject\manage
 r\command.py, line 102, in run
 runner.run()
   File
 c:\python24\lib\site-packages\SQLObject-0.7.0-py2.4.egg\sqlobject\manage
 r\command.py, line 233, in run
 self.command()
   File
 c:\python24\lib\site-packages\SQLObject-0.7.0-py2.4.egg\sqlobject\manage
 r\command.py, line 543, in command
 for soClass in self.classes(require_some=True):
   File
 c:\python24\lib\site-packages\SQLObject-0.7.0-py2.4.egg\sqlobject\manage
 r\command.py, line 255, in classes
 conn = self.connection()
   File
 c:\python24\lib\site-packages\SQLObject-0.7.0-py2.4.egg\sqlobject\manage
 r\command.py, line 316, in connection
 return sqlobject.connectionForURI(self.options.connection_uri)
   File
 c:\python24\lib\site-packages\SQLObject-0.7.0-py2.4.egg\sqlobject\dbconn
 ection.py, line 910, in connectionForURI
 assert self.schemeBuilders.has_key(scheme), (
 AssertionError: No SQLObject driver exists for mssql (only sqlite,
 sapdb, postgr
 esql, firebird, maxdb, sybase, interbase, psycopg, mysql, postgres)
 



[TurboGears] tg-admin sql create fails when using ForeignKey

2005-10-24 Thread Sean Cazzell

Hello,

I am taking a look at TurboGears and following through the getting
started guide.  I have found that running tg-admin sql create fails
with models containing foreign keys because the create table statements
are issued in the wrong order.  I am using postgresql.

Here's an example model:

class Site(SQLObject):
name = StringCol(length=25)
members = MultipleJoin('Member')

class Member(SQLObject):
site = ForeignKey('Site', unique=True)
username = StringCol(length=25)

Running tg-admin sql sql outputs the following:

CREATE TABLE member (
id SERIAL PRIMARY KEY,
site_id INT UNIQUE, CONSTRAINT site_id_exists FOREIGN KEY (site_id)
REFERENCES site (id) ,
username VARCHAR(25)
);

CREATE TABLE site (
id SERIAL PRIMARY KEY,
name VARCHAR(25)
);


And tg-admin sql create fails on the CREATE TABLE member statement as
the site table does not exist yet.  Is this a known limitation, or is
there some way around this?


Kind Regards,

Sean Cazzell