[TurboGears] Re: With whom do you guys host with?

2005-10-08 Thread Scott Benjamin

Has there been any progress on an offical deployment scenario?

I'd like to throw up some turbogears apps on my site, which doesn't
allow fastcgi, and I'm wondering what my options would be.

Also, I just found Turbo Gears last night, stayed up for 3 hours longer
than I should have just looking and finding my way around. Well done
indeed!

Scott



[TurboGears] Re: With whom do you guys host with?

2005-10-08 Thread Scott Benjamin

Whoops.. just after I posted that I found this:
http://www.turbogears.org/docs/deployment.html

heh.. 

Thanks,

Scott



[TurboGears] How to install TG on a webhost without root access?

2005-10-08 Thread Scott Benjamin

What's the preferred method of installing TurboGears on a webhost where
I don't have root access?  


Scott



[TurboGears] Re: How to install TG on a webhost without root access?

2005-10-08 Thread Kevin Dangoor

Hi Scott,

This is something on my todo list to experiment with and write up. In
the meantime, you should take a look at Phillip Eby's instructions for
non-root installations using setuptools:

http://peak.telecommunity.com/DevCenter/EasyInstall#non-root-installation

Kevin

On 10/8/05, Scott Benjamin [EMAIL PROTECTED] wrote:

 What's the preferred method of installing TurboGears on a webhost where
 I don't have root access?


 Scott




--
Kevin Dangoor
Author of the Zesty News RSS newsreader

email: [EMAIL PROTECTED]
company: http://www.BlazingThings.com
blog: http://www.BlueSkyOnMars.com


[TurboGears] Re: With whom do you guys host with?

2005-10-08 Thread Kevin Dangoor

Yeah, that document is woefully inadequate, but will get you
somewhere. The non-root installation instructions I just sent, plus
using mod_proxy (ProxyPass/ProxyPassReverse) or mod_rewrite should get
you a chunk of the way there.

Kevin

On 10/8/05, Scott Benjamin [EMAIL PROTECTED] wrote:

 Whoops.. just after I posted that I found this:
 http://www.turbogears.org/docs/deployment.html

 heh..

 Thanks,

 Scott




--
Kevin Dangoor
Author of the Zesty News RSS newsreader

email: [EMAIL PROTECTED]
company: http://www.BlazingThings.com
blog: http://www.BlueSkyOnMars.com


[TurboGears] Re: 0.8a1 incompatible with formencode 0.23dev ?

2005-10-08 Thread Krys Wilken

This one exists in 0.5 as well, I was going to mention it.

You need to have a def validation _error method as the TG code works for
that case but the if the method does not exist, the default raise a
traceback code is missing arguments.  I never bothered to figure out
the fix, though.  I just created a validation_error method on my controller.

I am trying to say with virgin stable releases as much as possible for
my project.

Hope this helps.

Krys

[EMAIL PROTECTED] wrote:

==
2005/10/07 16:44:22  INFO Traceback (most recent call last):
  File
/home/gary/lib/python2.4/site-packages/CherryPy-2.1.0_rc1-py2.4.egg/cherrypy/_cphttptools.py,
line 272, in run
main()
  File
/home/gary/lib/python2.4/site-packages/CherryPy-2.1.0_rc1-py2.4.egg/cherrypy/_cphttptools.py,
line 498, in main
body = page_handler(*args, **cherrypy.request.paramMap)
  File
/home/gary/lib/python2.4/site-packages/TurboGears-0.8a1dev-py2.4.egg/turbogears/controllers.py,
line 119, in newfunc
raise turbogearsvalid.Invalid(str(errors))
TypeError: __init__() takes at least 4 arguments (2 given)
=
turbogearsvalid is simply validators from formencode, the Invalid class
is like the following :

class Invalid(Exception):


This is raised in response to invalid input.  It has several
public attributes:

msg:
The message, *without* values substituted.  For instance, if
you want HTML quoting of values, you can apply that.
substituteArgs:
The arguments (a dictionary) to go with `msg`.
str(self):
The message describing the error, with values substituted.
value:
The offending (invalid) value.
state:
The state that went with this validator.  This is an
application-specific object.
error_list:
If this was a compound validator that takes a repeating value,
and sub-validator(s) had errors, then this is a list of those
exceptions.  The list will be the same length as the number of
values -- valid values will have None instead of an exception.
error_dict:
Like `error_list`, but for dictionary compound validators.


def __init__(self, msg,
 value, state, error_list=None, error_dict=None):
Exception.__init__(self, msg)
self.msg = msg
self.value = value
self.state = state
self.error_list = error_list
self.error_dict = error_dict


  




[TurboGears] Re: How does the current validator mechanism works ?

2005-10-08 Thread Krys Wilken

I agree completely.

In my project my validation_error method has to do just that: recall the
original method with all arguments + and errors argument.

This seems the best approach and the code is fairly boiler plate.  It
would be nice to see this as the default behaviour in TG.

Krys

[EMAIL PROTECTED] wrote:

I begin to start using the validator and got confused of what is the
design philosophy behind it.

1. There is an instance method validator_error that would be called if
exist otherwise it would raise another exception.

I believe this has to be mentioned in the documentation as otherwise,
this exception would not be caught by anyone and it would be the ugly
server get in trouble message, which is very scary but not the case.
Just some data content error.

If validator_error is defined, if will be called with the first
parameter being the original function(the one that turbogears.expose
supposed to be decorating).

While the documentation said I can do whatever I want, I think it would
be more natural to let the original function deal with it as this
validator_error is a centralized function(sort of catch all) that is
impossible to make meaningful error message/response.

Would it be better to just have a convention that any exposed function
that has validator enabled should expect one more argument error=None
to indicate such condition and let it do its job there ?


  




[TurboGears] Re: How does the current validator mechanism works ?

2005-10-08 Thread Jeff Watkins


What about a nested validation_error function. For example:


@turbogears.expose( validators= mySchema() )
def index( self, arg1, arg2 )
def validation_failed( errors ):
# do something clever here and ultimately
# either retry index or bail
pass

# real code for index
pass


Is it legal to have a self parameter for the nested function? If so,  
I guess we'll have to pass it along explicitly when calling the  
nested validation_failed function.


Of course, if no validation_failed function is defined, the class- 
based one should be tried next.




--
Jeff Watkins
http://metrocat.org/

Advertising directed at children is inherently deceptive and  
exploits children under eight years of age.

-- American Academy of Pediatrics



[TurboGears] Re: Auth spec

2005-10-08 Thread Krys Wilken

I like this.

I think groups are useful for organizational purposes on larger scale
apps, but roles is a better conceptual idea for permission assignment
and requirement.

I actually like Zope's User, Group and Role 3-way system, complicated
though it is.  it's great for large scale systems like Zope is intended
to be.

I think for TG, thought groups can come later, if the is a need.  KISS
right? :-)

Krys

Lethalman wrote:

I've seen how does multiauth work.
I suggest this auth model for turbogears:

MODEL

class AuthRole:
  name = StringCol(alternateID=True)
  inherit = RelatedJoin(AuthRole) # Is it possible?
  users = RelatedJoin(AuthUser)

class AuthUser:
  username = StringCol(alternateID=True)
  password = StringCol()
  roles = RelatedJoin(AuthRole)
  # Functions to get/save encrypted passwords

CONTROLLER

class Root:
  admin = Admin(['admin'])

  @turbogears.expose()
  def index(self)

  @turbogears.expose(secure=['user.vote_polls'])
  def vote(self)

class Admin:
  @turbogears.expose()
  def index(self)

  @turbogears.expose(secure=['admin.view_polls'])
  def view_polls(self)

  @turbogears.secure(secure=['admin.edit_polls'])
  @turbogears.expose()
  def edit_polls(self)

  @turbogears.secure(secure=['admin.del_polls'])
  @turbogears.expose()
  def del_polls(self)

Ok we have the following roles (- means inherit):
user
user.vote_polls - user
user.all - user, user.vote_polls
admin - user.all
admin.view_polls - admin
admin.edit_polls - admin.view_polls
admin.del_polls - admin.view_polls
admin.super - admin, admin.view_polls, admin.del_polls

And we have these users with relative roles:
A - user
B - user.all
C - admin
D - admin, admin.del_polls
E - admin.super

Ok, roles are recursively inherited and fetched in a single list even
if there're duplicates.

These are the access for each user:
A - Root.index
B - All Root
C - Admin.index
D - Admin.index, Admin.view_polls, Admin.del_polls
E - All Admin

What about? I think (opposite to my former mail) groups are unuseful.

--
www.italianpug.org - Italian Python User Group Founder

  




[TurboGears] Re: Building from subversion

2005-10-08 Thread Krys Wilken

It might be worth noting that easy_install.py -f . (note the period,
i.e. current directory) works.  -f can use local paths as well as urls. 

At work we have MS Proxy (NTLM auth) and McAfee WebShield, so
downloading anything is a royal pain.  I really like setuptools, but
having a download and local install capability is critical in my work
environment.

That said, I had to write a script to get setuptools installed from a
local egg.

I will be working on using this knowledge with Inno Setup to make a nice
and friendly stand-alone windows installer for my app.  It could be used
for TG too.

Ian, if you are reading this, I'd really love to hear your thoughts on
the use of setuptools (and getting setuptools initially installed)
without needing a network connection.  (Admittedly I am not well versed
in eggs as TG is my first real exposure to them. :-)

Hope this helps,
Krys

David Stanek wrote:

That is probably better than what I had done. I just grabbed the eggs from
the TurboGears download page and since I am on Linux I built a cElementTree
egg. Then I wrote a little shell script to set my PATH and PYTHONPATH.

David

On 10/7/05, [EMAIL PROTECTED] [EMAIL PROTECTED] wrote:
  

YES. I have gone through all these before. setuptools sounds great
except that the infrastructure is not there yet.






--
David Stanek
www.roninds.net http://www.roninds.net

  




[TurboGears] Re: How does the current validator mechanism works ?

2005-10-08 Thread Krys Wilken


Ian Bicking wrote:

 [EMAIL PROTECTED] wrote:

[snip]

 If validator_error is defined, if will be called with the first
 parameter being the original function(the one that turbogears.expose
 supposed to be decorating).

 While the documentation said I can do whatever I want, I think it would
 be more natural to let the original function deal with it as this
 validator_error is a centralized function(sort of catch all) that is
 impossible to make meaningful error message/response.


 It seems to me that another function should be called, but one that is
 a sister function, not a single validation_error function.  A
 particularly common one would be the function that originally
 generated the form, so it could regenerate the form with the errors in
 it.

 So it might be:


 @expose(validators=..., on_error='register'):
 def do_registration(self, ...):
 # actually perform action

 @expose(html='form.html'):
 def register(self):
 # creates form with action=do_registration
 # maybe expose pipes the output through htmlfill if this
 # is in response to an error, or... something

This works much better  than a generic validation_error method, IMHO.
Whether the same method is used to display the form and process the form
data or not should be up to the programmer, but coding is much simpler
if I can just say ok, were there any errors, rather than from which
method did I get these errors and how to I tell it that there were errors.

Krys


[TurboGears] Re: turbogears-admin shell initial data file

2005-10-08 Thread Krys Wilken

This works for me. :-)

As for you point 1), if there is no tg_init_database, then the behaviour
is exactly as before and SQLObject users will not be confused.  That is
to say, I have to do an explicit act to get the new behaviour and so I
will know what will happen.

As for point 2), I am thinking that a counterpart method like
tg_clear_database or something would be nice so that old data can be
torn down.  And alternative would be to make your tg_init_database,
check for the existence of any data you are trying to insert.

Further a reset or rebuild method is a simple as tg_clear_database();
tg_init_database().  If that is useful.

And then there is the blue-sky-on-mars wink thinking that this could
be the base for model versioning with upgrade functions in each model to
that can migrate old data structures to new ones. I think this is a bit
far off, though. (Can you tell I have been played with Zope and
Twisted?) :-)

Krys

Fabian Neumann wrote:

Krys Wilken wrote:
  

I think both ideas are of value.  An exec command for running scripts,
and a special module-level function in model.py that is run
automatically by sql create.



I might like it, too.  What do you think of this:

Index: turbogears/quickstart/projectname/model.py.source
===
--- turbogears/quickstart/projectname/model.py.source   (Revision 43)
+++ turbogears/quickstart/projectname/model.py.source   (Arbeitskopie)
@@ -6,3 +6,6 @@

 # class YourDataClass(SQLObject):
 # pass
+
+# def tg_init_database():
+# pass
Index: turbogears/command/__init__.py
===
--- turbogears/command/__init__.py  (Revision 43)
+++ turbogears/command/__init__.py  (Arbeitskopie)
@@ -104,6 +104,12 @@

 from sqlobject.manager import command
 command.the_runner.run(sys.argv)
+if sqlobjcommand == create:
+mod = self.get_model()
+if hasattr(mod, 'tg_init_database'):
+print 'Filling database'
+mod.tg_init_database()
+

 def fix_egginfo(self, eggname):
 print 


Two issues with that:
1. This behaviour may be unexpected by people who are familiar with
   sqlobject-admin create.
2. If you run sql create twice or more, those init values are doubled.

  

An alternative to a single module-level function would be a special
method on each model that is responsible for populating itself, perhaps
post_create(self) or something.  Sql create could just call that
method of each model after all the tables have been created.



I don't think this granularity is useful, as you can only create all
models at once (I think).

Fabian


  




[TurboGears] Re: How does the current validator mechanism works ?

2005-10-08 Thread Krys Wilken

Exactly.  Validation errors are not usually programming errors.  They
are usually user input errors.  Telling the user that they have inputted
invalid data should be simple and intuitive.  A separate method for
error handling is not intuitive to me. :-)

Krys

[EMAIL PROTECTED] wrote:

To me it seems like it should be an error if there's no validation_error
method and any validators are given.  This way the error is caught early
during development.



Yes, but there are sometimes(many times I would say) soft-errors that
don't need this kind of handling. A typical case would be the fields
may come in as nothing(None) which can be a don't care and proceed.

defining validation_error would grab the control of it without giving
it a chance to go on. And I re-read the code, what validation_error
received is not the original function, but the name of the function,
making calling it back a bit difficult.


  




[TurboGears] 'quickstart' error handling

2005-10-08 Thread Mike Harding
The quickstart project template has the interesting feature, inherited, 
I guess, from CherryPy...



If you access 'http://localhost:8080/?var=5' you get the ugly display:



Traceback (most recent call last):

File 
/usr/local/lib/python2.4/site-packages/CherryPy-2.1.0_betadev-py2.4.egg/cherrypy/_cphttptools.py, 
line 276, in run

 main()

File 
/usr/local/lib/python2.4/site-packages/CherryPy-2.1.0_betadev-py2.4.egg/cherrypy/_cphttptools.py, 
line 498, in main

 body = page_handler(*args, **cherrypy.request.paramMap)

File 
/usr/local/lib/python2.4/site-packages/TurboGears-0.5.1-py2.4.egg/turbogears/controllers.py, 
line 93, in newfunc

 output = func(self, *args, **kw)

TypeError: index() got an unexpected keyword argument 'var'



Would it make sense to either have the root object take a dictionary 
arg, or explaing how to have the system catch errors such as these so 
they don't go to the screen?





[TurboGears] MochiKit 0.90 released

2005-10-08 Thread Bob Ippolito


MochiKit 0.90 http://mochikit.com/download.html has been released!   
This release includes a new feature, some bug fixes.


The new feature in 0.90 is JSON serialization and evaluation support  
via serializeJSON, evalJSON and registerJSON.


2005-10-08  v0.90

- Fixed ISO compliance with toISODate
- Added missing operator.sub
- Placated Mozilla's strict warnings a bit
- Added JSON serialization and unserialization support to MochiKit.Base:
  serializeJSON, evalJSON, registerJSON.  This is very similar to  
the repr

  API.
- Fixed a bug in the script loader that failed in some scenarios when  
a script

  tag did not have a src attribute (thanks Ian!)
- Added new MochiKit.DOM createDOMFunc aliases: H1, H2, H3, BR, HR,  
TEXTAREA,

  P, FORM
- Use encodeURIComponent / decodeURIComponent for MochiKit.Base  
urlEncode

  and parseQueryString, when available.


[TurboGears] Re: turbogears.flash() only displays every other call

2005-10-08 Thread Krys Wilken

I ran into this too.

I don't know if the behaviour is a bug, or just if we are
misinterpreting the intended purpose of flash.

How flash works is to set a cookie which is sent to the browser.  The
message only gets displayed when the cookie comes back from the
browser.  The cookie is then deleted once it has been read back by the
server.  That's why it only shows up every other time.  It has to get to
the browser and come back to be displayed.  And once it is aback is it
removed.  If a new one is set at that time, then it has to do the full
trip again to be displayed.

I ended up just passing in my own message variable to the template and
having the template show the message if it exists. (Basically
duplicating the flash functionality but without using cookies.)

If this is not a bug, then I'd love to see documentation explaining the
purpose and semantics of using flash, particularly in conjunction with
HTTPRedirect and InternalRedirect.

Hope this helps,
Krys

Tim Lesher wrote:

[Env: Turbogears 0.5, running on Windows XP]

I have a template containing a form, which posts back to the same URL.
 My controller looks like this:

@turbogears.expose(html=yadda)
def showStuff(self, **kwargs):
if 'submit' in kwargs:
# [ Update the db ]
turbogears.flash('DB Updated')
return dict(...yadda...)

This works fine--the db gets updated every time, but the flash message
is only displayed on every _other_ try.  In other words, if I just
bounce on the Submit button, I see the flash message on one view, then
nothing the next view, then I see the flash message on the third view,
etc.

Am I misusing flash here?

If not, I'll cobble up a minimal example to show the problem.

Thanks!
--
Tim Lesher [EMAIL PROTECTED]

  




[TurboGears] Re: How does the current validator mechanism works ?

2005-10-08 Thread Krys Wilken

Interesting idea. :-)

I am unsure what benefit it provides over just say just having an extra
errors=None argument on the original method.  I'd love to hear your
thoughts on it though. :-)

It seems to me that that there are two simple ways of handling
validation errors:

1) Adding an errors=None argument to the method and letting it handle
things (so the validators would just populate the errors dict and pass
them on to the method), or
2) Ian's idea of an on_error='method_name' added to expose.

Actually, now that I am thinking of it, I'd say combine the two ideas.

If no on_error is provided assume the on_error method is the method
being decorated, otherwise call the specified method.

Whatever method is called would have and errors keyword argument which
is a dictionary in the form of: {'form_field_name': [list of Invalid
objects],...}

That way you can have, as Ian believes, separate methods for
presentation of a form and processing of it, or you can have one method
responsible for both, as others prefer.

In either case, the method that knows best about it's subject matter is
responsible for handling the errors, instead of some generic
validation_error method that knows nothing of the specifics of the
original method that was called.

Anyway, just my $.02.  Shoot me down if out in left field. :-)

Krys

Jeff Watkins wrote:


 What about a nested validation_error function. For example:


 @turbogears.expose( validators= mySchema() )
 def index( self, arg1, arg2 )
 def validation_failed( errors ):
 # do something clever here and ultimately
 # either retry index or bail
 pass

 # real code for index
 pass


 Is it legal to have a self parameter for the nested function? If so, 
 I guess we'll have to pass it along explicitly when calling the 
 nested validation_failed function.

 Of course, if no validation_failed function is defined, the class-
 based one should be tried next.



 -- 
 Jeff Watkins
 http://metrocat.org/

 Advertising directed at children is inherently deceptive and 
 exploits children under eight years of age.
 -- American Academy of Pediatrics





[TurboGears] Re: 'quickstart' error handling

2005-10-08 Thread Krys Wilken

What I like to do is add *args and **kwargs to controller methods,
precisely for that reason.

e.g. def index(self, expected_var, ..., *args, **kwargs):

That way I catch any extra argument passed in and I can either ignore
them or present the error in a friendlier way.

Not sure if there are better ways to do it though.

Hope this helps.
Krys

Mike Harding wrote:

The quickstart project template has the interesting feature, inherited, I
guess, from CherryPy...

If you access 'http://localhost:8080/?var=5' you get the ugly display:

Traceback (most recent call last):
File */usr/local/lib/python2.4/site-packages/CherryPy-
2.1.0_betadev-py2.4.egg/cherrypy/*_cphttptools.py, line 276, in run
main()
File */usr/local/lib/python2.4/site-packages/CherryPy-
2.1.0_betadev-py2.4.egg/cherrypy/*_cphttptools.py, line 498, in main
body = page_handler(*args, **cherrypy.request.paramMap)
File 
/usr/local/lib/python2.4/site-packages/TurboGears-0.5.1-py2.4.egg/turbogears/controllers.py,
line 93, in newfunc
output = func(self, *args, **kw)
TypeError: index() got an unexpected keyword argument 'var'

Would it make sense to either have the root object take a dictionary arg, or
explaing how to have the system catch errors such as these so they don't go
to the screen?

  




[TurboGears] Re: How does the current validator mechanism works ?

2005-10-08 Thread [EMAIL PROTECTED]

Agree. In its(TurboGears) current form, I have changed all my functions
to this form(thus ignore the validator feature) :

func(self,**kwargs):

Then I can define a formencode schema to validate against kwargs which
is a dict. Basically achieve what you mentioned. The only issue is, a
few line of code is needed to grab the keywords that is needed for
processing, back from kwargs, rather than func(self,
something=None,someother=None). But kwargs is needed anyway(as the
kitchen sink) or any strange hidden fields in a form would bomb.

Krys Wilken wrote:
 Interesting idea. :-)

 I am unsure what benefit it provides over just say just having an extra
 errors=None argument on the original method.  I'd love to hear your
 thoughts on it though. :-)

 It seems to me that that there are two simple ways of handling
 validation errors:

 1) Adding an errors=None argument to the method and letting it handle
 things (so the validators would just populate the errors dict and pass
 them on to the method), or
 2) Ian's idea of an on_error='method_name' added to expose.

 Actually, now that I am thinking of it, I'd say combine the two ideas.

 If no on_error is provided assume the on_error method is the method
 being decorated, otherwise call the specified method.

 Whatever method is called would have and errors keyword argument which
 is a dictionary in the form of: {'form_field_name': [list of Invalid
 objects],...}

 That way you can have, as Ian believes, separate methods for
 presentation of a form and processing of it, or you can have one method
 responsible for both, as others prefer.

 In either case, the method that knows best about it's subject matter is
 responsible for handling the errors, instead of some generic
 validation_error method that knows nothing of the specifics of the
 original method that was called.

 Anyway, just my $.02.  Shoot me down if out in left field. :-)

 Krys

 Jeff Watkins wrote:

 
  What about a nested validation_error function. For example:
 
 
  @turbogears.expose( validators= mySchema() )
  def index( self, arg1, arg2 )
  def validation_failed( errors ):
  # do something clever here and ultimately
  # either retry index or bail
  pass
 
  # real code for index
  pass
 
 
  Is it legal to have a self parameter for the nested function? If so,
  I guess we'll have to pass it along explicitly when calling the
  nested validation_failed function.
 
  Of course, if no validation_failed function is defined, the class-
  based one should be tried next.
 
 
 
  --
  Jeff Watkins
  http://metrocat.org/
 
  Advertising directed at children is inherently deceptive and
  exploits children under eight years of age.
  -- American Academy of Pediatrics
 
 



[TurboGears] Re: turbogears.flash() only displays every other call

2005-10-08 Thread Tim Lesher

On 10/8/05, Krys Wilken [EMAIL PROTECTED] wrote:

 I ran into this too.

 I don't know if the behaviour is a bug, or just if we are
 misinterpreting the intended purpose of flash.

 How flash works is to set a cookie which is sent to the browser.

Aha.  That's the problem.  That means I was misusing flash--it's used
when you want to display a message after a redirect.

 I ended up just passing in my own message variable to the template and
 having the template show the message if it exists. (Basically
 duplicating the flash functionality but without using cookies.)

That was my solution, too.

--
Tim Lesher [EMAIL PROTECTED]


[TurboGears] Re: Validator and None ?

2005-10-08 Thread Ian Bicking

[EMAIL PROTECTED] wrote:
 Is there a way to specify that None(empty, not present) is valid ?
 Something equivalent to :
 
 if my_string is None or my_string==: v = None
 else: v = validator.to_python(my_string)

v = validator(if_empty=None).to_python(my_string)

Note that you can clone any validator with modified arguments, by
calling it with those arguments.  I.e., these are the same:

v = validators.Int(max=10)(if_empty=0)
v = validators.Int(max=10, if_empty=0)