[web2py] Re: web2py 2.17.1

2018-08-13 Thread Jim Karsten
I am conditionally displaying the form input in a view. Something like this:

{{if 'name' in form.fields:}}

Name:
{{=form.custom.widget.name}}

{{pass}}

I can change that to: 
{{if 'name' in form.custom.widget:}}
...
{{pass}}

On Sunday, August 12, 2018 at 9:36:06 PM UTC-4, Massimo Di Pierro wrote:
>
> On second look this is correct and intentional and fixed a bug. this form 
> is a from a factory and there is no record. the field is not writable 
> therefore it can only be displayed in read-only mode but there is no value 
> (record) to display.
>
> Does it break something?
>
> On Sunday, 12 August 2018 12:52:31 UTC-7, Jim Karsten wrote:
>>
>> I'm seeing a change in behaviour between versions 2.16.1 and 2.17.1. 
>>
>> form = SQLFORM.factory(Field('name', writable=False))
>> print form.fields
>>
>> # In 2.16.1 prints: ['id', 'name']
>> # In 2.17.1 prints: ['id']
>>
>> Is this intentional?
>>
>>

-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[web2py] Re: web2py 2.17.1

2018-08-12 Thread Jim Karsten
I'm seeing a change in behaviour between versions 2.16.1 and 2.17.1. 

form = SQLFORM.factory(Field('name', writable=False))
print form.fields

# In 2.16.1 prints: ['id', 'name']
# In 2.17.1 prints: ['id']

Is this intentional?

-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[web2py] Re: Print statement fails in command line script (v2.15.3)

2017-08-30 Thread Jim Karsten
I'm using python version 2.7.12

On Tuesday, August 29, 2017 at 7:12:53 PM UTC-4, Dave S wrote:
>
>
>
> On Tuesday, August 29, 2017 at 1:33:53 PM UTC-7, Jim Karsten wrote:
>>
>> I run many scripts from the command line. After upgrading to v2.15.3, I 
>> find print statements produce a SyntaxError. If I convert the statements to 
>> a print function it works. This was not a problem in v2.14.6.
>>
>>
> What python version are you running?  
>
> I have a few controller functions that I run with -S, but I don't have 
> them on my 2.15.3 instance at the moment.  But I do have URL-accessed 
> controllers with print statements, and those seem fine ... 2.15.3, Python 
> 2.7.3 (on an antique Fedora).
>
>
>
>  
>
>> To illustrate:
>>
>> $ cat test.py
>> #!/usr/bin/env python
>> if __name__ == '__main__':
>> print 'Hello!'
>>
>> $ python web2py.sh --no-banner -S myapp -R test.py
>> Traceback (most recent call last):
>>   File "/srv/http/web2py/2.15.3/web2py/gluon/shell.py", line 270, in run
>> execfile(startfile, _env)
>>   File "/root/tmp/test.py", line 4
>> print 'abc'
>> SyntaxError: invalid syntax
>>
>> This works:
>>
>> $ cat test2.py
>> #!/usr/bin/env python
>> if __name__ == '__main__':
>> print('Hello!')
>>
>> $ python web2py.py --no-banner -S myapp -R test2.py
>> Hello!
>>
>> Is this is expected behaviour? Is there a command line option, or a small 
>> change that permits cli scripts to continue to accept python2 syntax?
>>
>>  Thanks,
>> Jim
>>
>
>
> /dps
>  
>

-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[web2py] Re: Print statement fails in command line script (v2.15.3)

2017-08-30 Thread Jim Karsten
Done: https://github.com/web2py/web2py/issues/1750
Thanks.
Jim

On Tuesday, August 29, 2017 at 9:41:49 PM UTC-4, Anthony wrote:
>
> Looks like shell.py imports print_function from __future__, which requires 
> use of the print() function. I suppose this should be considered a breaking 
> of backward compatibility, so feel free to report an issue on Github.
>
> Anthony
>
> On Tuesday, August 29, 2017 at 4:33:53 PM UTC-4, Jim Karsten wrote:
>>
>> I run many scripts from the command line. After upgrading to v2.15.3, I 
>> find print statements produce a SyntaxError. If I convert the statements to 
>> a print function it works. This was not a problem in v2.14.6.
>>
>> To illustrate:
>>
>> $ cat test.py
>> #!/usr/bin/env python
>> if __name__ == '__main__':
>> print 'Hello!'
>>
>> $ python web2py.sh --no-banner -S myapp -R test.py
>> Traceback (most recent call last):
>>   File "/srv/http/web2py/2.15.3/web2py/gluon/shell.py", line 270, in run
>> execfile(startfile, _env)
>>   File "/root/tmp/test.py", line 4
>> print 'abc'
>> SyntaxError: invalid syntax
>>
>> This works:
>>
>> $ cat test2.py
>> #!/usr/bin/env python
>> if __name__ == '__main__':
>> print('Hello!')
>>
>> $ python web2py.py --no-banner -S myapp -R test2.py
>> Hello!
>>
>> Is this is expected behaviour? Is there a command line option, or a small 
>> change that permits cli scripts to continue to accept python2 syntax?
>>
>>  Thanks,
>> Jim
>>
>

-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[web2py] Print statement fails in command line script (v2.15.3)

2017-08-29 Thread Jim Karsten
I run many scripts from the command line. After upgrading to v2.15.3, I 
find print statements produce a SyntaxError. If I convert the statements to 
a print function it works. This was not a problem in v2.14.6.

To illustrate:

$ cat test.py
#!/usr/bin/env python
if __name__ == '__main__':
print 'Hello!'

$ python web2py.sh --no-banner -S myapp -R test.py
Traceback (most recent call last):
  File "/srv/http/web2py/2.15.3/web2py/gluon/shell.py", line 270, in run
execfile(startfile, _env)
  File "/root/tmp/test.py", line 4
print 'abc'
SyntaxError: invalid syntax

This works:

$ cat test2.py
#!/usr/bin/env python
if __name__ == '__main__':
print('Hello!')

$ python web2py.py --no-banner -S myapp -R test2.py
Hello!

Is this is expected behaviour? Is there a command line option, or a small 
change that permits cli scripts to continue to accept python2 syntax?

 Thanks,
Jim

-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[web2py] Re: Grid links in component do not open in new window properly

2014-11-14 Thread Jim Karsten
I think I can make this work. Thanks for your help Anthony and Leonel.

Jim

On Thursday, November 13, 2014 9:33:04 AM UTC-5, Anthony wrote:

 A simpler option might be to check whether the request is being made via 
 Ajax, and conditionally change the view:

 def inner(): 
 response.view = 'default/inner.load' if request.ajax else 
 'default/inner.html'
 grid = SQLFORM.grid(db.item) 
 return locals() 

 In that case, the .html view should extend the layout. Alternatively, you 
 could have a single view with a conditional extends:

 {{extend 'layout.html' if not request.ajax else None}}

 Note that the view cannot be compiled in that case.

 Anthony

 On Thursday, November 13, 2014 7:37:49 AM UTC-5, Leonel Câmara wrote:

 The problem is that URL, when an extension is not specified, inherits it 
 from the current URL which is .load in the case where they are loaded in 
 components with extension='load'.

 The thing is, this need to be load, otherwise inner will use the generic 
 HTML view extending layout.html and you don't want to have a layout inside 
 your layout when you're not opening in a new window.

 So basically inner needs to detect whether it's really a component or 
 not, generally that's what the extension is for. The only way I can 
 remember to do this would be with stupid javascript hacks. For instance, 
 you could make an inner.load view like this:

 {{=grid}}


 script
 $('.web2py_grid a').each(function() {
 if (typeof $(this).attr('href') !== 'undefined') {
 $(this).attr('href', $(this).attr('href').replace('.load', 
 '.html'));
 $(this).click(function(e) {
 if (e.which == 1) { // If we're left clicking
 if(e.ctrlKey) { // ctrl key being pressed also means new 
 tab
 window.open($(this).attr('href'));
 return false;
 } else {  // We really want to stay in the component
 $(this).attr('href', $(this).attr('href').replace(
 '.html', '.load'));
 }
 }
 });
 }
 });
 /script


 What this does is make all links have a .html extension, then if the user 
 is left clicking it makes it .load again. Yep, it's ugly, but you asked for 
 it.

 [edit] Added a return false that was needed.



-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
web2py-users group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[web2py] Re: Bug? request.vars not set by routes_in query string.

2014-09-26 Thread Jim Karsten
Ticket opened:
http://code.google.com/p/web2py/issues/detail?id=1990

On Friday, September 26, 2014 10:48:13 AM UTC-4, Massimo Di Pierro wrote:

  bug. please open a ticket so we track it and fix it.

 On Thursday, 25 September 2014 16:45:19 UTC-5, Jim Karsten wrote:

 I am setting a query string in routes_in but the request.vars is not 
 getting set. To replicate:
  
   

 In routes.py
 routes_in = (
 (BASE + '/$anything', '/welcome/default/index?aaa=111bbb=222'),
 ... 
 )
  
  

 Then in 
 applications/welcome/views/default/index.html
   

  
   

 div
 vars: {{=request.vars}}br
 env: {{=request.env.query_string}}
 /div
  
  

 When I visit the welcome app, request.vars displays empty but 
 request.env.query_string is set to 
 'aaa=111bbb=222'
 Is this expected or a bug?

 Tested with: Version 2.9.11-stable+timestamp.2014.09.15.23.35.11

 Thanks,
 Jim



-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
web2py-users group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[web2py] Bug? request.vars not set by routes_in query string.

2014-09-25 Thread Jim Karsten
I am setting a query string in routes_in but the request.vars is not 
getting set. To replicate:

   

In routes.py
routes_in = (
(BASE + '/$anything', '/welcome/default/index?aaa=111bbb=222'),
... 
)

  

Then in 
applications/welcome/views/default/index.html   
   

   

div
vars: {{=request.vars}}br
env: {{=request.env.query_string}}
/div

  

When I visit the welcome app, request.vars displays empty but 
request.env.query_string is set to 
'aaa=111bbb=222'
Is this expected or a bug?

Tested with: Version 2.9.11-stable+timestamp.2014.09.15.23.35.11

Thanks,
Jim

-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
web2py-users group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[web2py] Re: how to use gluon Expose

2014-06-26 Thread Jim Karsten
I was experimenting with Expose this week and I came across similar 
problems. For example, if I click on a subfolder link, the page refreshes 
but still displays the contents of the base folder.

After some digging, I think I found the problem. The code in Expose uses 
request.raw_args to determine the subfolder or link clicked. If routers is 
set in routes.py, request.raw_args is never set, so the args is always an 
empty list. If Expose used request.args, it would work.

I created a bug report here: 
http://code.google.com/p/web2py/issues/detail?id=1947


On Monday, April 21, 2014 10:14:57 AM UTC-4, Louis Amon wrote:

 It gets me the same result : broken links  images

 On Monday, April 21, 2014 3:28:00 PM UTC+2, Massimo Di Pierro wrote:

 Can you try:

 Expose(os.path.join(request.folder,'static','presse'))

 On Monday, 21 April 2014 06:01:42 UTC-5, Louis Amon wrote:

 Hi,

 I'm trying to expose a folder in my application, so I tried to use the 
 Expose function as described here 
 http://web2py.com/books/default/chapter/29/14/other-recipes#Publishing-a-folder

 My controller looks like :

 from gluon.tools import Expose
 def presse():
 files=Expose(request.folder+'static/presse')
 return dict(files=files)


 When I reach the correct URL, I see links for every file in that folder, 
 but they point to nothing.

 Same goes for image previews : they are broken.


 I checked one of the broken previews, and it points to : 
 /presse/logo.png, when it should point to /static/presse/logo.png.


 What did I do wrong ?



-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
web2py-users group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[web2py] Re: Grid in component edit twice issue

2014-02-12 Thread Jim Karsten
Anyone have any ideas? Is it possible somehow to force an ajax reload of 
the grid after the edit form is submitted? 

-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
web2py-users group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


[web2py] Re: Grid in component edit twice issue

2014-02-05 Thread Jim Karsten
Yes, I am using the packed app as is.

I dug into it a bit and the request.cid is getting dropped. I used Firebug 
to expose the http headers. 

* Load the component and display the grid 
http://127.0.0.1:8000/testy/default/component.load 
GET component.load 
web2py-component-element c435484472283 
web2py-component-location http://127.0.0.1:8000/testy 

* Click Edit load the edit form 
http://127.0.0.1:8000/testy/default/component.load/edit/person/1 
GET 1 
web2py-component-element c435484472283 
web2py-component-location http://127.0.0.1:8000/testy 

* Submit form 
http://127.0.0.1:8000/testy/default/component.load/edit/person/1 
POST 1 
web2py-component-element c435484472283 
web2py-component-location http://127.0.0.1:8000/testy 

* Redisiplay the grid. 
http://127.0.0.1:8000/testy/default/component.load 
GET component.load 


The two web2py-component http headers are dropped when the component is 
reloaded to display the grid after the form is submitted. 

On Tuesday, February 4, 2014 10:07:23 AM UTC-5, Niphlod wrote:

 are you using exactly the app you packed ?

 On Tuesday, February 4, 2014 2:53:41 AM UTC+1, Jim Karsten wrote:

 Originally the *Edit* button has this code: 

 a class=button btn href=
 https://groups.google.com/testy/default/component.load/edit/person/1; 
 data-w2p_target=c932772971645 data-w2p_method=GET 
 data-w2p_disable_with=default 
 span class=icon pen icon-pencil/span 
 span class=buttontext button title=EditEdit/span 
 /a 

 I then edit and submit and the Edit button then has this code: 

 a class=button btn href=
 https://groups.google.com/testy/default/component.load/edit/person/1; 
 data-w2p_disable_with=default 
 span class=icon pen icon-pencil/span 
 span class=buttontext button title=EditEdit/span
 /a 

 The *data-w2p_target* and *data-w2p_method* attributes appear to be 
 dropped.

 I use Firebug. I don't see any js errors in the Console. 
 https://groups.google.com/testy/default/component.load/edit/person/1 



-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
web2py-users group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


[web2py] Grid in component edit twice issue

2014-01-15 Thread Jim Karsten
I have a grid inside a component. When I click the 'Edit' button on a row, 
submit the Edit form, then click the 'Edit' button a second time, the page 
reloads with only the component. 

Controllers: 
def index(): 
Container controller. 
return dict() 

def people(): 
 Grid controller. 
 grid = SQLFORM.grid(db.person) 
 return dict(grid=grid) 

View: index.html 
{{extend 'layout.html'}} 
{{=LOAD(c='mycontroller', f='people', extension='load', ajax=True)}}

View: people.load 
{{=grid}} 

After some digging I suspect the problem is because *request.cid* gets 
reset to *None*. 
I am using web2py version: 2.8.2 

Any suggestions or is this a bug. 
Jim

-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
web2py-users group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


[web2py] Re: web2py 2.7.4 is OUT

2013-10-15 Thread Jim Karsten
I am having conditional model sorting problems. The issue is discussed here 
https://groups.google.com/forum/#!topic/web2py-developers/uE4-EwSo4_Q 

It appears a fix was put into place but only affected compiled apps. My app 
is not compiled.

I have the following models. 
models/0.py 
models/db.py 
models/clients/edit/db.py 

In v2.6.4 they loaded in the order above.
In v2.7.4 they load in this order: 
models/0.py 
models/clients/edit/db.py 
models/db.py 

The conditional model models/clients/edit/db.py depends on models/db.py for 
defining global variables. In v2.7.4 the app is crashing. 

-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
web2py-users group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


[web2py] Re: web2py 2.7.4 is OUT

2013-10-15 Thread Jim Karsten
I am having conditional model sorting problems. The issue is discussed here 
https://groups.google.com/forum/#!topic/web2py-developers/uE4-EwSo4_Q
It appears a fix was put into place but only affected compiled apps. My app 
is not compiled.

I have the following models.
models/0.py
models/db.py
models/clients/edit/db.py

In v2.6.4 they loaded in the order above.
In v2.7.4 they load in this order:

models/0.py
models/clients/edit/db.py
models/db.py

The conditional model models/clients/edit/db.py depends on models/db.py for
defining global variables. In v2.7.4 the app is crashing.

-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
You received this message because you are subscribed to the Google Groups 
web2py-users group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


[web2py] Ver 2.3.2 changes the order models are loaded.

2012-12-20 Thread Jim Karsten
I have database tables defined in models/db.py. I have a 
controller-specific model defined in a models/client subdirectory. Ver 
2.3.2 loads the models in a different order from ver 2.2.1. 

Ver 2.2.1
models/0.py
models/db.py
models/clients/edit/db.py

Ver 2.3.2
models/0.py
models/clients/edit/db.py
models/db.py

The models/clients/edit/db.py depends on variables defined in modes/db.py 
so I get errors with Ver 2.3.2 

The sort=False argument was removed from the listdir call in this line of 
gluon/compileapp.py def run_models_in() 

models = listdir(path, '^\w+\.py$', 0, sort=False) # Ver 2.2.1 
models = listdir(path, '^\w+\.py$', 0)   # Ver 2.3.2 

If I restore that, it works again. 

The issue was discussed here: 
https://groups.google.com/d/topic/web2py/ZfI7K9jW45w/discussion 

In Ver 2.2.1, files in the models directory are first loaded in 
alphabetically order. Then each subfolder is handled in order, model files 
in subfolders are loaded in alphabetical order. In Ver 2.3.2, all models 
are sorted by path name and then loaded in that order. 

I can rename subfolders so they are loaded properly but before I change 
anything I'd like to make sure the effects of dropping sort=False were 
intended. 

-- 





[web2py] Re: Ver 2.3.2 changes the order models are loaded.

2012-12-20 Thread Jim Karsten
Sounds good. Thanks guys

On Thursday, December 20, 2012 1:12:20 PM UTC-5, Jim Karsten wrote:

 I have database tables defined in models/db.py. I have a 
 controller-specific model defined in a models/client subdirectory. Ver 
 2.3.2 loads the models in a different order from ver 2.2.1. 

 Ver 2.2.1
 models/0.py
 models/db.py
 models/clients/edit/db.py

 Ver 2.3.2
 models/0.py
 models/clients/edit/db.py
 models/db.py

 The models/clients/edit/db.py depends on variables defined in modes/db.py 
 so I get errors with Ver 2.3.2 

 The sort=False argument was removed from the listdir call in this line of 
 gluon/compileapp.py def run_models_in() 

 models = listdir(path, '^\w+\.py$', 0, sort=False) # Ver 2.2.1 
 models = listdir(path, '^\w+\.py$', 0)   # Ver 2.3.2 

 If I restore that, it works again. 

 The issue was discussed here: 
 https://groups.google.com/d/topic/web2py/ZfI7K9jW45w/discussion 

 In Ver 2.2.1, files in the models directory are first loaded in 
 alphabetically order. Then each subfolder is handled in order, model files 
 in subfolders are loaded in alphabetical order. In Ver 2.3.2, all models 
 are sorted by path name and then loaded in that order. 

 I can rename subfolders so they are loaded properly but before I change 
 anything I'd like to make sure the effects of dropping sort=False were 
 intended. 

-- 





[web2py] sessions2trash.py not working in v2.2.1, fix included

2012-10-24 Thread Jim Karsten
current.response._dbtable_and_field is referenced in sessions2trash.py. 
That value was replaced in version 2.2.1 with 
current.response.session_db_table, current.response.session_db_record_id, 
and current.response.session_db_unique_key. 

Attached is a fixed version of sessions2trash.py. 

-- 



#!/usr/bin/env python
# -*- coding: utf-8 -*-

sessions2trash.py

Run this script in a web2py environment shell e.g. python web2py.py -S app
If models are loaded (-M option) auth.settings.expiration is assumed
for sessions without an expiration. If models are not loaded, sessions older
than 60 minutes are removed. Use the --expiration option to override these
values.

Typical usage:

# Delete expired sessions every 5 minutes
nohup python web2py.py -S app -M -R scripts/sessions2trash.py 

# Delete sessions older than 60 minutes regardless of expiration,
# with verbose output, then exit.
python web2py.py -S app -M -R scripts/sessions2trash.py -A -o -x 3600 -f -v

# Delete all sessions regardless of expiry and exit.
python web2py.py -S app -M -R scripts/sessions2trash.py -A -o -x 0


from __future__ import with_statement
from gluon import current
from gluon.storage import Storage
from optparse import OptionParser
import cPickle
import datetime
import os
import stat
import time

EXPIRATION_MINUTES = 60
SLEEP_MINUTES = 5
VERSION = 0.3


class SessionSet(object):
Class representing a set of sessions

def __init__(self, expiration, force, verbose):
self.expiration = expiration
self.force = force
self.verbose = verbose

def get(self):
Get session files/records.
raise NotImplementedError

def trash(self):
Trash expired sessions.
now = datetime.datetime.now()
for item in self.get():
status = 'OK'
last_visit = item.last_visit_default()

try:
session = item.get()
if session.auth:
if session.auth.expiration and not self.force:
self.expiration = session.auth.expiration
if session.auth.last_visit:
last_visit = session.auth.last_visit
except:
pass

age = 0
if last_visit:
age = total_seconds(now - last_visit)

if age  self.expiration or not self.expiration:
item.delete()
status = 'trashed'

if self.verbose  1:
print 'key: %s' % str(item)
print 'expiration: %s seconds' % self.expiration
print 'last visit: %s' % str(last_visit)
print 'age: %s seconds' % age
print 'status: %s' % status
print ''
elif self.verbose  0:
print('%s %s' % (str(item), status))


class SessionSetDb(SessionSet):
Class representing a set of sessions stored in database

def __init__(self, expiration, force, verbose):
SessionSet.__init__(self, expiration, force, verbose)

def get(self):
Return list of SessionDb instances for existing sessions.
sessions = []
table = current.response.session_db_table
for row in table._db(table.id  0).select():
sessions.append(SessionDb(row))
return sessions


class SessionSetFiles(SessionSet):
Class representing a set of sessions stored in flat files

def __init__(self, expiration, force, verbose):
SessionSet.__init__(self, expiration, force, verbose)

def get(self):
Return list of SessionFile instances for existing sessions.
path = os.path.join(request.folder, 'sessions')
return [SessionFile(os.path.join(path, x)) for x in os.listdir(path)]


class SessionDb(object):
Class representing a single session stored in database

def __init__(self, row):
self.row = row

def delete(self):
table = current.response.session_db_table
self.row.delete_record()
table._db.commit()

def get(self):
session = Storage()
session.update(cPickle.loads(self.row.session_data))
return session

def last_visit_default(self):
if isinstance(self.row.modified_datetime, datetime.datetime):
return self.row.modified_datetime
else:
try:
return datetime.datetime.strptime(self.row.modified_datetime, '%Y-%m-%d %H:%M:%S.%f')
except:
print 'failed to retrieve last modified time (value: %s)' % self.row.modified_datetime

def __str__(self):
return self.row.unique_key


class SessionFile(object):
Class representing a single session stored as a flat file

def __init__(self, filename):
self.filename = filename

def delete(self):
os.unlink(self.filename)

def get(self):
session = Storage()
with open(self.filename, 'rb+') as f:

[web2py] Re: Custom import creates module name conflicts (2.1.1)

2012-10-22 Thread Jim Karsten
Thanks, Massimo.

I upgraded to web2py v2.2.1 and that patch addresses the 'ImportError: 
cannot import name web2py_uuid' error.

I still have name clashes with my constants.py module and MySQLdb. For now 
I am going to rename my module. I have some reservations about the new 
custom_importer as it can produce these clash problems and there is little 
I can do to prepare for them or protect my code from them.

On Friday, October 19, 2012 7:37:44 PM UTC-4, Massimo Di Pierro wrote:

 Good catch. Fixed in trunk

 On Friday, 19 October 2012 16:54:54 UTC-5, Jim Karsten wrote:

 I upgraded to v 2.1.1 and now see problems with module name conflicts due 
 to the custom importer. Previously I used v2.0.9 without problems.

 I have a custom application module named utils.py. This appears to 
 conflict with the gluon.utils module. I was able to simulate using the 
 basic web2py zip file and then creating a simple module 
 applications/welcome/modules/utils.py. When I access the welcome default 
 page, I get this error: 

 Traceback (most recent call last): 
 File /root/tmp/web2py/web2py/gluon/restricted.py, line 209, 
 in restricted exec ccode in environment 
 File /root/tmp/web2py/web2py/applications/welcome/models/db.py, line 
 42, 
 in from gluon.tools import Auth, Crud, Service, PluginManager, prettydate 
 File /root/tmp/web2py/web2py/gluon/custom_import.py, line 89, 
 in custom_importer return 
 NATIVE_IMPORTER(name,globals,locals,fromlist,level)
 File /root/tmp/web2py/web2py/gluon/tools.py, line 30, in from utils 
 import web2py_uuid 
 ImportError: cannot import name web2py_uuid 

 I disabled the custom importer by issuing a return immediately in 
 gluon/custom_import.py def custom_import_install() and the problem goes 
 away. 

 I can also correct this specific issue if I change this line in 
 gluon/tools.py 

 -from utils import web2py_uuid 
 +from gluon.utils import web2py_uuid 

 This last change works, but it isn't a complete solution. For example, in 
 another application I have a constants.py module. It is conflicting with a 
 constants module MySQLdb makes use of. Deep in the code of MySQLdb there is 
 a line:

 from constants import CLIENT, FIELD_TYPE 

 That import fails as it tries to find those classes in my custom module. 
 I can always rename my custom module, but this becomes a cat and mouse 
 game. I can't know every module name already in use. 

 Any suggestions for this? It's a bit of a show stopper for me. Perhaps an 
 option should be available to disable the custom importer. 



-- 





[web2py] Custom import creates module name conflicts (2.1.1)

2012-10-19 Thread Jim Karsten
I upgraded to v 2.1.1 and now see problems with module name conflicts due 
to the custom importer. Previously I used v2.0.9 without problems.

I have a custom application module named utils.py. This appears to conflict 
with the gluon.utils module. I was able to simulate using the basic web2py 
zip file and then creating a simple module 
applications/welcome/modules/utils.py. When I access the welcome default 
page, I get this error: 

Traceback (most recent call last): 
File /root/tmp/web2py/web2py/gluon/restricted.py, line 209, 
in restricted exec ccode in environment 
File /root/tmp/web2py/web2py/applications/welcome/models/db.py, line 42, 
in from gluon.tools import Auth, Crud, Service, PluginManager, prettydate 
File /root/tmp/web2py/web2py/gluon/custom_import.py, line 89, 
in custom_importer return 
NATIVE_IMPORTER(name,globals,locals,fromlist,level)
File /root/tmp/web2py/web2py/gluon/tools.py, line 30, in from utils 
import web2py_uuid 
ImportError: cannot import name web2py_uuid 

I disabled the custom importer by issuing a return immediately in 
gluon/custom_import.py def custom_import_install() and the problem goes 
away. 

I can also correct this specific issue if I change this line in 
gluon/tools.py 

-from utils import web2py_uuid 
+from gluon.utils import web2py_uuid 

This last change works, but it isn't a complete solution. For example, in 
another application I have a constants.py module. It is conflicting with a 
constants module MySQLdb makes use of. Deep in the code of MySQLdb there is 
a line:

from constants import CLIENT, FIELD_TYPE 

That import fails as it tries to find those classes in my custom module. I 
can always rename my custom module, but this becomes a cat and mouse game. 
I can't know every module name already in use. 

Any suggestions for this? It's a bit of a show stopper for me. Perhaps an 
option should be available to disable the custom importer. 

-- 





[web2py] Re: MySQLdb prints warnings to stdout

2012-09-17 Thread Jim Karsten
http://code.google.com/p/web2py/issues/detail?id=1007

-- 





[web2py] MySQLdb prints warnings to stdout

2012-09-14 Thread Jim Karsten
I use MySQL and after upgrading to 2.0.x I see MySQL warnings from time to 
time printed to stdout. It appears they originate from MySQLdb.

Here is a simple example of how to produce the warnings.

db.executesql('DROP TABLE IF EXISTS non_existent_table')
/path/to/2.0.8/web2py/gluon/dal.py:1653: Warning: Unknown table 
'non_existent_table'
  ret = self.cursor.execute(*a, **b)

Here is how I solved it. In *gluon/dal.py* add:

import warnings

class MySQLAdapter(BaseAdapter):

def execute(self, *a, **b):
if 'MySQL(MySQLdb)' in DRIVERS:
with warnings.catch_warnings(record=True) as warning_messages:
result = self.log_execute(*a, **b)
for w in warning_messages:
logger.warning(w)
else:
result = self.log_execute(*a, **b)
return result

Could that be considered for the trunk?

-- 





[web2py] SQLFORM formstyle argument changes

2012-09-10 Thread Jim Karsten
The *SQLFORM formstyle* argument can change from a string to a function. 
For example:

sqlform = SQLFORM(db.mytable, formstyle='table3cols')

Now (sqlform.formstyle == 'table3cols') returns *False*. *sqlform.formstyle*is 
now a function named 
*formstyle_table3cols*.

I haven't had any problems with it but is this not poor design?

-- 





[web2py] Re: hideerror in widget not working

2012-08-26 Thread Jim Karsten


On Friday, August 24, 2012 4:16:30 PM UTC-4, Anthony wrote:

 For now, a workaround might be to subclass INPUT and replace the xml() 
 method (http://code.google.com/p/web2py/source/browse/gluon/html.py#1692) 
 so it doesn't check for hideerror and simply displays the widget without 
 any error.

 Anthony

 On Friday, August 24, 2012 3:30:02 PM UTC-4, Jim Karsten wrote:

 I created a custom widget including an *INPUT* with a 
 *hideerror=True*parameter. It did not hide error messages.

 To simulate:

 in model:
 class 
 SimpleWidget(FormWidget): 
 _class = 
 'string'   
  


 
 @classmethod
 def widget(cls, field, value, 
 **attributes):
 default = 
 dict( 
 _type = 
 'text', 
 value = (not value is None and str(value)) or 
 '',   
 
 )   
 attr = cls._attributes(field, default, 
 **attributes)
  


 return INPUT(hideerror=True, 
 **attr)
  


 db.define_table('atable',


 Field('afield', 
 'string',   
 
 widget=SimpleWidget.widget, 
 
 requires=IS_NOT_EMPTY(),
 
 ),  
 
 migrate=True,   
 
 )   
  


 In controller:
   
 def 
 test_hideerror():   
 response.generic_patterns = 
 ['html']
 form = crud.update(db.atable, 
 request.args(0))  
 return dict(form=form)   

 Submit form with the 'afield' empty and it displays an error.

 This patch fixes it but it may change the logic in a way not originally 
 intended. In *gluon/html.py class DIV() def _traverse()*, 
 change:   
  


 
 c['hideerror']=hideerror
  


 to  

 if 'hideerror' not in 
 c.attributes: 
 c['hideerror']=hideerror   

 The patch only sets the hideerror attribute if it doesn't already exist. 
 With tet patch, if the widget has *hideerror=True*, if you use *
 form.validate(hideerror=False)*, a field using the widget will still 
 hide the error.


Do you consider it a bug or is that intended behaviour?

-- 





[web2py] hideerror in widget not working

2012-08-24 Thread Jim Karsten
I created a custom widget including an *INPUT* with a 
*hideerror=True*parameter. It did not hide error messages.

To simulate:

in model:
class 
SimpleWidget(FormWidget): 
_class = 
'string'   



@classmethod
def widget(cls, field, value, 
**attributes):
default = 
dict( 
_type = 
'text', 
value = (not value is None and str(value)) or 
'',   

)   
attr = cls._attributes(field, default, 
**attributes)


return INPUT(hideerror=True, 
**attr)


db.define_table('atable',   

Field('afield', 
'string',   

widget=SimpleWidget.widget, 

requires=IS_NOT_EMPTY(),

),  

migrate=True,   

)   


In controller:
  
def 
test_hideerror():   
response.generic_patterns = 
['html']
form = crud.update(db.atable, 
request.args(0))  
return dict(form=form)   

Submit form with the 'afield' empty and it displays an error.

This patch fixes it but it may change the logic in a way not originally 
intended. In *gluon/html.py class DIV() def _traverse()*, 
change:   



c['hideerror']=hideerror


to  
if 'hideerror' not in 
c.attributes: 
c['hideerror']=hideerror   

The patch only sets the hideerror attribute if it doesn't already exist. 
With tet patch, if the widget has *hideerror=True*, if you use *
form.validate(hideerror=False)*, a field using the widget will still hide 
the error.

-- 





[web2py] Re: Forms in multiple windows

2012-06-05 Thread Jim Karsten


On Monday, June 4, 2012 4:36:34 PM UTC-4, Anthony wrote:

 Massimo pointed out a flaw in my solution in that it would create an
 ever-growing number of session variables and would be vulnerable to a DoS
 attack.


 Maybe by default it could cycle through a small number of formnames (e.g., 
 _formname = _formname + '_1', etc.). So, for any given base _formname, 
 there could be up to, say, 5 distinct formnames in the session, which would 
 allow the user to open a handful of browser windows and be able to submit 
 from any of them.

 Anthony

 
I had considered something similar to this. It reduces the probability that 
a users gets a invalid form, but it's still possible.

What I see happening with users and my app is this:.

The default page has a form on it, one that is frequently used for entering 
customers into the system. At some point the user opens a page in a new 
window. They use this window to do various activities including entering 
any number of new customers using the form on the default page. At some 
point they close the window. The original window is now their 'active' 
window. They enter a new customer with the original form. It fails because 
the session formkey is no longer valid.

In general, a form failing isn't the end of the world. The user can just 
re-enter the data and submit it. It would be nice if I could give them some 
feed back. However, with the particular default form I am using, they 
require asking customers for their personal information, address, phone, 
etc. When the form fails, they have to ask again which does not make 
customers happy.

So in this case, I'd like to do what I can to make it work every time. It 
should be noted, my app is used internally and several people may share a 
computer at a counter. Often they open multiple browser windows and tabs in 
order to not disturb the browser left by another person.


 


[web2py] Forms in multiple windows

2012-06-04 Thread Jim Karsten
Could we get a discussion going about web2py handling forms in multiple 
windows? A form may not submit as expected if a second window or tab is 
opened with the same form. Here are steps to reproduce the issue.

1. Create a page with a form. The form can be created by Crud or SQLFORM.
2. Open the page in a window. Open the page in a second window.
3. Submit the form in the second window. This works fine.
4. Go back to the first window. Submit the form. The input is not saved.

I produced a ticket for this problem (Issue 825 
http://code.google.com/p/web2py/issues/detail?id=825) with a suggestion for 
a solution based on the discussion in this thread: 
https://groups.google.com/d/topic/web2py/X-GGxuvea-g/discussion

Massimo pointed out a flaw in my solution in that it would create an
ever-growing number of session variables and would be vulnerable to a DoS
attack.

While maybe not a common problem, opening a page in a second window does 
not seem to be something all that unusual. Should web2py forms be expected 
to handle this? 


[web2py] Re: Link in a validator error message.

2012-05-28 Thread Jim Karsten
Ok, I may try subclassing the validator and removing the translate calls 
since I'm not doing and language translation.

Thanks,
Jim


[web2py] Link in a validator error message.

2012-05-24 Thread Jim Karsten
I would like to include a link in a validator error_message. The 
translate() function converts the link such that the raw HTML gets 
displayed instead. Anyone have any suggestions for how to get around this 
problem?

Jim Karsten


[web2py] Component reshows validation messages.

2012-01-23 Thread Jim Karsten
If a page has a component, the validation error messages may display a 
second time. In web2py_ajax.html the function web2py_ajax_init() gets 
called twice, first when the main page loads called by 
*jQuery(document).ready(function() 
{});* and second when the component loads, called by function *
web2py_ajax_page()*. If the component loads quickly, the second display may 
not be visible. I am working with a component that has a minor delay as it 
loads data and the validation errors on the main page form display, then 
hide and display again.

I made this change to function web2py_ajax_init()
was:  
  jQuery('.error').hide().slideDown('slow');
now: 
  jQuery('.error').each( function () 
{   


if (! jQuery(this).data('_error_shown')) 
{  
  jQuery(this).hide().slideDown('slow').data('_error_shown', 
1);

}   
  });  

Each error message displays only once now.


[web2py] Re: Component reshows validation messages.

2012-01-23 Thread Jim Karsten
Yeah, my version is a bit dated. I'll have a look at the newer stuff. 
Thanks Anthony.


[web2py] Re: web2py 1.99.3 is OUT

2011-12-13 Thread Jim Karsten
Ok, sounds good. I'll convert the code to use hidden argument explained in 
Chapter 7. Thanks for the explanation, Anthony.


[web2py] Re: web2py 1.99.3 is OUT

2011-12-12 Thread Jim Karsten
SQLFORM.factory hidden fields are not working the same in 1.99.3 as in 
1.99.2. Here is a simple example 
form = SQLFORM.factory( 
Field('text_field'), 
Field('hidden_field', type='hidden', default='test'),) 

The hidden field is not hidden. Here is the html produced. The first is 
from 1.99.2, the second 1.99.3. 

input id=no_table_hidden_field class=hidden type=text value=test 
name=hidden_field style=display: none; 
input id=no_table_hidden_field class=string type=text value=test 
name=hidden_field 

If I use readable=False, writable=False, the field is hidden from the 
display but then no input is created for it. I have javascript code 
accessing the hidden input value. I can probably work around the problem 
using this syntax. 

form = SQLFORM.factory( 
Field('text_field'), 
hidden={'hidden_field': 'test'}) 

However, the input produced has no id or class attribute which I was using. 

input value=test name=hidden_field type=hidden 

Is what I'm seeing a bug or was the Field(... type='hidden'...) syntax 
never intended to work? 

[web2py] Re: 1.99 gluon/tools.py replace_id mishandling url [SOLVED]

2011-09-28 Thread Jim Karsten
I found a work around. I had two decorators on the index controller 
functions. I separated that function into two putting a decorator on each. 

Previously: 
@requires_session_option 
@auth.requires_login 
def index(): 
return dict() 

Now: 
@auth.requires_login 
def index(): 
redirect(URL('get_session_option')) 

@requires_session_option 
def get_session_option(): 
return dict()

Not sure if that's optimal but it's working.


[web2py] 1.99 gluon/tools.py replace_id mishandling url

2011-09-27 Thread Jim Karsten
Since upgrading to 1.99 (I tried both 1.99.1 and 1.99.2) I get this error: 

File /srv/http/myapp.com/web2py/gluon/tools.py, line 79, in replace_id 
return url % form.vars 
TypeError: float argument required, not Storage 

The value of url is: 

/myapp/misc/employee_select?next_url=%2Fmyapp%2Fdefault%2Findex 

The modulo operator is interpreting the '%2F' as a conversion type flags. 
Any suggestions?


Re: [web2py] JqGrid module

2011-08-05 Thread Jim Karsten
Johann, I updated the jqgrid application to include demos for using complex 
queries and accessing data from a webservice. Demos are found in the 
default.py controller. If you cloned the git repo, just run 'git pull' in 
the repo directory and you should get the latest.

Cheers,
Jim


[web2py] Re: jqgrid widget with no table source

2011-08-05 Thread Jim Karsten
xenebros, I updated the jqgrid application avaliable on the web2pyslice page 
to include a demo for accessing data from a webservice. Demos are found in 
the default.py controller.

Cheers,
Jim

[web2py] Re: jqgrid widget with no table source

2011-08-03 Thread Jim Karsten
I am working on a jqgrid module. There is a chance it can work for what you 
are trying to do. The module is designed around web2py tables but the JqGrid 
class can be subclassed and the data method, the method used to access the 
data for the jqgrid rows can be overridden with whatever you like. As long 
as it returns data in the expected format, it should work.

The application is here: http://www.web2pyslices.com/slices/take_slice/140

Let me know if you need help with that.


[web2py] JqGrid module

2011-07-30 Thread Jim Karsten
Ray Luo and I are developing a web2py jqgrid module that allows you to 
insert a jqgrid into a page with only a few lines of code.

# In 
model   
   



db.define_table('category', 

Field('name', label='Name of Category'), 
format='%(name)s') 


db.define_table('things',   


Field('name'),  
Field('quantity', 
'integer'),   

Field('owner'), 

Field('price','double'),
Field('category', db.category)) 



# In 
controller 


JqGrid = local_import('jqgrid', app='jqgrid', 
reload=True).JqGrid   
JqGrid.initialize_response_files(globals(), theme='ui-lightness', 
lang='en')


def 
things():   
return JqGrid(globals(), db.things)()   


See http://www.web2pyslices.com/slices/take_slice/140



[web2py] Re: Two fields with autocomplete in a single form fail

2011-07-21 Thread Jim Karsten
This was posted awhile ago but in case anyone else runs into this, the 
problem is the cities and categories fields have both the same name 'name'. 
The AutocompleteWidget *keyword* property gets set to the same value. The 
solution is to provide distinct *keyword* arguments.

Field('city', 
widget=SQLFORM.widgets.autocomplete(request, 
db.cities.name, 
id_field=db.cities.id,
keyword='_autocomplete_cities_%(fieldname)s')),

Field('category', 
widget=SQLFORM.widgets.autocomplete(request, 
db.categories.name http://db.cities.name/, 
id_field=db.categories.id http://db.cities.id/,
keyword='_autocomplete_categories_%(fieldname)s')),

I wonder if the default keyword argument should include the table name.

keyword = '_autocomplete_%(tablename)s_%(fieldname)s'
self.keyword = keyword % dict(tablename=field.tablename, 
fieldname=field.name)


[web2py] Reponse.flash clobbers session.flash

2011-07-09 Thread Jim Karsten
When controller2 is called it redirects to controller1. The session.flash 
message is lost. Any suggestions for how to prevent the response.flash from 
clobbering the session.flash?

def controller1():
form = 
SQLFORM.factory(Field('myfield'))
if 
form.accepts(request.vars,session):  
response.flash = 'Record 
updated'   
elif 
form.errors:   
response.flash = 'Form contains 
errors' 

else:   
response.flash = 'Please fill in the 
form'  
return 
dict(form=form)  


def 
controller2():  
session.flash = 'Message from session 
flash.'   
redirect(URL('controller1'))


Re: [web2py] Reponse.flash clobbers session.flash

2011-07-09 Thread Jim Karsten
Yeah, I'm aware of that. However, what if I want that message when 
controller1 is called on its own, not as a redirect from controller2. In the 
example I provided the message isn't very useful, but in some case the
message can be.


Re: [web2py] Reponse.flash clobbers session.flash

2011-07-09 Thread Jim Karsten
You could check whether there's something in response.flash and not clobber 
it, if you liked. Do this in a models file, for example? 

Re: [web2py] Reponse.flash clobbers session.flash

2011-07-09 Thread Jim Karsten
Ah, I see. Ok, i'll give that some thought.


[web2py] Re: Import from another application in 1.96.x

2011-06-15 Thread Jim Karsten
I understand what your saying and I do use that approach at times but I 
don't think it is ideal for what I'm looking at. Maybe I should explain 
further. 

While developing an application I might create a module in the applications 
modules directory. Then working on another application I see a need for that 
module from the first app. I could copy the module to the second 
application's module directory but that would create duplicate code. Instead 
I created an application called 'shared' used solely for it's modules 
directory. It acts as a library of these utility modules. All applications 
import from the shared modules as needed. It's working but feels a bit of a 
hack. With the changes to the import in 1.96.x, I thought there might be a 
better approach. 

I wonder if I should be using the site-packages directory instead of a 
shared app. 

[web2py] Re: Import from another application in 1.96.x

2011-06-14 Thread Jim Karsten
Ok, that might work.
Since many controllers make use of the other application, I'd rather not 
have to add the  'sys.path.append' line in each. I was thinking of adding it 
to a model file. Is that reasonable or would you recommend a better 
location?


[web2py] Re: Import from another application in 1.96.x

2011-06-13 Thread Jim Karsten
Anyone?


[web2py] Import from another application in 1.96.x

2011-06-10 Thread Jim Karsten
In a controller of one application I import classes from a module in another 
application using either of these syntaxes. 

from applications.another_app.modules.mymodule import MyClass 
MyClass = local_import('mymodule', app='another_app').MyClass 

Is there a better way to do that with the changes in 1.96.x? 


[web2py] Validator: one of several fields must be non-empty

2011-06-09 Thread Jim Karsten
This validator handles a case where at least one of several fields must be 
non-blank. 

class IS_NOT_ALL_EMPTY(object): 
Class representing a validator requiring at least one non-empty field in 
a set.  
def __init__(self, others, 
error_message='Enter a value in at least one field'): 
self.others = others 
self.error_message = error_message 

def __call__(self, value): 
okay = (value, None) 
error = (value, self.error_message) 
# Return okay either the 'value', or one of self.others is not empty. 
values = [] 
values.append(value) 
values.extend(self.others) 
empties = [] 
for v in values: 
unused_v, empty = is_empty(v) 
empties.append(empty) 
# Example empties == [True, True, False] 
# If one False exists, it's valid 
if reduce(lambda x, y: x and y, empties): 
return error 
return okay 

Usage: 

db.define_table('contact', 
Field('name', 'string' 
requires=IS_NOT_ALL_EMPTY([request.vars.organization], 
error_message='Enter a name or an organization'), 
), 
Field('organization', 'string', 
requires=IS_NOT_ALL_EMPTY([request.vars.name], 
error_message='Enter a name or an organization'),
)) 

Cheers, 
Jim Karsten 

[web2py] Re: Virtual fields and with_alias error

2011-05-26 Thread Jim Karsten
Done.
Issue 280: Virtual fields and with_alias error 


[web2py] Virtual fields and with_alias error

2011-05-25 Thread Jim Karsten
I am getting an exception raised when I combine virtual fields and aliases. 
Here is an example that produces the error. The example may not have 
practical use. It is used for illustration only. 

# In models/db.py 
db.define_table('person', 
Field('first_name'), 
Field('last_name')) 
db.define_table('couple', 
Field('husband_id', 
requires=IS_IN_DB(db, 'person.id', '%(first_name)s')), 
Field('wife_id', 
requires=IS_IN_DB(db, 'person.id', '%(first_name)s') 
)) 

class PersonVirtFields(object): 
def name(self): 
return %s %s % (self.person.first_name, self.person.last_name) 

db.person.virtualfields.append(PersonVirtFields()) 

# In controller 
def index(): 
husband = db.person.with_alias('husband') 
rows = db(db.couple.id0).select( husband.first_name, 
left=husband.on(husband.id==db.couple.husband_id)) 
return dict(rows=rows) 

The exception is: 
AttributeError: 'PersonVirtFields' object has no attribute 'person' 

I can avoid the exception if I change the line in the PersonVirtFields name 
method to: 
return %s %s % (self.husband.first_name, self.husband.last_name) 

The virtual class appears to be receiving the table name as per its alias. 
Is this a bug or is that expected behaviour? 

Regards, 
Jim Karsten 

[web2py] Re: Insert blank record crashes in sqlite

2011-05-12 Thread Jim Karsten
Here are two possible solutions, both for gluon.dal.py: 

class BaseAdapter(ConnectionPool): 

def insert(self,table,fields): 
if not fields: 
raise SyntaxError, 'No fields to insert' 
query = self._insert(table,fields) 
... 
return rid 

or 

class SQLiteAdapter(BaseAdapter): 

def insert(self,table,fields): 
if not fields: 
raise SyntaxError, 'No fields to insert' 
return BaseAdaptor.insert(self, table, fields) 

The first will affect all dbengines. The second is SQLite specific but there 
may be other dbengines that would benefit from that fix as well. 

[web2py] Insert blank record crashes in sqlite

2011-05-11 Thread Jim Karsten
I use the following line in a controller to add a blank record. 

record_id = db.mytable.insert() 

This works fine using MySQL but crashes with sqlite. The error is: 

File /root/staging/1.94.5/web2py/gluon/dal.py, line 4344, in insert 
  return self._db._adapter.insert(self,self._listify(fields)) 
File /root/staging/1.94.5/web2py/gluon/dal.py, line 763, in insert 
  raise e 
OperationalError: near ): syntax error 

The SQL is:   INSERT INTO mytable() VALUES (); 

I get a similar error in the sqlite console but it works fine in MySQL 

sqlite INSERT INTO mytable() VALUES (); 
Error: near ): syntax error 

Not sure if this is a bug or not. Some dal methods produce an syntax error 
if no fields are provided. 

db(db.mytable.id == 1).update()
SyntaxError: No fields to update 

Should insert() without fields be a syntax error? 

Regards, 
Jim Karsten 

[web2py] sessions2trash.py improved

2011-05-06 Thread Jim Karsten
Ross Peoples and I created a new version of sessions2trash.py. Features 
include: 

   - Deletes expired sessions files only based on sessions actual expiration 
   value. 


   - An option to delete sessions files once, then exit. 


   - An option to set the expiration time, overriding the default 60 
   minutes. 


   - An option to modify the sleep time between executions. 


   - Ability to delete all sessions files regardless of expiration time. 

For help: 
python web2py.py -S app -M -R scripts/sessions2trash.py -A --help 

Examples of typical usage are incuded in the script comments. This script 
works with session files only. 

Everyone is welcome to it. 

Regards 
Jim Karsten #!/usr/bin/env python
# -*- coding: utf-8 -*-

sessions2trash.py

Run this script in a web2py environment shell e.g. python web2py.py -S app
If models are loaded (-M option) auth.settings.expiration is assumed
for sessions without an expiration. If models are not loaded, sessions older
than 60 minutes are removed. Use the --expiration option to override these
values.

Typical usage:

# Delete expired sessions every 5 minutes
nohup python web2py.py -S app -M -R scripts/sessions2trash.py 

# Delete sessions older than 60 minutes regardless of expiration,
# with verbose output, then exit.
python web2py.py -S app -M -R scripts/sessions2trash.py -A -o -x 3600 -f -v

# Delete all sessions regardless of expiry and exit.
python web2py.py -S app -M -R scripts/sessions2trash.py -A -o -x 0


from gluon.storage import Storage
from optparse import OptionParser
import cPickle
import datetime
import os
import stat
import time

EXPIRATION_MINUTES = 60
SLEEP_MINUTES = 5
VERSION = 0.3


def main():
Main processing.

usage = '%prog [options]' + '\nVersion: %s' % VERSION
parser = OptionParser(usage=usage)

parser.add_option('-o', '--once',
action='store_true', dest='once', default=False,
help='Delete sessions, then exit.',
)
parser.add_option('-s', '--sleep',
dest='sleep', default=SLEEP_MINUTES * 60, type=int,
help='Number of seconds to sleep between executions. Default 300.',
)
parser.add_option('-x', '--expiration',
dest='expiration', default=None, type=int,
help='Expiration value for sessions without expiration (in seconds)',
)
parser.add_option('-f', '--force',
action='store_true', dest='force', default=False,
help=('Ignore session expiration. '
'Force expiry based on -x option or auth.settings.expiration.')
)
parser.add_option('-v', '--verbose',
action='store_true', dest='verbose', default=False,
help='Print verbose output.',
)

(options, unused_args) = parser.parse_args()

expiration = options.expiration
if expiration is None:
try:
expiration = auth.settings.expiration
except:
expiration = EXPIRATION_MINUTES * 60

while True:
trash_session_files(expiration, options.force, options.verbose)

if options.once:
break
else:
time.sleep(options.sleep)


def trash_session_files(expiration, force=False, verbose=False):

Trashes expired session files.

Arguments::
expiration: integer, expiration value to use for sessions without one.
force: If True, ignores session expiration and use value of
expiration argument.
verbose: If True, print names of sessions trashed.

now = datetime.datetime.now()

path = os.path.join(request.folder, 'sessions')
for file in os.listdir(path):
filename = os.path.join(path, file)
last_visit = datetime.datetime.fromtimestamp(
os.stat(filename)[stat.ST_MTIME])

if expiration  0:
try:
f = open(filename, 'rb+')
session = Storage()
session.update(cPickle.load(f))
f.close()

if session.auth:
if session.auth.expiration and not force:
expiration = session.auth.expiration
if session.auth.last_visit:
last_visit = session.auth.last_visit
except:
pass

if expiration == 0 or \
total_seconds(now - last_visit)  expiration:
os.unlink(filename)
if verbose:
print('Session trashed: %s' % file)


def total_seconds(delta):

Adapted from Python 2.7's timedelta.total_seconds() method.

Args:
delta: datetime.timedelta instance.

return (delta.microseconds + (delta.seconds + (delta.days * 24 * 3600)) * \
10 ** 6) / 10 ** 6

main()


[web2py] Re: Confusion using experts4solutions

2011-05-02 Thread Jim Karsten
Just to clarify, I posted on the freelance sites not to get coders competing 
for jobs, but to make use of their tools. I have lots of work and a healthy 
budget and I'm looking for a web2py professional. The job postings were 
intended to be just a stepping stone. 

Jim Karsten 

[web2py] Confusion using experts4solutions

2011-04-27 Thread Jim Karsten
We are working on a new web2py project. We are making progress and web2py 
has certainly improved our production but we could use some help. The 
experts4solutions site looks very promising but currently it doesn't provide 
details for handling various issues. 

We posted a couple of small jobs on elance, oDesk and vWorker, then sent the 
links each member of experts4solutions. 

Some of the issues the freelancing sites handle that we have a concern about 
include: job posting tools, contractor filtering tools, payment processing, 
commitment guarantees (for example, payment held in escrow), dispute 
settlements and arbitration, legal terms and software licences. 

Is our approach acceptable? What have others done in the past? 

Regards, 
Jim Karsten 

[web2py] web2py and freelancing services

2011-04-21 Thread Jim Karsten
We are looking for experienced developers to work on a web2py project.
We are considering using a freelancing service like vworker.com
(formerly rent-a-coder) or elance. Does anyone have any experience
with these companies?

Jim Karsten


[web2py] Re: web2py and freelancing services

2011-04-21 Thread Jim Karsten
Looks interesting. Thanks for the link.

On Apr 21, 4:09 pm, Kenneth Lundström kenneth.t.lundst...@gmail.com
wrote:
 Hello Jim,

 have you looked atwww.experts4solutions.com?

 Kenneth







  We are looking for experienced developers to work on a web2py project.
  We are considering using a freelancing service like vworker.com
  (formerly rent-a-coder) or elance. Does anyone have any experience
  with these companies?

  Jim Karsten


[web2py] Puzzling registered trademark symbol appearance

2011-03-29 Thread Jim Karsten
I have a variable named 'reg_no' that when used as a link paramater is
getting converted into a registered trademark symbol. Here is a simple
example that illustrates it.

The controller:

def page():
link = A('my link', _href=URL(r=request, vars=request.vars))
form = SQLFORM.factory(
Field('input_one', default=request.vars.input_one),
Field('reg_no', default=request.vars.reg_no),
)
return dict(form=form, link=link)

The view:

{{=form}}
{{=link}}


Enter values in both fields, then submit. Then click the link. The
link should refresh the page, with the form populated with the entered
values. If the second field is named 'input_two' it works. But when
it's named 'reg_no' the first input has 'aaaR_no=bbb' where 'aaa' and
'bbb' are the entered values and R is the registered trademark symbol,
and the second input is blank.

The link url is very different depending on the field name:

'input_two': http://www...com/demo/default/page?input_one=aaainput_two=bbb
'reg_no'   : http://www...com/demo/default/page?input_one=aaa%C2%AE_no%3Dbbb

I renamed 'reg_no' to something not starting with 'reg_' and I have it
working. I'm not sure if this is a bug or not.

Any insight would be welcome.

Jim Karsten


[web2py] ISNULL for sorting NULLs to bottom

2011-03-29 Thread Jim Karsten
I would like to sort records on a field such that NULL values get
sorted to the end. In MySQL the suggested solution is to use ISNULL.
For example

SELECT name FROM person ORDER BY ISNULL(name), name;

I tried other approaches such as sorting the rows returned from a
select but they were not practical as all records need to be retrieved
and in the application I am working on I only want a subset (ie. I am
using limitby)

I was able to implement this in web2py with the following patch.

gluon/dal.py

class BaseAdapter(ConnectionPool):

def ISNULL(self,first):
return 'ISNULL(%s)' % self.expand(first)

class Expression(object):

def isnull(self):
return Expression(self.db, self.db._adapter.ISNULL, self,
None, self.type)

Is there any desire for this feature in the trunk? I haven't given any
consideration to databases other than MySQL. I would be willing to dig
into this further if there is interest.


[web2py] Log tickets

2011-02-01 Thread Jim Karsten
On my development server, I log errors to syslog so they are
accessible from a single location. Web2py tickets present a problem
since they are not logged. I could configure syslog to access errors
from the ticket error file, but it contains more information than I
need and the text isn't in a suitable format.

I added three lines to the RestrictedError class log() method in gluon/
restricted.py. The traceback message of a ticket is then logged quite
nicely.

def log(self, request):
...

ticket_storage = TicketStorage(db=request.tickets_db)
ticket_storage.store(request, f, d)
=  for line in str(self.traceback).split(\n):
=  if len(line.strip())  1:
=  logger.error(line.strip())
return '%s/%s' % (a, f)
except:
logger.error(self.traceback)
return None

Is there any interest in adding that to the source code?

Also, when I first tested this, I copied the
logger.error(self.traceback) line from the except clause to log the
ticket message. It only logged the first line. The message logged is:
Traceback (most recent call last): which isn't much use. Possibly a
for loop similar to what I used above would improve that.

Regards,
Jim Karsten


[web2py] Possible typo in book

2010-12-21 Thread Jim Karsten
In web2py book, chapter 7 Forms and Validators, IS_IN_SET section,
second paragraph, should this line:

If you do not want a choose one option, set zero=False

be:

If you do not want a choose one option, set zero=None

Jim Karsten