Compare commits

...

20 Commits

Author SHA1 Message Date
mdipierro
f7bf1020df reverted gluon/packages/dal 2015-04-18 15:28:12 -05:00
mdipierro
75b8ceb022 Merge pull request #923 from gi0baro/validators
Fix serializers injection over new pydal
2015-04-18 15:17:06 -05:00
mdipierro
b4f3784136 Merge pull request #922 from dokime7/patch-7
Fix crash with list:reference field
2015-04-18 15:16:25 -05:00
mdipierro
f1297bb827 Merge pull request #918 from niphlod/enhancement/anyserver
added waitress to anyserver
2015-04-18 15:15:02 -05:00
mdipierro
435ebeaae4 more consulting companies 2015-04-18 15:13:03 -05:00
gi0baro
537045082c Updated dal test due to new serializers 2015-04-18 15:08:39 +02:00
gi0baro
4bea52a7b5 Fix serializers injection over new pydal 2015-04-18 15:04:01 +02:00
Jeremie Dokime
33295e516f Fix crash with list:reference field
When using validate_and_update() or validate_and_insert() on a table with a list:reference field, the request crashes after timeout with:
  File "web2py/gluon/globals.py", line 270, in body
    raise HTTP(400, "Bad Request - HTTP body is incomplete")

The request crashes because there is an hidden exception with the isinstance function:
isinstance() arg 2 must be a class, type, or tuple of classes and types

When no using GAE, the GoogleDatastoreAdapter variable is None, so isinstance crash.
See the last line of pydal/adapters/__init__.py

This is a regression intruduced after the v2.9.12.
2015-04-18 02:15:45 +02:00
mdipierro
f33ccf3366 experimental fix for represent 2015-04-16 16:53:12 -05:00
niphlod
0784680c90 added waitress to anyserver 2015-04-15 23:55:44 +02:00
mdipierro
e940228eaf Merge pull request #912 from ilvalle/sqlcustomtype
extend sqlcustomform to support widget/represent
2015-04-15 13:01:50 -05:00
mdipierro
50769a627a Merge pull request #916 from gi0baro/issue-904
Fixes #904
2015-04-15 13:01:19 -05:00
mdipierro
e68ecaa131 Merge pull request #915 from BuhtigithuB/update/gluon-contrib-pypyodbc
Update gluon/contrib/pypyodbc.py 1.3.0 -> 1.3.3
2015-04-15 13:01:01 -05:00
gi0baro
95e6e8577b Fixes #904 2015-04-14 15:25:26 +02:00
Hardirc
19c83d4ad6 Update gluon/contrib/pypyodbc.py 1.3.0 -> 1.3.3 2015-04-13 18:43:48 -04:00
ilvalle
9c92bd1050 extend sqlcustomform to support widget/represent (possible fix to web2py/pydal#127) 2015-04-12 21:04:05 +02:00
mdipierro
b3b95ccf5f Merge pull request #906 from niphlod/fix/895
file is already open at this point... fixes #895
2015-04-08 23:24:16 -05:00
niphlod
cefa30841b file is already open at this point... fixes #895 2015-04-08 21:47:04 +02:00
mdipierro
15ff8669cb fixed dal tracking, thanks Niphlod 2015-04-06 16:24:49 -05:00
mdipierro
a921751e8e stripe form bs3 compatible, disabled cache.ram max utilization 2015-04-05 18:17:27 -05:00
11 changed files with 513 additions and 474 deletions

View File

@@ -180,6 +180,11 @@ class Servers:
s = wsgi.WSGIServer(callable=app, bind="%s:%d" % address)
s.start()
@staticmethod
def waitress(app, address, **options):
from waitress import serve
serve(app, host=address[0], port=address[1], _quiet=True)
def mongrel2_handler(application, conn, debug=False):
"""

View File

@@ -18,7 +18,7 @@
</ul>
<div class="tab-content">
<div class="tab-pane active" id="alltables">
<table>
<table class="table">
{{for db in sorted(databases):}}
{{for table in databases[db].tables:}}
{{qry='%s.%s.id>0'%(db,table)}}
@@ -40,7 +40,7 @@
{{=A("%s.%s" % (db,table),_href=URL('select',args=[db],vars=dict(query=qry)))}}
</th>
<td>
{{=A(str(T('New Record')),_href=URL('insert',args=[db,table]),_class="btn")}}
{{=A(str(T('New Record')),_href=URL('insert',args=[db,table]),_class="btn btn-default")}}
</td>
</tr>
{{pass}}
@@ -61,7 +61,7 @@
</pre>
{{pass}}
{{if table:}}
{{=A(str(T('New Record')),_href=URL('insert',args=[request.args[0],table]),_class="btn")}}<br/><br/>
{{=A(str(T('New Record')),_href=URL('insert',args=[request.args[0],table]),_class="btn btn-default")}}<br/><br/>
<h3>{{=T("Rows in Table")}}</h3><br/>
{{else:}}
<h3>{{=T("Rows selected")}}</h3><br/>
@@ -72,8 +72,8 @@
{{=T('"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN')}}</p>
<br/><br/>
<h4>{{=T("%s selected", nrows)}}</h4>
{{if start>0:}}{{=A(T('previous %s rows') % step,_href=URL('select',args=request.args[0],vars=dict(start=start-step)),_class="btn")}}{{pass}}
{{if stop<nrows:}}{{=A(T('next %s rows') % step,_href=URL('select',args=request.args[0],vars=dict(start=start+step)),_class="btn")}}{{pass}}
{{if start>0:}}{{=A(T('previous %s rows') % step,_href=URL('select',args=request.args[0],vars=dict(start=start-step)),_class="btn btn-default")}}{{pass}}
{{if stop<nrows:}}{{=A(T('next %s rows') % step,_href=URL('select',args=request.args[0],vars=dict(start=start+step)),_class="btn btn-default")}}{{pass}}
{{if rows:}}
<div style="overflow:auto; width:80%;">
{{linkto = lambda f, t, r: URL('update', args=[request.args[0], r, f]) if f else "#"}}
@@ -82,7 +82,7 @@
</div>
{{pass}}
<br/><br/><h3>{{=T("Import/Export")}}</h3><br/>
<a href="{{=URL('csv',args=request.args[0],vars=dict(query=query))}}" class="btn">{{=T("export as csv file")}}</a>
<a href="{{=URL('csv',args=request.args[0],vars=dict(query=query))}}" class="btn btn-default">{{=T("export as csv file")}}</a>
{{=formcsv or ''}}
{{elif request.function=='insert':}}

View File

@@ -33,6 +33,9 @@
<li><a target="_blank" href="https://loadinfo-net.appspot.com">LoadInfo</a> (Bulgaria)</li>
<li><a target="_blank" href="http://www.appliedobjects.com">Applied Objects</a> (New Zealand)</li>
<li><a target="_blank" href="http://www.sistemasagiles.com.ar/">Sistemas Ágiles</a> ("Agile Systems") (Argentina)</li>
<li><a target="_blank" href="http://www.definescope.com/en/services/consulting/">DefineScope</a> (Portugal)</li>
<li><a target="_blank" href="http://10Biosystems.com">10BioSystems</a></li>
<li><a target="_blank" href="http://www.dutveul.nl">Dutveul</a> (Netherlands)</li>
</ul>
</div>

View File

@@ -99,7 +99,7 @@ class CacheAbstract(object):
"""
cache_stats_name = 'web2py_cache_statistics'
max_ram_utilization = 90 # percent
max_ram_utilization = None # percent
def __init__(self, request=None):
"""Initializes the object
@@ -353,7 +353,7 @@ class CacheOnDisk(CacheAbstract):
raise KeyError
self.wait_portalock(val_file)
value = pickle.load(recfile.open(key, 'rb', path=self.folder))
value = pickle.load(val_file)
val_file.close()
return value

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,24 @@ from hashlib import sha1
class Stripe:
"""
Usage:
Use in WEB2PY (guaranteed PCI compliant)
def pay():
from gluon.contrib.stripe import StripeForm
form = StripeForm(
pk=STRIPE_PUBLISHABLE_KEY,
sk=STRIPE_SECRET_KEY,
amount=150, # $1.5 (amount is in cents)
description="Nothing").process()
if form.accepted:
payment_id = form.response['id']
redirect(URL('thank_you'))
elif form.errors:
redirect(URL('pay_error'))
return dict(form=form)
Low level API:
key='<api key>'
d = Stripe(key).charge(
amount=100, # 1 dollar!!!!
@@ -22,22 +39,6 @@ class Stripe:
{u'fee': 0, u'description': u'test charge', u'created': 1321242072, u'refunded': False, u'livemode': False, u'object': u'charge', u'currency': u'usd', u'amount': 100, u'paid': True, u'id': u'ch_sdjasgfga83asf', u'card': {u'exp_month': 5, u'country': u'US', u'object': u'card', u'last4': u'4242', u'exp_year': 2012, u'type': u'Visa'}}
if paid is True than transaction was processed
Use in WEB2PY (guaranteed PCI compliant)
def pay():
from gluon.contrib.stripe import StripeForm
form = StripeForm(
pk=STRIPE_PUBLISHABLE_KEY,
sk=STRIPE_SECRET_KEY,
amount=150, # $1.5 (amount is in cents)
description="Nothing").process()
if form.accepted:
payment_id = form.response['id']
redirect(URL('thank_you'))
elif form.errors:
redirect(URL('pay_error'))
return dict(form=form)
"""
URL_CHARGE = 'https://%s:@api.stripe.com/v1/charges'
@@ -188,37 +189,36 @@ jQuery(function(){
<h3>Payment Amount: {{=currency_symbol}} {{="%.2f" % (0.01*amount)}}</h3>
<form action="" method="POST" id="payment-form" class="form-horizontal">
<div class="form-row control-group">
<label class="control-label">Card Number</label>
<div class="controls">
<div class="form-row form-group">
<label class="col-sm-2 control-label">Card Number</label>
<div class="controls col-sm-10">
<input type="text" size="20" data-stripe="number"
placeholder="4242424242424242"/>
placeholder="4242424242424242" class="form-control"/>
</div>
</div>
<div class="form-row control-group">
<label class="control-label">CVC</label>
<div class="controls">
<div class="form-row form-group">
<label class="col-sm-2 control-label">CVC</label>
<div class="controls col-sm-10">
<input type="text" size="4" style="width:80px" data-stripe="cvc"
placeholder="XXX"/>
placeholder="XXX" class="form-control"/>
<a href="http://en.wikipedia.org/wiki/Card_Verification_Code" target="_blank">What is this?</a>
</div>
</div>
<div class="form-row control-group">
<label class="control-label">Expiration</label>
<div class="controls">
<input type="text" size="2" style="width:40px" data-stripe="exp-month"
placeholder="MM"/>
<div class="form-row form-group">
<label class="col-sm-2 control-label">Expiration</label>
<div class="controls col-sm-10">
<input type="text" size="2" style="width:40px; display:inline-block"
data-stripe="exp-month" placeholder="MM" class="form-control"/>
/
<input type="text" size="4" style="width:80px" data-stripe="exp-year"
placeholder="YYYY"/>
<input type="text" size="4" style="width:80px; display:inline-block"
data-stripe="exp-year" placeholder="YYYY" class="form-control"/>
</div>
</div>
<div class="control-group">
<div class="controls">
<div class="form-row form-group">
<div class="controls col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-primary">Submit Payment</button>
<div class="payment-errors error hidden"></div>
</div>

View File

@@ -14,7 +14,7 @@ from pydal import DAL as DAL
from pydal import Field
from pydal.objects import Row, Rows, Table, Query, Expression
from pydal import SQLCustomType, geoPoint, geoLine, geoPolygon
import copy_reg as copyreg
def _default_validators(db, field):
"""
@@ -81,12 +81,12 @@ def _default_validators(db, field):
requires[0] = validators.IS_EMPTY_OR(requires[0])
return requires
from gluon import serializers as w2p_serializers
from gluon.serializers import custom_json, xml
from gluon.utils import web2py_uuid
from gluon import sqlhtml
DAL.serializers = w2p_serializers
DAL.serializers = {'json': custom_json, 'xml': xml}
DAL.validators_method = _default_validators
DAL.uuid = lambda x: web2py_uuid()
DAL.representers = {

View File

@@ -58,9 +58,12 @@ def represent(field, value, record):
f = field.represent
if not callable(f):
return str(value)
n = f.func_code.co_argcount - len(f.func_defaults or [])
if getattr(f, 'im_self', None):
n -= 1
if hasattr(f,'func_code'):
n = f.func_code.co_argcount - len(f.func_defaults or [])
if getattr(f, 'im_self', None):
n -= 1
else:
n = 1
if n == 1:
return f(value)
elif n == 2:
@@ -1205,6 +1208,9 @@ class SQLFORM(FORM):
elif field.type == 'boolean':
inp = self.widgets.boolean.widget(
field, default, _disabled=True)
elif isinstance(field.type, SQLCustomType) and callable(field.type.represent):
# SQLCustomType has a represent, use it
inp = field.type.represent(default, record)
else:
inp = field.formatter(default)
if getattr(field, 'show_if', None):
@@ -1246,6 +1252,9 @@ class SQLFORM(FORM):
dspval = ''
elif field.type == 'blob':
continue
elif isinstance(field.type, SQLCustomType) and callable(field.type.widget):
# SQLCustomType has a widget, use it
inp = field.type.widget(field, default)
else:
field_type = widget_class.match(str(field.type)).group()
field_type = field_type in self.widgets and field_type or 'string'
@@ -2708,6 +2717,9 @@ class SQLFORM(FORM):
_href='%s/%s' % (upload, value))
else:
value = ''
elif isinstance(field.type, SQLCustomType) and callable(field.type.represent):
# SQLCustomType has a represent, use it
value = field.type.represent(value, row)
if isinstance(value, str):
value = truncate_string(value, maxlength)
elif not isinstance(value, XmlComponent):

View File

@@ -15,10 +15,11 @@ from gluon.dal import DAL, Field
class TestDALSubclass(unittest.TestCase):
def testRun(self):
import gluon.serializers as mserializers
from gluon.serializers import custom_json, xml
from gluon import sqlhtml
db = DAL(check_reserved=['all'])
self.assertEqual(db.serializers, mserializers)
self.assertEqual(db.serializers['json'], custom_json)
self.assertEqual(db.serializers['xml'], xml)
self.assertEqual(db.representers['rows_render'], sqlhtml.represent)
self.assertEqual(db.representers['rows_xml'], sqlhtml.SQLTABLE)

View File

@@ -611,7 +611,7 @@ class IS_IN_DB(Validator):
def count(values, s=self.dbset, f=field):
return s(f.belongs(map(int, values))).count()
if isinstance(self.dbset.db._adapter, GoogleDatastoreAdapter):
if GoogleDatastoreAdapter is not None and isinstance(self.dbset.db._adapter, GoogleDatastoreAdapter):
range_ids = range(0, len(values), 30)
total = sum(count(values[i:i + 30]) for i in range_ids)
if total == len(values):