fixws and 'new' button in grid query
This commit is contained in:
@@ -23,3 +23,5 @@ from compileapp import LOAD
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -453,3 +453,4 @@ def create_missing_app_folders(request):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -430,3 +430,4 @@ class Cache(object):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -51,3 +51,4 @@ def getcfs(key, filename, filter=None):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+4
-3
@@ -127,7 +127,7 @@ def LOAD(c=None, f='index', args=None, vars=None,
|
||||
else:
|
||||
if not isinstance(args,(list,tuple)):
|
||||
args = [args]
|
||||
c = c or request.controller
|
||||
c = c or request.controller
|
||||
other_request = Storage()
|
||||
for key, value in request.items():
|
||||
other_request[key] = value
|
||||
@@ -160,9 +160,9 @@ def LOAD(c=None, f='index', args=None, vars=None,
|
||||
copy.copy(current.response.generic_patterns)
|
||||
other_environment['request'] = other_request
|
||||
other_environment['response'] = other_response
|
||||
|
||||
|
||||
## some magic here because current are thread-locals
|
||||
|
||||
|
||||
original_request, current.request = current.request, other_request
|
||||
original_response, current.response = current.response, other_response
|
||||
page = run_controller_in(c, f, other_environment)
|
||||
@@ -656,3 +656,4 @@ if __name__ == '__main__':
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -719,3 +719,4 @@ def contenttype(filename, default='text/plain'):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -259,3 +259,5 @@ if __name__=='__main__':
|
||||
test()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ class DowCommerce:
|
||||
self.parameters = {}
|
||||
self.setParameter('username', username)
|
||||
self.setParameter('password', password)
|
||||
|
||||
|
||||
|
||||
def process(self):
|
||||
encoded_args = urllib.urlencode(self.parameters)
|
||||
@@ -58,11 +58,11 @@ class DowCommerce:
|
||||
results += str(opened.read()).split(self.delimiter)
|
||||
finally:
|
||||
opened.close()
|
||||
|
||||
|
||||
for result in results:
|
||||
(key,val) = result.split('=')
|
||||
self.results[key] = val
|
||||
|
||||
|
||||
if self.results['response'] == '1':
|
||||
self.error = False
|
||||
self.success = True
|
||||
@@ -74,7 +74,7 @@ class DowCommerce:
|
||||
elif self.results['response'] == '3':
|
||||
self.error = True
|
||||
self.success = False
|
||||
self.declined = False
|
||||
self.declined = False
|
||||
else:
|
||||
self.error = True
|
||||
self.success = False
|
||||
@@ -82,7 +82,7 @@ class DowCommerce:
|
||||
raise DowCommerce.DowCommerceError(self.results)
|
||||
|
||||
def setTransaction(self, creditcard, expiration, total, cvv=None, orderid=None, orderdescription=None,
|
||||
ipaddress=None, tax=None, shipping=None,
|
||||
ipaddress=None, tax=None, shipping=None,
|
||||
firstname=None, lastname=None, company=None, address1=None, address2=None, city=None, state=None, zipcode=None,
|
||||
country=None, phone=None, fax=None, emailaddress=None, website=None,
|
||||
shipping_firstname=None, shipping_lastname=None, shipping_company=None, shipping_address1=None, shipping_address2=None,
|
||||
@@ -93,11 +93,11 @@ class DowCommerce:
|
||||
raise DowCommerce.DowCommerceError('No expiration number passed to setTransaction(): {0}'.format(expiration))
|
||||
if str(total).strip() == '' or total == None:
|
||||
raise DowCommerce.DowCommerceError('No total amount passed to setTransaction(): {0}'.format(total))
|
||||
|
||||
|
||||
self.setParameter('ccnumber', creditcard)
|
||||
self.setParameter('ccexp', expiration)
|
||||
self.setParameter('amount', total)
|
||||
|
||||
|
||||
if cvv:
|
||||
self.setParameter('cvv', cvv)
|
||||
if orderid:
|
||||
@@ -110,10 +110,10 @@ class DowCommerce:
|
||||
self.setParameter('tax', tax)
|
||||
if shipping:
|
||||
self.setParameter('shipping', shipping)
|
||||
|
||||
## billing info
|
||||
|
||||
## billing info
|
||||
if firstname:
|
||||
self.setParameter('firstname', firstname)
|
||||
self.setParameter('firstname', firstname)
|
||||
if lastname:
|
||||
self.setParameter('lastname', lastname)
|
||||
if company:
|
||||
@@ -138,7 +138,7 @@ class DowCommerce:
|
||||
self.setParameter('email', emailaddress)
|
||||
if website:
|
||||
self.setParameter('website', website)
|
||||
|
||||
|
||||
## shipping info
|
||||
if shipping_firstname:
|
||||
self.setParameter('shipping_firstname', shipping_firstname)
|
||||
@@ -147,9 +147,9 @@ class DowCommerce:
|
||||
if shipping_company:
|
||||
self.setParameter('shipping_company', shipping_company)
|
||||
if shipping_address1:
|
||||
self.setParameter('shipping_address1', shipping_address1)
|
||||
self.setParameter('shipping_address1', shipping_address1)
|
||||
if shipping_address2:
|
||||
self.setParameter('shipping_address2', shipping_address2)
|
||||
self.setParameter('shipping_address2', shipping_address2)
|
||||
if shipping_city:
|
||||
self.setParameter('shipping_city', shipping_city)
|
||||
if shipping_state:
|
||||
@@ -188,12 +188,12 @@ class DowCommerce:
|
||||
def getResultResponseShort(self):
|
||||
responses = ['', 'Approved', 'Declined', 'Error']
|
||||
return responses[int(self.results['response'])]
|
||||
|
||||
|
||||
def getFullResponse(self):
|
||||
return self.results
|
||||
|
||||
return self.results
|
||||
|
||||
def getResponseText(self):
|
||||
return self.results['responsetext']
|
||||
return self.results['responsetext']
|
||||
|
||||
def test():
|
||||
import socket
|
||||
@@ -220,7 +220,7 @@ def test():
|
||||
payment.setTransaction(creditcard, expiration, total, cvv=cvv, tax=tax, orderid=orderid, orderdescription='Test Transaction',
|
||||
firstname='John', lastname='Doe', company='Acme', address1='123 Min Street', city='Hometown', state='VA',
|
||||
zipcode='12345', country='US', phone='888-555-1212', emailaddress='john@noemail.local', ipaddress='192.168.1.1')
|
||||
|
||||
|
||||
payment.process()
|
||||
if payment.isApproved():
|
||||
print 'Payment approved!'
|
||||
@@ -240,3 +240,5 @@ if __name__=='__main__':
|
||||
test()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -190,3 +190,5 @@ if __name__ == "__main__":
|
||||
tornado.ioloop.IOLoop.instance().start()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -3906,3 +3906,5 @@ def parse(url_file_stream_or_string, etag=None, modified=None, agent=None, refer
|
||||
result['namespaces'] = feedparser.namespacesInUse
|
||||
return result
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -51,3 +51,5 @@ class MemcacheClient(Client):
|
||||
key = '%s/%s' % (self.request.application, key)
|
||||
self.delete(key)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -86,3 +86,5 @@ def autoretry_datastore_timeouts(attempts=5.0, interval=0.1, exponent=2.0):
|
||||
apiproxy_stub_map.MakeSyncCall = wrapper
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -63,3 +63,5 @@ def pdf_from_html(html):
|
||||
return pyfpdf_from_html(html)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -14,4 +14,6 @@ def button(merchant_id="123456789012345",
|
||||
button = '<form action="https://checkout.google.com/api/checkout/v2/checkoutForm/Merchant/%s" id="BB_BuyButtonForm" method="post" name="BB_BuyButtonForm" target="_top">%s<input name="_charset_" type="hidden" value="utf-8"/><input alt="" src="https://checkout.google.com/buttons/buy.gif?merchant_id=%s&w=117&h=48&style=white&variant=text&loc=en_US" type="image"/></form>' % (merchant_id, list_products, merchant_id)
|
||||
return XML(button)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -5,3 +5,5 @@ __all__ = ['DAL','Field','drivers','gae']
|
||||
from gluon.dal import DAL, Field, Table, Query, Set, Expression, Row, Rows, drivers, BaseAdapter, SQLField, SQLTable, SQLXorable, SQLQuery, SQLSet, SQLRows, SQLStorage, SQLDB, GQLDB, SQLALL, SQLCustomType, gae
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -906,3 +906,5 @@ if __name__ == '__main__':
|
||||
doctest.testmod()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -123,3 +123,5 @@ if __name__ == "__main__":
|
||||
print authenticate(getpass.getuser(), getpass.getpass())
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -164,3 +164,5 @@ if __name__ == '__main__':
|
||||
print ell.generate(1000,prefix=None)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -21,15 +21,15 @@ def RedisCache(*args, **vars):
|
||||
from gluon.contrib.redis import RedisCache
|
||||
cache.redis = RedisCache('localhost:6379',db=None, debug=True)
|
||||
|
||||
cache.redis.stats()
|
||||
|
||||
cache.redis.stats()
|
||||
|
||||
return a dictionary with statistics of Redis server
|
||||
with one additional key ('w2p_keys') showing all keys currently set
|
||||
from web2py with their TTL
|
||||
if debug=True additional tracking is activate and another key is added
|
||||
('w2p_stats') showing total_hits and misses
|
||||
('w2p_stats') showing total_hits and misses
|
||||
"""
|
||||
|
||||
|
||||
locker.acquire()
|
||||
try:
|
||||
if not hasattr(RedisCache, 'redis_instance'):
|
||||
@@ -52,7 +52,7 @@ class RedisClient(object):
|
||||
app = request.application
|
||||
else:
|
||||
app = ''
|
||||
|
||||
|
||||
if not app in self.meta_storage:
|
||||
self.storage = self.meta_storage[app] = {
|
||||
CacheAbstract.cache_stats_name: {
|
||||
@@ -72,7 +72,7 @@ class RedisClient(object):
|
||||
obj = self.r_server.get(key)
|
||||
if obj:
|
||||
if self.debug:
|
||||
self.r_server.incr('web2py_cache_statistics:hit_total')
|
||||
self.r_server.incr('web2py_cache_statistics:hit_total')
|
||||
value = pickle.loads(obj)
|
||||
elif f is None:
|
||||
if obj: self.r_server.delete(key)
|
||||
@@ -94,7 +94,7 @@ class RedisClient(object):
|
||||
|
||||
def clear(self, regex):
|
||||
"""
|
||||
Auxiliary function called by `clear` to search and
|
||||
Auxiliary function called by `clear` to search and
|
||||
clear cache entries
|
||||
"""
|
||||
r = re.compile(regex)
|
||||
@@ -120,7 +120,9 @@ class RedisClient(object):
|
||||
statscollector['w2p_keys']["%s_expire_in_sec" % (a)] = \
|
||||
self.r_server.ttl(a)
|
||||
return statscollector
|
||||
|
||||
|
||||
def __keyFormat__(self, key):
|
||||
return 'w2p:%s:%s' % (self.request.application,
|
||||
return 'w2p:%s:%s' % (self.request.application,
|
||||
key.replace(' ', '_'))
|
||||
|
||||
|
||||
|
||||
@@ -588,3 +588,5 @@ if __name__ == '__main__':
|
||||
print test()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -266,3 +266,5 @@ if __name__=='__main__':
|
||||
while True: print run(history, raw_input('>>> ')).rstrip()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ from cStringIO import StringIO
|
||||
import random
|
||||
import sys
|
||||
try:
|
||||
import gluon.contrib.simplejson as json # try web2py json serializer
|
||||
import gluon.contrib.simplejson as json # try web2py json serializer
|
||||
except ImportError:
|
||||
try:
|
||||
import json # try stdlib (py2.6)
|
||||
@@ -40,7 +40,7 @@ class JSONRPCError(RuntimeError):
|
||||
def __unicode__(self):
|
||||
return u"%s: %s" % (self.code, self.message)
|
||||
def __str__(self):
|
||||
return self.__unicode__().encode("ascii","ignore")
|
||||
return self.__unicode__().encode("ascii","ignore")
|
||||
|
||||
|
||||
class JSONDummyParser:
|
||||
@@ -55,11 +55,11 @@ class JSONDummyParser:
|
||||
|
||||
class JSONTransportMixin:
|
||||
"json wrapper for xmlrpclib transport interfase"
|
||||
|
||||
|
||||
def send_content(self, connection, request_body):
|
||||
connection.putheader("Content-Type", "application/json")
|
||||
connection.putheader("Content-Length", str(len(request_body)))
|
||||
connection.endheaders()
|
||||
connection.endheaders()
|
||||
if request_body:
|
||||
connection.send(request_body)
|
||||
# todo: add gzip compression
|
||||
@@ -76,7 +76,7 @@ class JSONTransport(JSONTransportMixin, Transport):
|
||||
class JSONSafeTransport(JSONTransportMixin, SafeTransport):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class ServerProxy(object):
|
||||
"JSON RPC Simple Client Service Proxy"
|
||||
|
||||
@@ -99,12 +99,12 @@ class ServerProxy(object):
|
||||
transport = JSONTransport()
|
||||
self.__transport = transport
|
||||
self.__encoding = encoding
|
||||
self.__verbose = verbose
|
||||
self.__verbose = verbose
|
||||
|
||||
def __getattr__(self, attr):
|
||||
"pseudo method that can be called"
|
||||
return lambda *args: self.call(attr, *args)
|
||||
|
||||
|
||||
def call(self, method, *args):
|
||||
"JSON RPC communication (method invocation)"
|
||||
|
||||
@@ -120,15 +120,15 @@ class ServerProxy(object):
|
||||
request,
|
||||
verbose=self.__verbose
|
||||
)
|
||||
|
||||
|
||||
# store plain request and response for further debugging
|
||||
self.json_request = request
|
||||
self.json_response = response
|
||||
|
||||
# parse json data coming from service
|
||||
# parse json data coming from service
|
||||
# {'version': '1.1', 'id': id, 'result': result, 'error': None}
|
||||
response = json.loads(response)
|
||||
|
||||
|
||||
if response['id'] != request_id:
|
||||
raise JSONRPCError(0, "JSON Request ID != Response ID")
|
||||
|
||||
@@ -145,3 +145,5 @@ if __name__ == "__main__":
|
||||
client = ServerProxy(location, verbose='--verbose' in sys.argv,)
|
||||
print client.add(1, 2)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -112,3 +112,5 @@ def sms_email(number,provider):
|
||||
return number+SMSCODES[provider]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -262,3 +262,5 @@ if __name__ == '__main__':
|
||||
print s['c'].computed_value
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ class Stripe:
|
||||
print Stripe(key).check(d['id'])
|
||||
print Stripe(key).refund(d['id'])
|
||||
Sample output (python dict):
|
||||
{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'}}
|
||||
{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
|
||||
"""
|
||||
@@ -27,11 +27,11 @@ class Stripe:
|
||||
def charge(self,
|
||||
amount,
|
||||
currency='usd',
|
||||
card_number='4242424242424242',
|
||||
card_number='4242424242424242',
|
||||
card_exp_month='5',
|
||||
card_exp_year='2012',
|
||||
card_cvc_check='123',
|
||||
description='test charge'):
|
||||
description='test charge'):
|
||||
params = urllib.urlencode({'amount':amount,
|
||||
'currency':currency,
|
||||
'card[number]':card_number,
|
||||
@@ -62,3 +62,5 @@ if __name__=='__main__':
|
||||
print 'paid',s['paid'],s['amount'] ,s['currency']
|
||||
s = Stripe(key).refund(d[u'id'])
|
||||
print 'refunded',s['refunded']
|
||||
|
||||
|
||||
|
||||
@@ -243,3 +243,5 @@ class TaskBarIcon:
|
||||
STOPPED = 1
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ Aim is
|
||||
Taken from http://pypi.python.org/pypi/httpagentparser (MIT license)
|
||||
Modified my Ross Peoples for web2py to better support iPhone and iPad.
|
||||
Modified by Angelo Compagnucci <angelo.compagnucci@gmail.com> to better support a wide ringe of mobile devices.
|
||||
Now it supports: tablet device (is_tablet), BlackBerry, BlackBerry PlayBook, Android Tablets, Windows Mobile,
|
||||
Now it supports: tablet device (is_tablet), BlackBerry, BlackBerry PlayBook, Android Tablets, Windows Mobile,
|
||||
Symbian.
|
||||
"""
|
||||
import sys
|
||||
@@ -81,11 +81,11 @@ class DetectorBase(object):
|
||||
result['is_mobile'] = is_mobile
|
||||
if is_tablet:
|
||||
result['is_tablet'] = is_tablet
|
||||
|
||||
|
||||
version = self.getVersion(agent)
|
||||
if version:
|
||||
result[self.info_type]['version'] = version
|
||||
|
||||
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -222,13 +222,13 @@ class BlackBerry(OS):
|
||||
look_for = ['BlackBerry']
|
||||
prefs = dict( flavor=['PlayBook'])
|
||||
is_mobile = True
|
||||
|
||||
|
||||
# Manual check for tablet
|
||||
def checkWords(self, agent):
|
||||
if 'BlackBerry' in agent or 'PlayBook' in agent:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def getVersion(self, agent):
|
||||
pass
|
||||
|
||||
@@ -236,14 +236,14 @@ class PlayBook(Flavor):
|
||||
look_for = ['PlayBook']
|
||||
is_mobile=True
|
||||
is_tablet=True
|
||||
|
||||
|
||||
def getVersion(self, agent):
|
||||
return agent.partition('Tablet OS')[2].partition(';')[0].strip()
|
||||
|
||||
class Macintosh(OS):
|
||||
look_for = ['Macintosh']
|
||||
prefs = dict(dist=None, flavor=['MacOS'])
|
||||
|
||||
|
||||
def getVersion(self, agent):
|
||||
pass
|
||||
|
||||
@@ -269,7 +269,7 @@ class Windows(OS):
|
||||
|
||||
def getVersion(self, agent):
|
||||
v = agent.partition('NT')
|
||||
return v[1]+' '+v[2].replace(')',';').partition(';')[0].strip()
|
||||
return v[1]+' '+v[2].replace(')',';').partition(';')[0].strip()
|
||||
|
||||
class WindowsMobile(Dist):
|
||||
name = 'Phone'
|
||||
@@ -320,7 +320,7 @@ class SymbianOS(OS):
|
||||
class Series(Flavor):
|
||||
look_for = ['SymbianOS', 'Series']
|
||||
version_splitters = ['/', ';']
|
||||
|
||||
|
||||
def getVersion(self, agent):
|
||||
return agent.partition('Series')[2].partition(' ')[0].replace('/',' ')
|
||||
|
||||
@@ -330,8 +330,8 @@ class BrowserNG(Browser):
|
||||
|
||||
class iPhone(Dist):
|
||||
look_for = ['iPhone']
|
||||
is_mobile = True
|
||||
prefs = dict(browser=['SafariMobile'])
|
||||
is_mobile = True
|
||||
prefs = dict(browser=['SafariMobile'])
|
||||
|
||||
def getVersion(self, agent):
|
||||
version_end_chars = ['like', ';', ')']
|
||||
@@ -377,7 +377,7 @@ def detect(agent):
|
||||
prefs = detector.prefs
|
||||
break
|
||||
except Exception, ex:
|
||||
result['exception'] = ex
|
||||
result['exception'] = ex
|
||||
return result
|
||||
|
||||
|
||||
@@ -415,8 +415,8 @@ if __name__ == '__main__':
|
||||
import unittest
|
||||
|
||||
data = (
|
||||
|
||||
|
||||
|
||||
|
||||
('Mozilla/5.0 (SymbianOS/9.2; U; Series60/3.1 Nokia6120c/3.83; Profile/MIDP-2.0 Configuration/CLDC-1.1) AppleWebKit/413 (KHTML, like Gecko) Safari/413',
|
||||
('Series SymbianOS 60 3.1', 'Safari', True),
|
||||
{'is_mobile': True, 'is_tablet': False, 'flavor': {'name': 'Series', 'version': '60 3.1'}, 'os': {'name': 'SymbianOS', 'version': '9.2'}, 'browser': {'name': 'Safari'}},),
|
||||
@@ -503,16 +503,18 @@ if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
|
||||
class mobilize(object):
|
||||
class mobilize(object):
|
||||
|
||||
def __init__(self, func):
|
||||
self.func = func
|
||||
def __init__(self, func):
|
||||
self.func = func
|
||||
|
||||
def __call__(self):
|
||||
from gluon import current
|
||||
from gluon import current
|
||||
user_agent = current.request.user_agent()
|
||||
if user_agent.is_mobile:
|
||||
if user_agent.is_mobile:
|
||||
items = current.response.view.split('.')
|
||||
items.insert(-1,'mobile')
|
||||
current.response.view = '.'.join(items)
|
||||
return self.func()
|
||||
return self.func()
|
||||
|
||||
|
||||
|
||||
@@ -325,3 +325,4 @@ class _Web2pyDateTrackerImporter(_Web2pyImporter, _DateTrackerImporter):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+8
-7
@@ -1139,7 +1139,7 @@ class BaseAdapter(ConnectionPool):
|
||||
def _select(self, query, fields, attributes):
|
||||
for key in set(attributes.keys())-set(('orderby', 'groupby', 'limitby',
|
||||
'required', 'cache', 'left',
|
||||
'distinct', 'having', 'join',
|
||||
'distinct', 'having', 'join',
|
||||
'for_update')):
|
||||
raise SyntaxError, 'invalid select attribute: %s' % key
|
||||
# ## if no fields specified take them all from the requested tables
|
||||
@@ -1150,7 +1150,7 @@ class BaseAdapter(ConnectionPool):
|
||||
else:
|
||||
new_fields.append(item)
|
||||
fields = new_fields
|
||||
tablenames = self.tables(query)
|
||||
tablenames = self.tables(query)
|
||||
|
||||
if query and not query.ignore_common_filters:
|
||||
query = self.common_filter(query,tablenames)
|
||||
@@ -3414,7 +3414,7 @@ class GoogleDatastoreAdapter(NoSQLAdapter):
|
||||
|
||||
if not query.ignore_common_filters:
|
||||
query = self.common_filter(query,[tablename])
|
||||
|
||||
|
||||
tableobj = self.db[tablename]._tableobj
|
||||
items = tableobj.all()
|
||||
filters = self.expand(query)
|
||||
@@ -3800,8 +3800,8 @@ class MongoDBAdapter(NoSQLAdapter):
|
||||
ctable = self.connection[table._tablename]
|
||||
values = dict((k.name,self.represent(v,table[k.name].type)) for k,v in fields)
|
||||
ctable.insert(values)
|
||||
return int(str(values['_id']), 16)
|
||||
|
||||
return int(str(values['_id']), 16)
|
||||
|
||||
def create_table(self, table, migrate=True, fake_migrate=False, polymodel=None, isCapped=False):
|
||||
if isCapped:
|
||||
raise RuntimeError, "Not implemented"
|
||||
@@ -4622,13 +4622,13 @@ def index():
|
||||
if self._common_fields:
|
||||
fields = [f for f in fields] + [f for f in self._common_fields]
|
||||
|
||||
common_filter = args.get('common_filter', None)
|
||||
common_filter = args.get('common_filter', None)
|
||||
|
||||
t = self[tablename] = table_class(self, tablename, *fields,
|
||||
**dict(primarykey=primarykey,
|
||||
trigger_name=trigger_name,
|
||||
sequence_name=sequence_name,
|
||||
common_filter=common_filter))
|
||||
common_filter=common_filter))
|
||||
|
||||
# db magic
|
||||
if self._uri in (None,'None'):
|
||||
@@ -6502,3 +6502,4 @@ if __name__ == '__main__':
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -85,3 +85,4 @@ def communicate(command=None):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -75,3 +75,4 @@ def decoder(buffer):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -397,3 +397,4 @@ def make_fake_file_like_object():
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+9
-8
@@ -42,7 +42,7 @@ try:
|
||||
have_minify = True
|
||||
except ImportError:
|
||||
have_minify = False
|
||||
|
||||
|
||||
regex_session_id = re.compile('^([\w\-]+/)?[\w\-\.]+$')
|
||||
|
||||
__all__ = ['Request', 'Response', 'Session']
|
||||
@@ -207,11 +207,11 @@ class Response(Storage):
|
||||
|
||||
def include_files(self):
|
||||
|
||||
|
||||
|
||||
"""
|
||||
Caching method for writing out files.
|
||||
Caching method for writing out files.
|
||||
By default, caches in ram for 5 minutes. To change,
|
||||
response.cache_includes = (cache_method, time_expire).
|
||||
response.cache_includes = (cache_method, time_expire).
|
||||
Example: (cache.disk, 60) # caches to disk for 1 minute.
|
||||
"""
|
||||
from gluon import URL
|
||||
@@ -222,7 +222,7 @@ class Response(Storage):
|
||||
if have_minify and (self.optimize_css or self.optimize_js):
|
||||
# cache for 5 minutes by default
|
||||
cache = self.cache_includes or (current.cache.ram, 60*5)
|
||||
def call_minify():
|
||||
def call_minify():
|
||||
return minify.minify(files,URL('static','temp'),
|
||||
current.request.folder,
|
||||
self.optimize_css,self.optimize_js)
|
||||
@@ -233,7 +233,7 @@ class Response(Storage):
|
||||
else:
|
||||
files = call_minify()
|
||||
s = ''
|
||||
for item in files:
|
||||
for item in files:
|
||||
if isinstance(item,str):
|
||||
f = item.lower()
|
||||
if f.endswith('.css'): s += css_template % item
|
||||
@@ -358,10 +358,10 @@ class Response(Storage):
|
||||
if hasattr(thread,'instances'):
|
||||
dbstats = [TABLE(*[TR(PRE(row[0]),'%.2fms' % (row[1]*1000)) \
|
||||
for row in i.db._timings]) \
|
||||
for i in thread.instances]
|
||||
for i in thread.instances]
|
||||
else:
|
||||
dbstats = [] # if no db or on GAE
|
||||
u = web2py_uuid()
|
||||
u = web2py_uuid()
|
||||
return DIV(
|
||||
BUTTON('design',_onclick="document.location='%s'" % admin),
|
||||
BUTTON('request',_onclick="jQuery('#request-%s').slideToggle()"%u),
|
||||
@@ -600,3 +600,4 @@ class Session(Storage):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -336,3 +336,4 @@ if __name__ == '__main__':
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+2
-1
@@ -2100,7 +2100,7 @@ class MENU(DIV):
|
||||
return self.serialize_mobile(self.data, 0).xml()
|
||||
else:
|
||||
return self.serialize(self.data, 0).xml()
|
||||
|
||||
|
||||
|
||||
def embed64(
|
||||
filename = None,
|
||||
@@ -2303,3 +2303,4 @@ if __name__ == '__main__':
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -129,3 +129,4 @@ def redirect(location, how=303):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -110,3 +110,4 @@ for module in base_modules + contributed_modules:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -354,3 +354,4 @@ if __name__ == '__main__':
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+2
-1
@@ -788,7 +788,7 @@ class HttpServer(object):
|
||||
sock_list.extend([ssl_private_key, ssl_certificate])
|
||||
if ssl_ca_certificate:
|
||||
sock_list.append(ssl_ca_certificate)
|
||||
|
||||
|
||||
logger.info('SSL is ON')
|
||||
app_info = {'wsgi_app': appfactory(wsgibase,
|
||||
log_filename,
|
||||
@@ -830,3 +830,4 @@ class HttpServer(object):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -29,3 +29,4 @@ regex_extend = re.compile(\
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+3
-2
@@ -26,7 +26,7 @@ _cron_stopping = False
|
||||
def absolute_path_link(path):
|
||||
"""
|
||||
Return an absolute path for the destination of a symlink
|
||||
|
||||
|
||||
"""
|
||||
if os.path.islink(path):
|
||||
link = os.readlink(path)
|
||||
@@ -263,7 +263,7 @@ def crondance(applications_parent, ctype='soft', startup=False):
|
||||
if _cron_stopping:
|
||||
break;
|
||||
apath = os.path.join(apppath,app)
|
||||
|
||||
|
||||
# if app is a symbolic link to other app, skip it
|
||||
full_apath_link = absolute_path_link(apath)
|
||||
if full_apath_link in full_apath_links:
|
||||
@@ -336,3 +336,4 @@ def crondance(applications_parent, ctype='soft', startup=False):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -125,3 +125,4 @@ if __name__ == '__main__':
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1714,3 +1714,4 @@ ADAPTERS['all'] = reduce(lambda a,b:a.union(b),(x for x in ADAPTERS.values()))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -303,3 +303,4 @@ def snapshot(info=None, context=5, code=None, environment=None):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+2
-1
@@ -188,7 +188,7 @@ def try_rewrite_on_error(http_response, request, environ, ticket=None):
|
||||
else:
|
||||
error_raising_path = environ['PATH_INFO']
|
||||
# Rewrite routes_onerror path.
|
||||
path_info = '/' + path_info.lstrip('/') # add leading '/' if missing
|
||||
path_info = '/' + path_info.lstrip('/') # add leading '/' if missing
|
||||
environ['PATH_INFO'] = path_info
|
||||
error_handling_path = url_in(request, environ)[1]['PATH_INFO']
|
||||
# Avoid infinite loop.
|
||||
@@ -1273,3 +1273,4 @@ def get_effective_router(appname):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+2
-1
@@ -458,7 +458,7 @@ class Listener(Thread):
|
||||
self.err_log.error("Cannot find root ca certificate file "
|
||||
"'%s'. Cannot bind to %s:%s" % data)
|
||||
return
|
||||
|
||||
|
||||
# Set socket options
|
||||
try:
|
||||
listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
@@ -2074,3 +2074,4 @@ def demo():
|
||||
if __name__=='__main__':
|
||||
demo()
|
||||
|
||||
|
||||
|
||||
@@ -225,3 +225,4 @@ def sanitize(text, permitted_tags=[
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+26
-25
@@ -109,9 +109,9 @@ def demo_function(*argv,**kwargs):
|
||||
""" test function """
|
||||
for i in range(argv[0]):
|
||||
print 'click',i
|
||||
time.sleep(1)
|
||||
time.sleep(1)
|
||||
return 'done'
|
||||
|
||||
|
||||
#the two functions below deal with simplejson decoding as unicode, esp for the dict decode
|
||||
#and subsequent usage as function Keyword arguments unicode variable names won't work!
|
||||
#borrowed from http://stackoverflow.com/questions/956867/how-to-get-string-objects-instead-unicode-ones-from-json-in-python
|
||||
@@ -136,12 +136,12 @@ def _decode_dict(dct):
|
||||
v = _decode_list(v)
|
||||
newdict[k] = v
|
||||
return newdict
|
||||
|
||||
|
||||
def executor(queue,task):
|
||||
""" the background process """
|
||||
logging.debug(' task started')
|
||||
stdout, sys.stdout = sys.stdout, cStringIO.StringIO()
|
||||
try:
|
||||
try:
|
||||
if task.app:
|
||||
os.chdir(os.environ['WEB2PY_PATH'])
|
||||
from gluon.shell import env
|
||||
@@ -152,9 +152,9 @@ def executor(queue,task):
|
||||
_env = env(task.app,import_models=True)
|
||||
logging.getLogger().setLevel(level)
|
||||
scheduler = current._scheduler
|
||||
scheduler_tasks = current._scheduler.tasks
|
||||
scheduler_tasks = current._scheduler.tasks
|
||||
_function = scheduler_tasks[task.function]
|
||||
globals().update(_env)
|
||||
globals().update(_env)
|
||||
args = loads(task.args)
|
||||
vars = loads(task.vars, object_hook=_decode_dict)
|
||||
result = dumps(_function(*args,**vars))
|
||||
@@ -182,7 +182,7 @@ class MetaScheduler(threading.Thread):
|
||||
('terminated',None,None)
|
||||
"""
|
||||
queue = multiprocessing.Queue(maxsize=1)
|
||||
p = multiprocessing.Process(target=executor,args=(queue,task))
|
||||
p = multiprocessing.Process(target=executor,args=(queue,task))
|
||||
self.process = p
|
||||
logging.debug(' task starting')
|
||||
p.start()
|
||||
@@ -196,7 +196,7 @@ class MetaScheduler(threading.Thread):
|
||||
return TaskReport(STOPPED)
|
||||
if p.is_alive():
|
||||
p.terminate()
|
||||
p.join()
|
||||
p.join()
|
||||
logging.debug(' task timeout')
|
||||
return TaskReport(TIMEOUT)
|
||||
elif queue.empty():
|
||||
@@ -211,7 +211,7 @@ class MetaScheduler(threading.Thread):
|
||||
logging.info('die!')
|
||||
self.have_heartbeat = False
|
||||
self.terminate_process()
|
||||
|
||||
|
||||
def terminate_process(self):
|
||||
try:
|
||||
self.process.terminate()
|
||||
@@ -221,17 +221,17 @@ class MetaScheduler(threading.Thread):
|
||||
def run(self):
|
||||
""" the thread that sends heartbeat """
|
||||
counter = 0
|
||||
while self.have_heartbeat:
|
||||
while self.have_heartbeat:
|
||||
self.send_heartbeat(counter)
|
||||
counter += 1
|
||||
|
||||
def start_heartbeats(self):
|
||||
self.start()
|
||||
|
||||
|
||||
def send_heartbeat(self,counter):
|
||||
print 'thum'
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
def pop_task(self):
|
||||
return Task(
|
||||
app = None,
|
||||
@@ -243,7 +243,7 @@ class MetaScheduler(threading.Thread):
|
||||
def report_task(self,task,task_report):
|
||||
print 'reporting task'
|
||||
pass
|
||||
|
||||
|
||||
def sleep(self):
|
||||
pass
|
||||
|
||||
@@ -304,7 +304,7 @@ class Scheduler(MetaScheduler):
|
||||
self.worker_name = worker_name or socket.gethostname()+'#'+str(web2py_uuid())
|
||||
|
||||
from gluon import current
|
||||
current._scheduler = self
|
||||
current._scheduler = self
|
||||
|
||||
self.define_tables(db,migrate=migrate)
|
||||
|
||||
@@ -364,7 +364,7 @@ class Scheduler(MetaScheduler):
|
||||
|
||||
def pop_task(self):
|
||||
now = datetime.datetime.now()
|
||||
db, ts = self.db, self.db.scheduler_task
|
||||
db, ts = self.db, self.db.scheduler_task
|
||||
try:
|
||||
logging.debug(' grabbing all queued tasks')
|
||||
all_available = db(ts.status.belongs((QUEUED,RUNNING)))\
|
||||
@@ -385,7 +385,7 @@ class Scheduler(MetaScheduler):
|
||||
grabbed = db(ts.assigned_worker_name==self.worker_name)\
|
||||
(ts.status==ASSIGNED)
|
||||
task = grabbed.select(limitby=(0,1), orderby=ts.next_run_time).first()
|
||||
|
||||
|
||||
logging.debug(' releasing all but one (running)')
|
||||
if task:
|
||||
task.update_record(status=RUNNING,last_run_time=now)
|
||||
@@ -399,7 +399,7 @@ class Scheduler(MetaScheduler):
|
||||
run_again = True
|
||||
else:
|
||||
run_again = False
|
||||
logging.debug(' new scheduler_run record')
|
||||
logging.debug(' new scheduler_run record')
|
||||
while True:
|
||||
try:
|
||||
run_id = db.scheduler_run.insert(
|
||||
@@ -432,7 +432,7 @@ class Scheduler(MetaScheduler):
|
||||
stop_time = datetime.datetime.now(),
|
||||
result = task_report.result,
|
||||
output = task_report.output,
|
||||
traceback = task_report.tb)
|
||||
traceback = task_report.tb)
|
||||
if task_report.status == COMPLETED:
|
||||
d = dict(status = task.run_again and QUEUED or COMPLETED,
|
||||
next_run_time = task.next_run_time,
|
||||
@@ -447,27 +447,27 @@ class Scheduler(MetaScheduler):
|
||||
db(db.scheduler_task.id==task.task_id)\
|
||||
(db.scheduler_task.status==RUNNING).update(**d)
|
||||
db.commit()
|
||||
logging.info('task completed (%s)' % task_report.status)
|
||||
|
||||
logging.info('task completed (%s)' % task_report.status)
|
||||
|
||||
def send_heartbeat(self,counter):
|
||||
if not self.db_thread:
|
||||
logging.debug('thread building own DAL object')
|
||||
logging.debug('thread building own DAL object')
|
||||
self.db_thread = DAL(self.db._uri,folder = self.db._adapter.folder)
|
||||
self.define_tables(self.db_thread,migrate=False)
|
||||
try:
|
||||
db = self.db_thread
|
||||
sw, st = db.scheduler_worker, db.scheduler_task
|
||||
now = datetime.datetime.now()
|
||||
expiration = now-datetime.timedelta(seconds=self.heartbeat*3)
|
||||
expiration = now-datetime.timedelta(seconds=self.heartbeat*3)
|
||||
# record heartbeat
|
||||
logging.debug('........recording heartbeat')
|
||||
logging.debug('........recording heartbeat')
|
||||
if not db(sw.worker_name==self.worker_name)\
|
||||
.update(last_heartbeat = now, status = ACTIVE):
|
||||
sw.insert(status = ACTIVE,worker_name = self.worker_name,
|
||||
first_heartbeat = now,last_heartbeat = now)
|
||||
if counter % 10 == 0:
|
||||
# deallocate jobs assigned to inactive workers and requeue them
|
||||
logging.debug(' freeing workers that have not sent heartbeat')
|
||||
logging.debug(' freeing workers that have not sent heartbeat')
|
||||
inactive_workers = db(sw.last_heartbeat<expiration)
|
||||
db(st.assigned_worker_name.belongs(
|
||||
inactive_workers._select(sw.worker_name)))\
|
||||
@@ -478,7 +478,7 @@ class Scheduler(MetaScheduler):
|
||||
except:
|
||||
db.rollback()
|
||||
time.sleep(self.heartbeat)
|
||||
|
||||
|
||||
def sleep(self):
|
||||
time.sleep(self.heartbeat) # should only sleep until next available task
|
||||
|
||||
@@ -546,3 +546,4 @@ def main():
|
||||
|
||||
if __name__=='__main__':
|
||||
main()
|
||||
|
||||
|
||||
@@ -86,3 +86,4 @@ def rss(feed):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -11,3 +11,4 @@ settings = global_settings # legacy compatibility
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -419,3 +419,4 @@ if __name__ == '__main__':
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -6,3 +6,4 @@ from dal import DAL, Field, Table, Query, Set, Expression, Row, Rows, drivers, B
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+12
-8
@@ -60,19 +60,19 @@ def safe_float(x):
|
||||
|
||||
class FormWidget(object):
|
||||
"""
|
||||
helper for SQLFORM to generate form input fields
|
||||
helper for SQLFORM to generate form input fields
|
||||
(widget), related to the fieldtype
|
||||
"""
|
||||
|
||||
_class = 'generic-widget'
|
||||
|
||||
@classmethod
|
||||
def _attributes(cls, field,
|
||||
def _attributes(cls, field,
|
||||
widget_attributes, **attributes):
|
||||
"""
|
||||
helper to build a common set of attributes
|
||||
|
||||
:param field: the field involved,
|
||||
:param field: the field involved,
|
||||
some attributes are derived from this
|
||||
:param widget_attributes: widget related attributes
|
||||
:param attributes: any other supplied attributes
|
||||
@@ -162,7 +162,7 @@ class TextWidget(FormWidget):
|
||||
"""
|
||||
|
||||
default = dict(value = value)
|
||||
attr = cls._attributes(field, default,
|
||||
attr = cls._attributes(field, default,
|
||||
**attributes)
|
||||
return TEXTAREA(**attr)
|
||||
|
||||
@@ -214,7 +214,7 @@ class OptionsWidget(FormWidget):
|
||||
if hasattr(requires[0], 'options'):
|
||||
options = requires[0].options()
|
||||
else:
|
||||
raise SyntaxError, 'widget cannot determine options of %s' % field
|
||||
raise SyntaxError, 'widget cannot determine options of %s' % field
|
||||
opts = [OPTION(v, _value=k) for (k, v) in options]
|
||||
|
||||
return SELECT(*opts, **attr)
|
||||
@@ -1333,11 +1333,14 @@ class SQLFORM(FORM):
|
||||
_id="w2p_value_"+name)
|
||||
else:
|
||||
value_input = INPUT(_type='text',_id="w2p_value_"+name,_class=field.type)
|
||||
new_button = INPUT(_type="button", _value=T('New'),
|
||||
_onclick="w2p_build_query('new','"+str(field)+"')")
|
||||
and_button = INPUT(_type="button", _value=T('And'),
|
||||
_onclick="w2p_build_query('and','"+str(field)+"')")
|
||||
or_button = INPUT(_type="button", _value=T('Or'),
|
||||
_onclick="w2p_build_query('or','"+str(field)+"')")
|
||||
criterion.extend([operators,value_input,and_button,or_button])
|
||||
|
||||
criterion.extend([operators,value_input,new_button,and_button,or_button])
|
||||
criteria.append(DIV(criterion, _id='w2p_field_%s' % name,
|
||||
_class='w2p_query_row hidden'))
|
||||
criteria.insert(0,SELECT(
|
||||
@@ -1355,7 +1358,7 @@ class SQLFORM(FORM):
|
||||
var s=a+' '+option+' "'+value+'"';
|
||||
var k=jQuery('#web2py_keywords');
|
||||
var v=k.val();
|
||||
k.val((v?(v+' '+ aggregator +' '):'')+s);
|
||||
if(aggregator=='new') k.val(s); else k.val((v?(v+' '+ aggregator +' '):'')+s);
|
||||
jQuery('#w2p_query_fields').val('').change();
|
||||
jQuery('#w2p_query_panel').slideUp();
|
||||
}
|
||||
@@ -1590,7 +1593,7 @@ class SQLFORM(FORM):
|
||||
table = db[request.args[-2]]
|
||||
if ondelete:
|
||||
ondelete(table,request.args[-1],ret)
|
||||
ret = db(table.id==request.args[-1]).delete()
|
||||
ret = db(table.id==request.args[-1]).delete()
|
||||
return ret
|
||||
elif csv and len(request.args)>0 and request.args[-1]=='csv':
|
||||
if request.vars.keywords:
|
||||
@@ -2253,3 +2256,4 @@ form_factory = SQLFORM.factory # for backward compatibility, deprecated
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -224,3 +224,4 @@ if __name__ == '__main__':
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -109,3 +109,4 @@ def stream_file_or_304_or_206(
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -931,3 +931,4 @@ if __name__ == '__main__':
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+17
-16
@@ -39,7 +39,7 @@ except ImportError:
|
||||
except:
|
||||
import contrib.simplejson as json_parser # fallback to pure-Python module
|
||||
|
||||
__all__ = ['Mail', 'Auth', 'Recaptcha', 'Crud', 'Service',
|
||||
__all__ = ['Mail', 'Auth', 'Recaptcha', 'Crud', 'Service',
|
||||
'PluginManager', 'fetch', 'geocode', 'prettydate']
|
||||
|
||||
### mind there are two loggers here (logger and crud.settings.logger)!
|
||||
@@ -834,7 +834,7 @@ class Auth(object):
|
||||
|
||||
def here(self):
|
||||
return URL(args=current.request.args,vars=current.request.vars)
|
||||
|
||||
|
||||
def __init__(self, environment=None, db=None, mailer=True,
|
||||
hmac_key=None, controller='default', cas_provider=None):
|
||||
"""
|
||||
@@ -1443,7 +1443,7 @@ class Auth(object):
|
||||
If the user doesn't yet exist, then they are created.
|
||||
"""
|
||||
table_user = self.settings.table_user
|
||||
user = None
|
||||
user = None
|
||||
checks = []
|
||||
# make a guess about who this user is
|
||||
for fieldname in ['registration_id','username','email']:
|
||||
@@ -1540,7 +1540,7 @@ class Auth(object):
|
||||
del session._cas_service
|
||||
if request.vars.has_key('warn'):
|
||||
response.headers['refresh'] = "5;URL=%s"%service+"?ticket="+ticket
|
||||
return A("Continue to %s"%service,
|
||||
return A("Continue to %s"%service,
|
||||
_href=service+"?ticket="+ticket)
|
||||
else:
|
||||
redirect(service+"?ticket="+ticket)
|
||||
@@ -1690,7 +1690,7 @@ class Auth(object):
|
||||
captcha = self.settings.login_captcha or \
|
||||
(self.settings.login_captcha!=False and self.settings.captcha)
|
||||
if captcha:
|
||||
addrow(form, captcha.label, captcha, captcha.comment,
|
||||
addrow(form, captcha.label, captcha, captcha.comment,
|
||||
self.settings.formstyle,'captcha__row')
|
||||
accepted_form = False
|
||||
|
||||
@@ -1764,7 +1764,7 @@ class Auth(object):
|
||||
cas_user[passfield] = None
|
||||
user = self.get_or_create_user(table_user._filter_fields(cas_user))
|
||||
elif hasattr(cas,'login_form'):
|
||||
return cas.login_form()
|
||||
return cas.login_form()
|
||||
else:
|
||||
# we need to pass through login again before going on
|
||||
next = self.url('user',args='login')
|
||||
@@ -1861,8 +1861,8 @@ class Auth(object):
|
||||
if log is DEFAULT:
|
||||
log = self.messages.register_log
|
||||
|
||||
passfield = self.settings.password_field
|
||||
formstyle = self.settings.formstyle
|
||||
passfield = self.settings.password_field
|
||||
formstyle = self.settings.formstyle
|
||||
form = SQLFORM(table_user,
|
||||
fields = self.settings.register_fields,
|
||||
hidden = dict(_next=next),
|
||||
@@ -2501,7 +2501,7 @@ class Auth(object):
|
||||
|
||||
def f(*a, **b):
|
||||
|
||||
basic_allowed,basic_accepted,user = self.basic()
|
||||
basic_allowed,basic_accepted,user = self.basic()
|
||||
user = user or self.user
|
||||
if requires_login:
|
||||
if not user:
|
||||
@@ -2517,9 +2517,9 @@ class Auth(object):
|
||||
self.settings.on_failed_authentication,
|
||||
self.settings.login_url+\
|
||||
'?_next='+urllib.quote(next))
|
||||
|
||||
|
||||
#Check condition variable.
|
||||
#Since condition could be callable, following cases could occur:
|
||||
#Since condition could be callable, following cases could occur:
|
||||
# 1. condition == True => ok
|
||||
# 2. condition == False => failed
|
||||
# 3. condition is NOT callable but it NOT None and NOT False and NOT 0 => failed
|
||||
@@ -2796,20 +2796,20 @@ class Auth(object):
|
||||
If you have a table (db.mytable) that needs full revision history you can just do:
|
||||
|
||||
form=crud.update(db.mytable,myrecord,onaccept=auth.archive)
|
||||
|
||||
|
||||
or
|
||||
|
||||
form=SQLFORM(db.mytable,myrecord).process(onaccept=auth.archive)
|
||||
|
||||
crud.archive will define a new table "mytable_archive" and store
|
||||
a copy of the current record (if archive_current=True)
|
||||
or a copy of the previous record (if archive_current=False)
|
||||
crud.archive will define a new table "mytable_archive" and store
|
||||
a copy of the current record (if archive_current=True)
|
||||
or a copy of the previous record (if archive_current=False)
|
||||
in the newly created table including a reference
|
||||
to the current record.
|
||||
|
||||
fields allows to specify extra fields that need to be archived.
|
||||
|
||||
If you want to access such table you need to define it yourself
|
||||
If you want to access such table you need to define it yourself
|
||||
in a model:
|
||||
|
||||
db.define_table('mytable_archive',
|
||||
@@ -4109,3 +4109,4 @@ class PluginManager(object):
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
||||
|
||||
@@ -127,3 +127,4 @@ def web2py_uuid():
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+4
-3
@@ -2290,7 +2290,7 @@ class IS_LIST_OF(Validator):
|
||||
self.minimum = minimum
|
||||
self.maximum = maximum
|
||||
self.error_message = error_message or "enter between %(min)g and %(max)g values"
|
||||
|
||||
|
||||
def __call__(self, value):
|
||||
ivalue = value
|
||||
if not isinstance(value, list):
|
||||
@@ -2514,10 +2514,10 @@ class CRYPT(object):
|
||||
If the digest_alg is specified this is used to replace the
|
||||
MD5 with, for example, SHA512. The digest_alg can be
|
||||
the name of a hashlib algorithm as a string or the algorithm itself.
|
||||
|
||||
|
||||
min_length is the minimal password length (default 4) - IS_STRONG for serious security
|
||||
error_message is the message if password is too short
|
||||
|
||||
|
||||
Notice that an empty password is accepted but invalid. It will not allow login back.
|
||||
Stores junk as hashed password.
|
||||
"""
|
||||
@@ -2978,3 +2978,4 @@ if __name__ == '__main__':
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+2
-1
@@ -813,7 +813,7 @@ def start_schedulers(options):
|
||||
p.terminate()
|
||||
p.join()
|
||||
|
||||
|
||||
|
||||
def start(cron=True):
|
||||
""" Start server """
|
||||
|
||||
@@ -982,3 +982,4 @@ def start(cron=True):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -164,3 +164,4 @@ if __name__ == '__main__':
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -22,3 +22,4 @@ def handler(request, response, methods):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user