diff --git a/VERSION b/VERSION
index ba504ebd..a93bd69e 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-Version 2.1.1 (2012-10-19 10:37:01) dev
+Version 2.1.1 (2012-10-19 12:33:48) dev
diff --git a/__init__.py b/__init__.py
index 8b137891..e69de29b 100644
--- a/__init__.py
+++ b/__init__.py
@@ -1 +0,0 @@
-
diff --git a/anyserver.py b/anyserver.py
index 46daf4ec..473cceaa 100644
--- a/anyserver.py
+++ b/anyserver.py
@@ -16,44 +16,47 @@ import urllib
path = os.path.dirname(os.path.abspath(__file__))
os.chdir(path)
-sys.path = [path]+[p for p in sys.path if not p==path]
+sys.path = [path] + [p for p in sys.path if not p == path]
import gluon.main
from gluon.fileutils import read_file, write_file
+
class Servers:
@staticmethod
def cgi(app, address=None, **options):
from wsgiref.handlers import CGIHandler
- CGIHandler().run(app) # Just ignore host and port here
+ CGIHandler().run(app) # Just ignore host and port here
@staticmethod
- def flup(app,address, **options):
+ def flup(app, address, **options):
import flup.server.fcgi
flup.server.fcgi.WSGIServer(app, bindAddress=address).run()
@staticmethod
- def wsgiref(app,address,**options): # pragma: no cover
+ def wsgiref(app, address, **options): # pragma: no cover
from wsgiref.simple_server import make_server, WSGIRequestHandler
+
class QuietHandler(WSGIRequestHandler):
- def log_request(*args, **kw): pass
+ def log_request(*args, **kw):
+ pass
options['handler_class'] = QuietHandler
- srv = make_server(address[0],address[1],app,**options)
+ srv = make_server(address[0], address[1], app, **options)
srv.serve_forever()
@staticmethod
- def cherrypy(app,address, **options):
+ def cherrypy(app, address, **options):
from cherrypy import wsgiserver
server = wsgiserver.CherryPyWSGIServer(address, app)
server.start()
@staticmethod
- def rocket(app,address, **options):
+ def rocket(app, address, **options):
from gluon.rocket import CherryPyWSGIServer
server = CherryPyWSGIServer(address, app)
server.start()
@staticmethod
- def rocket_with_repoze_profiler(app,address, **options):
+ def rocket_with_repoze_profiler(app, address, **options):
from gluon.rocket import CherryPyWSGIServer
from repoze.profile.profiler import AccumulatingProfileMiddleware
from gluon.settings import global_settings
@@ -63,44 +66,46 @@ class Servers:
log_filename='wsgi.prof',
discard_first_request=True,
flush_at_shutdown=True,
- path = '/__profile__'
- )
+ path='/__profile__'
+ )
server = CherryPyWSGIServer(address, wrapped)
server.start()
@staticmethod
- def paste(app,address,**options):
+ def paste(app, address, **options):
from paste import httpserver
from paste.translogger import TransLogger
httpserver.serve(app, host=address[0], port=address[1], **options)
@staticmethod
- def fapws(app,address, **options):
+ def fapws(app, address, **options):
import fapws._evwsgi as evwsgi
from fapws import base
- evwsgi.start(address[0],str(address[1]))
+ evwsgi.start(address[0], str(address[1]))
evwsgi.set_base_module(base)
+
def app(environ, start_response):
environ['wsgi.multiprocess'] = False
return app(environ, start_response)
- evwsgi.wsgi_cb(('',app))
+ evwsgi.wsgi_cb(('', app))
evwsgi.run()
-
@staticmethod
- def gevent(app,address, **options):
- from gevent import monkey; monkey.patch_all()
+ def gevent(app, address, **options):
+ from gevent import monkey
+ monkey.patch_all()
from gevent import pywsgi
from gevent.pool import Pool
- pywsgi.WSGIServer(address, app, spawn = 'workers' in options and Pool(int(options.workers)) or 'default').serve_forever()
+ pywsgi.WSGIServer(address, app, spawn='workers' in options and Pool(
+ int(options.workers)) or 'default').serve_forever()
@staticmethod
- def bjoern(app,address, **options):
+ def bjoern(app, address, **options):
import bjoern
bjoern.run(app, *address)
@staticmethod
- def tornado(app,address, **options):
+ def tornado(app, address, **options):
import tornado.wsgi
import tornado.httpserver
import tornado.ioloop
@@ -110,7 +115,7 @@ class Servers:
tornado.ioloop.IOLoop.instance().start()
@staticmethod
- def twisted(app,address, **options):
+ def twisted(app, address, **options):
from twisted.web import server, wsgi
from twisted.python.threadpool import ThreadPool
from twisted.internet import reactor
@@ -122,42 +127,44 @@ class Servers:
reactor.run()
@staticmethod
- def diesel(app,address, **options):
+ def diesel(app, address, **options):
from diesel.protocols.wsgi import WSGIApplication
app = WSGIApplication(app, port=address[1])
app.run()
@staticmethod
- def gunicorn(app,address, **options):
+ def gunicorn(app, address, **options):
from gunicorn.app.base import Application
config = {'bind': "%s:%d" % address}
config.update(options)
sys.argv = ['anyserver.py']
+
class GunicornApplication(Application):
def init(self, parser, opts, args):
return config
+
def load(self):
return app
g = GunicornApplication()
g.run()
@staticmethod
- def eventlet(app,address, **options):
+ def eventlet(app, address, **options):
from eventlet import wsgi, listen
wsgi.server(listen(address), app)
@staticmethod
- def mongrel2(app,address,**options):
+ def mongrel2(app, address, **options):
import uuid
sys.path.append(os.path.abspath(os.path.dirname(__file__)))
from mongrel2 import handler
conn = handler.Connection(str(uuid.uuid4()),
"tcp://127.0.0.1:9997",
"tcp://127.0.0.1:9996")
- mongrel2_handler(app,conn,debug=False)
+ mongrel2_handler(app, conn, debug=False)
-def run(servername,ip,port,softcron=True,logging=False,profiler=None):
+def run(servername, ip, port, softcron=True, logging=False, profiler=None):
if logging:
application = gluon.main.appfactory(wsgiapp=gluon.main.wsgibase,
logfilename='httpserver.log',
@@ -167,9 +174,10 @@ def run(servername,ip,port,softcron=True,logging=False,profiler=None):
if softcron:
from gluon.settings import global_settings
global_settings.web2py_crontype = 'soft'
- getattr(Servers,servername)(application,(ip,int(port)))
+ getattr(Servers, servername)(application, (ip, int(port)))
-def mongrel2_handler(application,conn,debug=False):
+
+def mongrel2_handler(application, conn, debug=False):
"""
Based on :
https://github.com/berry/Mongrel2-WSGI-Handler/blob/master/wsgi-handler.py
@@ -194,20 +202,23 @@ def mongrel2_handler(application,conn,debug=False):
# and responses. Unless I have missed something.
while True:
- if debug: print "WAITING FOR REQUEST"
+ if debug:
+ print "WAITING FOR REQUEST"
# receive a request
req = conn.recv()
- if debug: print "REQUEST BODY: %r\n" % req.body
+ if debug:
+ print "REQUEST BODY: %r\n" % req.body
if req.is_disconnect():
- if debug: print "DISCONNECT"
- continue #effectively ignore the disconnect from the client
+ if debug:
+ print "DISCONNECT"
+ continue # effectively ignore the disconnect from the client
# Set a couple of environment attributes a.k.a. header attributes
# that are a must according to PEP 333
environ = req.headers
- environ['SERVER_PROTOCOL'] = 'HTTP/1.1' # SimpleHandler expects a server_protocol, lets assume it is HTTP 1.1
+ environ['SERVER_PROTOCOL'] = 'HTTP/1.1' # SimpleHandler expects a server_protocol, lets assume it is HTTP 1.1
environ['REQUEST_METHOD'] = environ['METHOD']
if ':' in environ['Host']:
environ['SERVER_NAME'] = environ['Host'].split(':')[0]
@@ -215,17 +226,19 @@ def mongrel2_handler(application,conn,debug=False):
else:
environ['SERVER_NAME'] = environ['Host']
environ['SERVER_PORT'] = ''
- environ['SCRIPT_NAME'] = '' # empty for now
+ environ['SCRIPT_NAME'] = '' # empty for now
environ['PATH_INFO'] = urllib.unquote(environ['PATH'])
if '?' in environ['URI']:
environ['QUERY_STRING'] = environ['URI'].split('?')[1]
else:
environ['QUERY_STRING'] = ''
if 'Content-Length' in environ:
- environ['CONTENT_LENGTH'] = environ['Content-Length'] # necessary for POST to work with Django
+ environ['CONTENT_LENGTH'] = environ[
+ 'Content-Length'] # necessary for POST to work with Django
environ['wsgi.input'] = req.body
- if debug: print "ENVIRON: %r\n" % environ
+ if debug:
+ print "ENVIRON: %r\n" % environ
# SimpleHandler needs file-like stream objects for
# requests, errors and responses
@@ -234,7 +247,8 @@ def mongrel2_handler(application,conn,debug=False):
respIO = StringIO.StringIO()
# execute the application
- handler = SimpleHandler(reqIO, respIO, errIO, environ, multithread = False, multiprocess = False)
+ handler = SimpleHandler(reqIO, respIO, errIO, environ,
+ multithread=False, multiprocess=False)
handler.run(application)
# Get the response and filter out the response (=data) itself,
@@ -258,11 +272,15 @@ def mongrel2_handler(application,conn,debug=False):
errors = errIO.getvalue()
# return the response
- if debug: print "RESPONSE: %r\n" % response
+ if debug:
+ print "RESPONSE: %r\n" % response
if errors:
- if debug: print "ERRORS: %r" % errors
+ if debug:
+ print "ERRORS: %r" % errors
data = "%s\r\n\r\n%s" % (data, errors)
- conn.reply_http(req, data, code = code, status = status, headers = headers)
+ conn.reply_http(
+ req, data, code=code, status=status, headers=headers)
+
def main():
usage = "python anyserver.py -s tornado -i 127.0.0.1 -p 8000 -l -P"
@@ -282,7 +300,7 @@ def main():
default=False,
dest='profiler',
help='profiler filename')
- servers = ', '.join(x for x in dir(Servers) if not x[0]=='_')
+ servers = ', '.join(x for x in dir(Servers) if not x[0] == '_')
parser.add_option('-s',
'--server',
default='rocket',
@@ -304,8 +322,10 @@ def main():
dest='workers',
help='number of workers number')
(options, args) = parser.parse_args()
- print 'starting %s on %s:%s...' % (options.server,options.ip,options.port)
- run(options.server,options.ip,options.port,logging=options.logging,profiler=options.profiler)
+ print 'starting %s on %s:%s...' % (
+ options.server, options.ip, options.port)
+ run(options.server, options.ip, options.port,
+ logging=options.logging, profiler=options.profiler)
-if __name__=='__main__':
+if __name__ == '__main__':
main()
diff --git a/cgihandler.py b/cgihandler.py
index 3c919199..0929ed15 100755
--- a/cgihandler.py
+++ b/cgihandler.py
@@ -56,7 +56,7 @@ import wsgiref.handlers
path = os.path.dirname(os.path.abspath(__file__))
os.chdir(path)
-sys.path = [path]+[p for p in sys.path if not p==path]
+sys.path = [path] + [p for p in sys.path if not p == path]
import gluon.main
diff --git a/fcgihandler.py b/fcgihandler.py
index 76cda9b8..a3d4a5df 100755
--- a/fcgihandler.py
+++ b/fcgihandler.py
@@ -34,7 +34,7 @@ import os
path = os.path.dirname(os.path.abspath(__file__))
os.chdir(path)
-sys.path = [path]+[p for p in sys.path if not p==path]
+sys.path = [path] + [p for p in sys.path if not p == path]
import gluon.main
import gluon.contrib.gateways.fcgi as fcgi
diff --git a/gaehandler.py b/gaehandler.py
index 0965fffe..b039d40b 100755
--- a/gaehandler.py
+++ b/gaehandler.py
@@ -33,7 +33,7 @@ import wsgiref.handlers
import datetime
path = os.path.dirname(os.path.abspath(__file__))
-sys.path = [path]+[p for p in sys.path if not p==path]
+sys.path = [path] + [p for p in sys.path if not p == path]
sys.modules['cPickle'] = sys.modules['pickle']
@@ -83,7 +83,7 @@ def wsgiapp(env, res):
if global_settings.web2py_runtime == 'gae:development':
gluon.admin.create_missing_folders()
- web2py_path = global_settings.applications_parent # backward compatibility
+ web2py_path = global_settings.applications_parent # backward compatibility
return gluon.main.wsgibase(env, res)
@@ -91,6 +91,7 @@ def wsgiapp(env, res):
if LOG_STATS or DEBUG:
wsgiapp = log_stats(wsgiapp)
+
def main():
"""Run the wsgi app"""
run_wsgi_app(wsgiapp)
diff --git a/gluon/__init__.py b/gluon/__init__.py
index 7065a70a..3e9801f7 100644
--- a/gluon/__init__.py
+++ b/gluon/__init__.py
@@ -10,7 +10,7 @@ Web2Py framework modules
========================
"""
-__all__ = ['A', 'B', 'BEAUTIFY', 'BODY', 'BR', 'CAT', 'CENTER', 'CLEANUP', 'CODE', 'CRYPT', 'DAL', 'DIV', 'EM', 'EMBED', 'FIELDSET', 'FORM', 'Field', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'HEAD', 'HR', 'HTML', 'HTTP', 'I', 'IFRAME', 'IMG', 'INPUT', 'IS_ALPHANUMERIC', 'IS_DATE', 'IS_DATETIME', 'IS_DATETIME_IN_RANGE', 'IS_DATE_IN_RANGE', 'IS_DECIMAL_IN_RANGE', 'IS_EMAIL', 'IS_EMPTY_OR', 'IS_EQUAL_TO', 'IS_EXPR', 'IS_FLOAT_IN_RANGE', 'IS_IMAGE', 'IS_INT_IN_RANGE', 'IS_IN_DB', 'IS_IN_SET', 'IS_IPV4', 'IS_LENGTH', 'IS_LIST_OF', 'IS_LOWER', 'IS_MATCH', 'IS_NOT_EMPTY', 'IS_NOT_IN_DB', 'IS_NULL_OR', 'IS_SLUG', 'IS_STRONG', 'IS_TIME', 'IS_UPLOAD_FILENAME', 'IS_UPPER', 'IS_URL', 'LABEL', 'LEGEND', 'LI', 'LINK', 'LOAD', 'MARKMIN', 'MENU', 'META', 'OBJECT', 'OL', 'ON', 'OPTGROUP', 'OPTION', 'P', 'PRE', 'SCRIPT', 'SELECT', 'SPAN', 'SQLFORM', 'SQLTABLE', 'STRONG', 'STYLE', 'TABLE', 'TAG', 'TBODY', 'TD', 'TEXTAREA', 'TFOOT', 'TH', 'THEAD', 'TITLE', 'TR', 'TT', 'UL', 'URL', 'XHTML', 'XML','redirect','current','embed64']
+__all__ = ['A', 'B', 'BEAUTIFY', 'BODY', 'BR', 'CAT', 'CENTER', 'CLEANUP', 'CODE', 'CRYPT', 'DAL', 'DIV', 'EM', 'EMBED', 'FIELDSET', 'FORM', 'Field', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'HEAD', 'HR', 'HTML', 'HTTP', 'I', 'IFRAME', 'IMG', 'INPUT', 'IS_ALPHANUMERIC', 'IS_DATE', 'IS_DATETIME', 'IS_DATETIME_IN_RANGE', 'IS_DATE_IN_RANGE', 'IS_DECIMAL_IN_RANGE', 'IS_EMAIL', 'IS_EMPTY_OR', 'IS_EQUAL_TO', 'IS_EXPR', 'IS_FLOAT_IN_RANGE', 'IS_IMAGE', 'IS_INT_IN_RANGE', 'IS_IN_DB', 'IS_IN_SET', 'IS_IPV4', 'IS_LENGTH', 'IS_LIST_OF', 'IS_LOWER', 'IS_MATCH', 'IS_NOT_EMPTY', 'IS_NOT_IN_DB', 'IS_NULL_OR', 'IS_SLUG', 'IS_STRONG', 'IS_TIME', 'IS_UPLOAD_FILENAME', 'IS_UPPER', 'IS_URL', 'LABEL', 'LEGEND', 'LI', 'LINK', 'LOAD', 'MARKMIN', 'MENU', 'META', 'OBJECT', 'OL', 'ON', 'OPTGROUP', 'OPTION', 'P', 'PRE', 'SCRIPT', 'SELECT', 'SPAN', 'SQLFORM', 'SQLTABLE', 'STRONG', 'STYLE', 'TABLE', 'TAG', 'TBODY', 'TD', 'TEXTAREA', 'TFOOT', 'TH', 'THEAD', 'TITLE', 'TR', 'TT', 'UL', 'URL', 'XHTML', 'XML', 'redirect', 'current', 'embed64']
from globals import current
from html import *
diff --git a/gluon/admin.py b/gluon/admin.py
index ba392dbb..7f7888cb 100644
--- a/gluon/admin.py
+++ b/gluon/admin.py
@@ -23,6 +23,7 @@ from http import HTTP
if not global_settings.web2py_runtime_gae:
import site
+
def apath(path='', r=None):
"""
Builds a path inside an application folder
@@ -95,6 +96,7 @@ def app_pack_compiled(app, request, raise_ex=False):
raise
return None
+
def app_cleanup(app, request):
"""
Removes session, cache and error files
@@ -113,7 +115,7 @@ def app_cleanup(app, request):
if os.path.exists(path):
for f in os.listdir(path):
try:
- if f[:1]!='.': os.unlink(os.path.join(path,f))
+ if f[:1] != '.': os.unlink(os.path.join(path, f))
except IOError:
r = False
@@ -122,7 +124,7 @@ def app_cleanup(app, request):
if os.path.exists(path):
for f in os.listdir(path):
try:
- if f[:1]!='.': recursive_unlink(os.path.join(path,f))
+ if f[:1] != '.': recursive_unlink(os.path.join(path, f))
except IOError:
r = False
@@ -131,7 +133,7 @@ def app_cleanup(app, request):
if os.path.exists(path):
for f in os.listdir(path):
try:
- if f[:1]!='.': os.unlink(os.path.join(path,f))
+ if f[:1] != '.': os.unlink(os.path.join(path, f))
except IOError:
r = False
return r
@@ -158,7 +160,8 @@ def app_compile(app, request):
remove_compiled_application(folder)
return tb
-def app_create(app, request,force=False,key=None,info=False):
+
+def app_create(app, request, force=False, key=None, info=False):
"""
Create a copy of welcome.w2p (scaffolding) app
@@ -186,17 +189,17 @@ def app_create(app, request,force=False,key=None,info=False):
return False
try:
w2p_unpack('welcome.w2p', path)
- for subfolder in ['models','views','controllers', 'databases',
- 'modules','cron','errors','sessions',
- 'languages','static','private','uploads']:
- subpath = os.path.join(path,subfolder)
+ for subfolder in ['models', 'views', 'controllers', 'databases',
+ 'modules', 'cron', 'errors', 'sessions',
+ 'languages', 'static', 'private', 'uploads']:
+ subpath = os.path.join(path, subfolder)
if not os.path.exists(subpath):
os.mkdir(subpath)
db = os.path.join(path, 'models', 'db.py')
if os.path.exists(db):
data = read_file(db)
data = data.replace('',
- 'sha512:'+(key or web2py_uuid()))
+ 'sha512:' + (key or web2py_uuid()))
write_file(db, data)
if info:
return True, None
@@ -283,6 +286,7 @@ def app_uninstall(app, request):
except Exception:
return False
+
def plugin_pack(app, plugin_name, request):
"""
Builds a w2p package for the application
@@ -302,12 +306,14 @@ def plugin_pack(app, plugin_name, request):
filename of the w2p file or None on error
"""
try:
- filename = apath('../deposit/web2py.plugin.%s.w2p' % plugin_name, request)
+ filename = apath(
+ '../deposit/web2py.plugin.%s.w2p' % plugin_name, request)
w2p_pack_plugin(filename, apath(app, request), plugin_name)
return filename
except Exception:
return False
+
def plugin_install(app, fobj, request, filename):
"""
Installs an application:
@@ -345,6 +351,7 @@ def plugin_install(app, fobj, request, filename):
os.unlink(upname)
return False
+
def check_new_version(myversion, version_URL):
"""
Compares current web2py's version with the latest stable web2py version.
@@ -375,6 +382,7 @@ def check_new_version(myversion, version_URL):
else:
return False, version
+
def unzip(filename, dir, subfolder=''):
"""
Unzips filename into dir (.zip only, no .gz etc)
@@ -382,7 +390,7 @@ def unzip(filename, dir, subfolder=''):
"""
filename = abspath(filename)
if not zipfile.is_zipfile(filename):
- raise RuntimeError, 'Not a valid zipfile'
+ raise RuntimeError('Not a valid zipfile')
zf = zipfile.ZipFile(filename)
if not subfolder.endswith('/'):
subfolder = subfolder + '/'
@@ -392,7 +400,7 @@ def unzip(filename, dir, subfolder=''):
continue
#print name[n:]
if name.endswith('/'):
- folder = os.path.join(dir,name[n:])
+ folder = os.path.join(dir, name[n:])
if not os.path.exists(folder):
os.mkdir(folder)
else:
@@ -421,7 +429,7 @@ def upgrade(request, url='http://web2py.com'):
if not gluon_parent.endswith('/'):
gluon_parent = gluon_parent + '/'
(check, version) = check_new_version(web2py_version,
- url+'/examples/default/version')
+ url + '/examples/default/version')
if not check:
return (False, 'Already latest version')
if os.path.exists(os.path.join(gluon_parent, 'web2py.exe')):
@@ -442,35 +450,40 @@ def upgrade(request, url='http://web2py.com'):
file = None
try:
write_file(filename, urllib.urlopen(full_url).read(), 'wb')
- except Exception,e:
+ except Exception, e:
return False, e
try:
unzip(filename, destination, subfolder)
return True, None
- except Exception,e:
+ except Exception, e:
return False, e
+
def add_path_first(path):
- sys.path = [path]+[p for p in sys.path if (not p==path and not p==(path+'/'))]
+ sys.path = [path] + [p for p in sys.path if (
+ not p == path and not p == (path + '/'))]
if not global_settings.web2py_runtime_gae:
site.addsitedir(path)
+
def create_missing_folders():
if not global_settings.web2py_runtime_gae:
for path in ('applications', 'deposit', 'site-packages', 'logs'):
path = abspath(path, gluon=True)
if not os.path.exists(path):
os.mkdir(path)
- paths = (global_settings.gluon_parent, abspath('site-packages', gluon=True), abspath('gluon', gluon=True), '')
+ paths = (global_settings.gluon_parent, abspath(
+ 'site-packages', gluon=True), abspath('gluon', gluon=True), '')
[add_path_first(path) for path in paths]
+
def create_missing_app_folders(request):
if not global_settings.web2py_runtime_gae:
if request.folder not in global_settings.app_folders:
for subfolder in ('models', 'views', 'controllers', 'databases',
'modules', 'cron', 'errors', 'sessions',
'languages', 'static', 'private', 'uploads'):
- path = os.path.join(request.folder, subfolder)
+ path = os.path.join(request.folder, subfolder)
if not os.path.exists(path):
os.mkdir(path)
global_settings.app_folders.add(request.folder)
diff --git a/gluon/cache.py b/gluon/cache.py
index ec26711f..6c52c418 100644
--- a/gluon/cache.py
+++ b/gluon/cache.py
@@ -40,6 +40,7 @@ __all__ = ['Cache', 'lazy_cache']
DEFAULT_TIME_EXPIRE = 300
+
class CacheAbstract(object):
"""
Abstract class for cache implementations.
@@ -73,7 +74,7 @@ class CacheAbstract(object):
raise NotImplementedError
def __call__(self, key, f,
- time_expire = DEFAULT_TIME_EXPIRE):
+ time_expire=DEFAULT_TIME_EXPIRE):
"""
Tries retrieve the value corresponding to `key` from the cache of the
object exists and if it did not expire, else it called the function `f`
@@ -130,6 +131,7 @@ class CacheAbstract(object):
if r.match(str(key)):
del storage[key]
+
class CacheInRam(CacheAbstract):
"""
Ram based caching
@@ -147,8 +149,10 @@ class CacheInRam(CacheAbstract):
self.request = request
def initialize(self):
- if self.initialized: return
- else: self.initialized = True
+ if self.initialized:
+ return
+ else:
+ self.initialized = True
self.locker.acquire()
request = self.request
if request:
@@ -172,13 +176,14 @@ class CacheInRam(CacheAbstract):
self._clear(storage, regex)
if not CacheAbstract.cache_stats_name in storage.keys():
- storage[CacheAbstract.cache_stats_name] = {'hit_total': 0,'misses': 0}
+ storage[CacheAbstract.cache_stats_name] = {
+ 'hit_total': 0, 'misses': 0}
self.locker.release()
def __call__(self, key, f,
- time_expire = DEFAULT_TIME_EXPIRE,
- destroyer = None):
+ time_expire=DEFAULT_TIME_EXPIRE,
+ destroyer=None):
"""
Attention! cache.ram does not copy the cached object. It just stores a reference to it.
Turns out the deepcopying the object has some problems:
@@ -269,14 +274,15 @@ class CacheOnDisk(CacheAbstract):
try:
storage = shelve.open(self.shelve_name)
except:
- logger.error('corrupted cache file %s, will try rebuild it' \
- % (self.shelve_name))
+ logger.error('corrupted cache file %s, will try rebuild it'
+ % (self.shelve_name))
storage = None
if not storage and os.path.exists(self.shelve_name):
os.unlink(self.shelve_name)
storage = shelve.open(self.shelve_name)
if not CacheAbstract.cache_stats_name in storage.keys():
- storage[CacheAbstract.cache_stats_name] = {'hit_total':0, 'misses': 0}
+ storage[CacheAbstract.cache_stats_name] = {
+ 'hit_total': 0, 'misses': 0}
storage.sync()
except Exception, e:
if storage:
@@ -286,7 +292,8 @@ class CacheOnDisk(CacheAbstract):
portalocker.unlock(locker)
locker.close()
locked = False
- raise RuntimeError, 'unable to create/re-create cache file %s' % self.shelve_name
+ raise RuntimeError(
+ 'unable to create/re-create cache file %s' % self.shelve_name)
self.locker = locker
self.locked = locked
self.storage = storage
@@ -298,8 +305,10 @@ class CacheOnDisk(CacheAbstract):
self.folder = folder
def initialize(self):
- if self.initialized: return
- else: self.initialized = True
+ if self.initialized:
+ return
+ else:
+ self.initialized = True
folder = self.folder
request = self.request
@@ -312,8 +321,8 @@ class CacheOnDisk(CacheAbstract):
### we need this because of a possible bug in shelve that may
### or may not lock
- self.locker_name = os.path.join(folder,'cache.lock')
- self.shelve_name = os.path.join(folder,'cache.shelve')
+ self.locker_name = os.path.join(folder, 'cache.lock')
+ self.shelve_name = os.path.join(folder, 'cache.shelve')
def clear(self, regex=None):
self.initialize()
@@ -328,7 +337,7 @@ class CacheOnDisk(CacheAbstract):
self._close_shelve_and_unlock()
def __call__(self, key, f,
- time_expire = DEFAULT_TIME_EXPIRE):
+ time_expire=DEFAULT_TIME_EXPIRE):
self.initialize()
dt = time_expire
storage = self._open_shelve_and_lock()
@@ -346,7 +355,7 @@ class CacheOnDisk(CacheAbstract):
else:
value = f()
storage[key] = (now, value)
- storage[CacheAbstract.cache_stats_name]['misses']+=1
+ storage[CacheAbstract.cache_stats_name]['misses'] += 1
storage.sync()
finally:
self._close_shelve_and_unlock()
@@ -365,8 +374,9 @@ class CacheOnDisk(CacheAbstract):
self._close_shelve_and_unlock()
return value
+
class CacheAction(object):
- def __init__(self,func,key,time_expire,cache,cache_model):
+ def __init__(self, func, key, time_expire, cache, cache_model):
self.__name__ = func.__name__
self.__doc__ = func.__doc__
self.func = func
@@ -374,17 +384,18 @@ class CacheAction(object):
self.time_expire = time_expire
self.cache = cache
self.cache_model = cache_model
- def __call__(self,*a,**b):
+
+ def __call__(self, *a, **b):
if not self.key:
- key2 = self.__name__+':'+repr(a)+':'+repr(b)
+ key2 = self.__name__ + ':' + repr(a) + ':' + repr(b)
else:
- key2 = self.key.replace('%(name)s',self.__name__)\
- .replace('%(args)s',str(a)).replace('%(vars)s',str(b))
+ key2 = self.key.replace('%(name)s', self.__name__)\
+ .replace('%(args)s', str(a)).replace('%(vars)s', str(b))
cache_model = self.cache_model
- if not cache_model or isinstance(cache_model,str):
- cache_model = getattr(self.cache,cache_model or 'ram')
+ if not cache_model or isinstance(cache_model, str):
+ cache_model = getattr(self.cache, cache_model or 'ram')
return cache_model(key2,
- lambda a=a,b=b:self.func(*a,**b),
+ lambda a=a, b=b: self.func(*a, **b),
self.time_expire)
@@ -424,9 +435,9 @@ class Cache(object):
logger.warning('no cache.disk (AttributeError)')
def __call__(self,
- key = None,
- time_expire = DEFAULT_TIME_EXPIRE,
- cache_model = None):
+ key=None,
+ time_expire=DEFAULT_TIME_EXPIRE,
+ cache_model=None):
"""
Decorator function that can be used to cache any function/method.
@@ -459,8 +470,8 @@ class Cache(object):
`request.env.path_info` as key.
"""
- def tmp(func,cache=self,cache_model=cache_model):
- return CacheAction(func,key,time_expire,self,cache_model)
+ def tmp(func, cache=self, cache_model=cache_model):
+ return CacheAction(func, key, time_expire, self, cache_model)
return tmp
@staticmethod
@@ -473,7 +484,7 @@ class Cache(object):
cache_model(prefix + key, f, time_expire)
-def lazy_cache(key=None,time_expire=None,cache_model='ram'):
+def lazy_cache(key=None, time_expire=None, cache_model='ram'):
"""
can be used to cache any function including in modules,
as long as the cached function is only called within a web2py request
@@ -481,11 +492,12 @@ def lazy_cache(key=None,time_expire=None,cache_model='ram'):
the time_expire defaults to None (no cache expiration)
if cache_model is "ram" then the model is current.cache.ram, etc.
"""
- def decorator(f,key=key,time_expire=time_expire,cache_model=cache_model):
+ def decorator(f, key=key, time_expire=time_expire, cache_model=cache_model):
key = key or repr(f)
- def g(*c,**d):
+
+ def g(*c, **d):
from gluon import current
- return current.cache(key,time_expire,cache_model)(f)(*c,**d)
+ return current.cache(key, time_expire, cache_model)(f)(*c, **d)
g.__name__ = f.__name__
return g
return decorator
diff --git a/gluon/compileapp.py b/gluon/compileapp.py
index fc3eada8..36360d7a 100644
--- a/gluon/compileapp.py
+++ b/gluon/compileapp.py
@@ -48,7 +48,7 @@ except:
logger.warning('unable to import py_compile')
is_pypy = settings.global_settings.is_pypy
-is_gae = settings.global_settings.web2py_runtime_gae
+is_gae = settings.global_settings.web2py_runtime_gae
is_jython = settings.global_settings.is_jython
pjoin = os.path.join
@@ -95,6 +95,7 @@ _TEST()
CACHED_REGEXES = {}
CACHED_REGEXES_MAX_SIZE = 1000
+
def re_compile(regex):
try:
return CACHED_REGEXES[regex]
@@ -104,6 +105,7 @@ def re_compile(regex):
compiled_regex = CACHED_REGEXES[regex] = re.compile(regex)
return compiled_regex
+
class mybuiltin(object):
"""
NOTE could simple use a dict and populate it,
@@ -114,14 +116,16 @@ class mybuiltin(object):
try:
return getattr(__builtin__, key)
except AttributeError:
- raise KeyError, key
+ raise KeyError(key)
+
def __setitem__(self, key, value):
setattr(self, key, value)
+
def LOAD(c=None, f='index', args=None, vars=None,
- extension=None, target=None,ajax=False,ajax_trap=False,
- url=None,user_signature=False, timeout=None, times=1,
- content='loading...',**attr):
+ extension=None, target=None, ajax=False, ajax_trap=False,
+ url=None, user_signature=False, timeout=None, times=1,
+ content='loading...', **attr):
""" LOAD a component into the action's document
Timing options:
@@ -134,13 +138,14 @@ def LOAD(c=None, f='index', args=None, vars=None,
is added on page loading without delay.
"""
from html import TAG, DIV, URL, SCRIPT, XML
- if args is None: args = []
+ if args is None:
+ args = []
vars = Storage(vars or {})
- target = target or 'c'+str(random.random())[2:]
- attr['_id']=target
+ target = target or 'c' + str(random.random())[2:]
+ attr['_id'] = target
request = current.request
if '.' in f:
- f, extension = f.rsplit('.',1)
+ f, extension = f.rsplit('.', 1)
if url or ajax:
url = url or URL(request.application, c, f, r=request,
args=args, vars=vars, extension=extension,
@@ -160,19 +165,20 @@ def LOAD(c=None, f='index', args=None, vars=None,
if not isinstance(timeout, (int, long)):
raise ValueError("Timeout argument must be an integer or None")
elif timeout <= 0:
- raise ValueError("Timeout argument must be greater than zero or None")
+ raise ValueError(
+ "Timeout argument must be greater than zero or None")
statement = "web2py_component('%s','%s', %s, %s);" \
- % (url, target, timeout, times)
+ % (url, target, timeout, times)
else:
statement = "web2py_component('%s','%s');" % (url, target)
script = SCRIPT(statement, _type="text/javascript")
if not content is None:
- return TAG[''](script, DIV(content,**attr))
+ return TAG[''](script, DIV(content, **attr))
else:
return TAG[''](script)
else:
- if not isinstance(args,(list,tuple)):
+ if not isinstance(args, (list, tuple)):
args = [args]
c = c or request.controller
other_request = Storage(request)
@@ -186,17 +192,17 @@ def LOAD(c=None, f='index', args=None, vars=None,
other_request.post_vars = Storage()
other_response = Response()
other_request.env.path_info = '/' + \
- '/'.join([request.application,c,f] + \
- map(str, other_request.args))
+ '/'.join([request.application, c, f] +
+ map(str, other_request.args))
other_request.env.query_string = \
vars and URL(vars=vars).split('?')[1] or ''
other_request.env.http_web2py_component_location = \
request.env.path_info
other_request.cid = target
other_request.env.http_web2py_component_element = target
- other_response.view = '%s/%s.%s' % (c,f, other_request.extension)
+ other_response.view = '%s/%s.%s' % (c, f, other_request.extension)
- other_environment = copy.copy(current.globalenv) ### NASTY
+ other_environment = copy.copy(current.globalenv) # NASTY
other_response._view_environment = other_environment
other_response.generic_patterns = \
@@ -218,40 +224,41 @@ def LOAD(c=None, f='index', args=None, vars=None,
js = None
if ajax_trap:
link = URL(request.application, c, f, r=request,
- args=args, vars=vars, extension=extension,
- user_signature=user_signature)
+ args=args, vars=vars, extension=extension,
+ user_signature=user_signature)
js = "web2py_trap_form('%s','%s');" % (link, target)
- script = js and SCRIPT(js,_type="text/javascript") or ''
- return TAG[''](DIV(XML(page),**attr),script)
-
+ script = js and SCRIPT(js, _type="text/javascript") or ''
+ return TAG[''](DIV(XML(page), **attr), script)
class LoadFactory(object):
"""
Attention: this helper is new and experimental
"""
- def __init__(self,environment):
+ def __init__(self, environment):
self.environment = environment
+
def __call__(self, c=None, f='index', args=None, vars=None,
- extension=None, target=None,ajax=False,ajax_trap=False,
- url=None,user_signature=False, content='loading...',**attr):
- if args is None: args = []
+ extension=None, target=None, ajax=False, ajax_trap=False,
+ url=None, user_signature=False, content='loading...', **attr):
+ if args is None:
+ args = []
vars = Storage(vars or {})
import globals
- target = target or 'c'+str(random.random())[2:]
- attr['_id']=target
+ target = target or 'c' + str(random.random())[2:]
+ attr['_id'] = target
request = self.environment['request']
if '.' in f:
- f, extension = f.rsplit('.',1)
+ f, extension = f.rsplit('.', 1)
if url or ajax:
url = url or html.URL(request.application, c, f, r=request,
args=args, vars=vars, extension=extension,
user_signature=user_signature)
script = html.SCRIPT('web2py_component("%s","%s")' % (url, target),
_type="text/javascript")
- return html.TAG[''](script, html.DIV(content,**attr))
+ return html.TAG[''](script, html.DIV(content, **attr))
else:
- if not isinstance(args,(list,tuple)):
+ if not isinstance(args, (list, tuple)):
args = [args]
c = c or request.controller
@@ -266,15 +273,15 @@ class LoadFactory(object):
other_request.post_vars = Storage()
other_response = globals.Response()
other_request.env.path_info = '/' + \
- '/'.join([request.application,c,f] + \
- map(str, other_request.args))
+ '/'.join([request.application, c, f] +
+ map(str, other_request.args))
other_request.env.query_string = \
vars and html.URL(vars=vars).split('?')[1] or ''
other_request.env.http_web2py_component_location = \
request.env.path_info
other_request.cid = target
other_request.env.http_web2py_component_element = target
- other_response.view = '%s/%s.%s' % (c,f, other_request.extension)
+ other_response.view = '%s/%s.%s' % (c, f, other_request.extension)
other_environment = copy.copy(self.environment)
other_response._view_environment = other_environment
other_response.generic_patterns = \
@@ -299,8 +306,8 @@ class LoadFactory(object):
args=args, vars=vars, extension=extension,
user_signature=user_signature)
js = "web2py_trap_form('%s','%s');" % (link, target)
- script = js and html.SCRIPT(js,_type="text/javascript") or ''
- return html.TAG[''](html.DIV(html.XML(page),**attr),script)
+ script = js and html.SCRIPT(js, _type="text/javascript") or ''
+ return html.TAG[''](html.DIV(html.XML(page), **attr), script)
def local_import_aux(name, reload_force=False, app='welcome'):
@@ -321,7 +328,7 @@ def local_import_aux(name, reload_force=False, app='welcome'):
This prevents conflict between applications and un-necessary execs.
It can be used to import any module, including regular Python modules.
"""
- items = name.replace('/','.')
+ items = name.replace('/', '.')
name = "applications.%s.modules.%s" % (app, items)
module = __import__(name)
for item in name.split(".")[1:]:
@@ -355,12 +362,14 @@ OLD IMPLEMENTATION:
file.close()
imp.release_lock()
if not module:
- raise ImportError, "cannot find module %s in %s" % (filename, modulepath)
+ raise ImportError, "cannot find module %s in %s" % (
+ filename, modulepath)
return module
"""
-_base_environment_ = dict((k,getattr(html,k)) for k in html.__all__)
-_base_environment_.update((k,getattr(validators,k)) for k in validators.__all__)
+_base_environment_ = dict((k, getattr(html, k)) for k in html.__all__)
+_base_environment_.update(
+ (k, getattr(validators, k)) for k in validators.__all__)
_base_environment_['__builtins__'] = __builtins__
_base_environment_['HTTP'] = HTTP
_base_environment_['redirect'] = redirect
@@ -372,6 +381,7 @@ _base_environment_['SQLFORM'] = SQLFORM
_base_environment_['SQLTABLE'] = SQLTABLE
_base_environment_['LOAD'] = LOAD
+
def build_environment(request, response, session, store_current=True):
"""
Build the environment dictionary into which web2py files are executed.
@@ -384,7 +394,7 @@ def build_environment(request, response, session, store_current=True):
# Enable standard conditional models (i.e., /*.py, /[controller]/*.py, and
# /[controller]/[function]/*.py)
response.models_to_run = [r'^\w+\.py$', r'^%s/\w+\.py$' % request.controller,
- r'^%s/%s/\w+\.py$' % (request.controller, request.function)]
+ r'^%s/%s/\w+\.py$' % (request.controller, request.function)]
t = environment['T'] = translator(request)
c = environment['cache'] = Cache(request)
@@ -398,23 +408,24 @@ def build_environment(request, response, session, store_current=True):
current.cache = c
global __builtins__
- if is_jython: # jython hack
+ if is_jython: # jython hack
__builtins__ = mybuiltin()
- elif is_pypy: # apply the same hack to pypy too
+ elif is_pypy: # apply the same hack to pypy too
__builtins__ = mybuiltin()
else:
- __builtins__['__import__'] = __builtin__.__import__ ### WHY?
+ __builtins__['__import__'] = __builtin__.__import__ # WHY?
environment['request'] = request
environment['response'] = response
environment['session'] = session
environment['local_import'] = \
- lambda name, reload=False, app=request.application:\
- local_import_aux(name,reload,app)
+ lambda name, reload=False, app=request.application:\
+ local_import_aux(name, reload, app)
BaseAdapter.set_folder(pjoin(request.folder, 'databases'))
response._view_environment = copy.copy(environment)
custom_import_install()
return environment
+
def save_pyc(filename):
"""
Bytecode compiles the file `filename`
@@ -431,7 +442,7 @@ def read_pyc(filename):
"""
data = read_file(filename, 'rb')
if not is_gae and data[:4] != imp.get_magic():
- raise SystemError, 'compiled code is incompatible'
+ raise SystemError('compiled code is incompatible')
return marshal.loads(data[8:])
@@ -458,7 +469,7 @@ def compile_models(folder):
path = pjoin(folder, 'models')
for file in listdir(path, '.+\.py$'):
data = read_file(pjoin(path, file))
- filename = pjoin(folder, 'compiled','models',file)
+ filename = pjoin(folder, 'compiled', 'models', file)
mktree(filename)
write_file(filename, data)
save_pyc(filename)
@@ -473,14 +484,14 @@ def compile_controllers(folder):
path = pjoin(folder, 'controllers')
for file in listdir(path, '.+\.py$'):
### why is this here? save_pyc(pjoin(path, file))
- data = read_file(pjoin(path,file))
+ data = read_file(pjoin(path, file))
exposed = regex_expose.findall(data)
for function in exposed:
command = data + "\nresponse._vars=response._caller(%s)\n" % \
function
filename = pjoin(folder, 'compiled', ('controllers/'
+ file[:-3]).replace('/', '_')
- + '_' + function + '.py')
+ + '_' + function + '.py')
write_file(filename, command)
save_pyc(filename)
os.unlink(filename)
@@ -500,19 +511,19 @@ def run_models_in(environment):
for model in listdir(cpath, '^models_\w+\.pyc$', 0):
restricted(read_pyc(model), environment, layer=model)
path = pjoin(cpath, 'models')
- models = listdir(path, '^\w+\.pyc$',0,sort=False)
- compiled=True
+ models = listdir(path, '^\w+\.pyc$', 0, sort=False)
+ compiled = True
else:
path = pjoin(folder, 'models')
- models = listdir(path, '^\w+\.py$',0,sort=False)
- compiled=False
+ models = listdir(path, '^\w+\.py$', 0, sort=False)
+ compiled = False
n = len(path) + 1
for model in models:
regex = environment['response'].models_to_run
if isinstance(regex, list):
regex = re_compile('|'.join(regex))
file = model[n:].replace(os.path.sep, '/').replace('.pyc', '.py')
- if not regex.search(file) and c!= 'appadmin':
+ if not regex.search(file) and c != 'appadmin':
continue
elif compiled:
code = read_pyc(model)
@@ -538,7 +549,7 @@ def run_controller_in(controller, function, environment):
badf = 'invalid function (%s/%s)' % (controller, function)
if os.path.exists(path):
filename = pjoin(path, 'controllers_%s_%s.pyc'
- % (controller, function))
+ % (controller, function))
if not os.path.exists(filename):
raise HTTP(404,
rewrite.THREAD_LOCAL.routes.error_message % badf,
@@ -548,7 +559,8 @@ def run_controller_in(controller, function, environment):
# TESTING: adjust the path to include site packages
from settings import global_settings
from admin import abspath, add_path_first
- paths = (global_settings.gluon_parent, abspath('site-packages', gluon=True), abspath('gluon', gluon=True), '')
+ paths = (global_settings.gluon_parent, abspath(
+ 'site-packages', gluon=True), abspath('gluon', gluon=True), '')
[add_path_first(path) for path in paths]
# TESTING END
@@ -578,18 +590,19 @@ def run_controller_in(controller, function, environment):
code = "%s\nresponse._vars=response._caller(%s)\n" % (code, function)
if is_gae:
layer = filename + ':' + function
- code = getcfs(layer, filename, lambda: compile2(code,layer))
+ code = getcfs(layer, filename, lambda: compile2(code, layer))
restricted(code, environment, filename)
response = environment['response']
- vars=response._vars
+ vars = response._vars
if response.postprocessing:
vars = reduce(lambda vars, p: p(vars), response.postprocessing, vars)
- if isinstance(vars,unicode):
+ if isinstance(vars, unicode):
vars = vars.encode('utf8')
- elif hasattr(vars,'xml') and callable(vars.xml):
+ elif hasattr(vars, 'xml') and callable(vars.xml):
vars = vars.xml()
return vars
+
def run_view_in(environment):
"""
Executes the view for the requested action.
@@ -606,7 +619,7 @@ def run_view_in(environment):
if response.generic_patterns:
patterns = response.generic_patterns
regex = re_compile('|'.join(map(fnmatch.translate, patterns)))
- short_action = '%(controller)s/%(function)s.%(extension)s' % request
+ short_action = '%(controller)s/%(function)s.%(extension)s' % request
allow_generic = regex.search(short_action)
else:
allow_generic = False
@@ -626,7 +639,7 @@ def run_view_in(environment):
files.append('views_generic.pyc')
# end backward compatibility code
for f in files:
- filename = pjoin(path,f)
+ filename = pjoin(path, f)
if os.path.exists(filename):
code = read_pyc(filename)
restricted(code, environment, layer=filename)
@@ -648,13 +661,14 @@ def run_view_in(environment):
ccode = getcfs(layer, filename,
lambda: compile2(parse_template(view,
pjoin(folder, 'views'),
- context=environment),layer))
+ context=environment), layer))
else:
ccode = parse_template(view,
pjoin(folder, 'views'),
context=environment)
restricted(ccode, environment, layer)
+
def remove_compiled_application(folder):
"""
Deletes the folder `compiled` containing the compiled application.
@@ -662,7 +676,7 @@ def remove_compiled_application(folder):
try:
shutil.rmtree(pjoin(folder, 'compiled'))
path = pjoin(folder, 'controllers')
- for file in listdir(path,'.*\.pyc$',drop=False):
+ for file in listdir(path, '.*\.pyc$', drop=False):
os.unlink(file)
except OSError:
pass
diff --git a/gluon/contenttype.py b/gluon/contenttype.py
index 4270bb6c..7d221330 100644
--- a/gluon/contenttype.py
+++ b/gluon/contenttype.py
@@ -700,7 +700,7 @@ CONTENT_TYPE = {
'.zabw': 'application/x-abiword',
'.zip': 'application/zip',
'.zoo': 'application/x-zoo',
- }
+}
def contenttype(filename, default='text/plain'):
@@ -709,11 +709,11 @@ def contenttype(filename, default='text/plain'):
"""
i = filename.rfind('.')
- if i>=0:
- default = CONTENT_TYPE.get(filename[i:].lower(),default)
+ if i >= 0:
+ default = CONTENT_TYPE.get(filename[i:].lower(), default)
j = filename.rfind('.', 0, i)
- if j>=0:
- default = CONTENT_TYPE.get(filename[j:].lower(),default)
+ if j >= 0:
+ default = CONTENT_TYPE.get(filename[j:].lower(), default)
if default.startswith('text/'):
default += '; charset=utf-8'
return default
diff --git a/gluon/contrib/AuthorizeNet.py b/gluon/contrib/AuthorizeNet.py
index d54d7ee9..da882d08 100755
--- a/gluon/contrib/AuthorizeNet.py
+++ b/gluon/contrib/AuthorizeNet.py
@@ -21,6 +21,7 @@ import urllib
_known_tuple_types = {}
+
class NamedTupleBase(tuple):
"""Base class for named tuples with the __new__ operator set, named tuples
yielded by the namedtuple() function will subclass this and add
@@ -29,7 +30,7 @@ class NamedTupleBase(tuple):
"""Create a new instance of this fielded tuple"""
# May need to unpack named field values here
if kws:
- values = list(args) + [None]*(len(cls._fields) - len(args))
+ values = list(args) + [None] * (len(cls._fields) - len(args))
fields = dict((val, idx) for idx, val in enumerate(cls._fields))
for kw, val in kws.iteritems():
assert kw in kws, "%r not in field list" % kw
@@ -37,6 +38,7 @@ class NamedTupleBase(tuple):
args = tuple(values)
return tuple.__new__(cls, args)
+
def namedtuple(typename, fieldnames):
"""
>>> import namedtuples
@@ -75,24 +77,26 @@ def namedtuple(typename, fieldnames):
# Done
return new_tuple_type
+
class AIM:
class AIMError(Exception):
def __init__(self, value):
self.parameter = value
+
def __str__(self):
return str(self.parameter)
def __init__(self, login, transkey, testmode=False):
- if str(login).strip() == '' or login == None:
+ if str(login).strip() == '' or login is None:
raise AIM.AIMError('No login name provided')
- if str(transkey).strip() == '' or transkey == None:
+ if str(transkey).strip() == '' or transkey is None:
raise AIM.AIMError('No transaction key provided')
if testmode != True and testmode != False:
raise AIM.AIMError('Invalid value for testmode. Must be True or False. "{0}" given.'.format(testmode))
self.testmode = testmode
- self.proxy = None;
+ self.proxy = None
self.delimiter = '|'
self.results = []
self.error = True
@@ -117,8 +121,9 @@ class AIM:
else:
url = 'https://secure.authorize.net/gateway/transact.dll'
- if self.proxy == None:
- self.results += str(urllib.urlopen(url, encoded_args).read()).split(self.delimiter)
+ if self.proxy is None:
+ self.results += str(urllib.urlopen(
+ url, encoded_args).read()).split(self.delimiter)
else:
opener = urllib.FancyURLopener(self.proxy)
opened = opener.open(url, encoded_args)
@@ -147,36 +152,37 @@ class AIM:
raise AIM.AIMError(self.response.ResponseText)
def setTransaction(self, creditcard, expiration, total, cvv=None, tax=None, invoice=None):
- if str(creditcard).strip() == '' or creditcard == None:
+ if str(creditcard).strip() == '' or creditcard is None:
raise AIM.AIMError('No credit card number passed to setTransaction(): {0}'.format(creditcard))
- if str(expiration).strip() == '' or expiration == None:
+ if str(expiration).strip() == '' or expiration is None:
raise AIM.AIMError('No expiration number to setTransaction(): {0}'.format(expiration))
- if str(total).strip() == '' or total == None:
+ if str(total).strip() == '' or total is None:
raise AIM.AIMError('No total amount passed to setTransaction(): {0}'.format(total))
self.setParameter('x_card_num', creditcard)
self.setParameter('x_exp_date', expiration)
self.setParameter('x_amount', total)
- if cvv != None:
+ if cvv is not None:
self.setParameter('x_card_code', cvv)
- if tax != None:
+ if tax is not None:
self.setParameter('x_tax', tax)
- if invoice != None:
+ if invoice is not None:
self.setParameter('x_invoice_num', invoice)
def setTransactionType(self, transtype=None):
- types = ['AUTH_CAPTURE', 'AUTH_ONLY', 'PRIOR_AUTH_CAPTURE', 'CREDIT', 'CAPTURE_ONLY', 'VOID']
+ types = ['AUTH_CAPTURE', 'AUTH_ONLY', 'PRIOR_AUTH_CAPTURE',
+ 'CREDIT', 'CAPTURE_ONLY', 'VOID']
if transtype.upper() not in types:
raise AIM.AIMError('Incorrect Transaction Type passed to setTransactionType(): {0}'.format(transtype))
self.setParameter('x_type', transtype.upper())
def setProxy(self, proxy=None):
- if str(proxy).strip() == '' or proxy == None:
+ if str(proxy).strip() == '' or proxy is None:
raise AIM.AIMError('No proxy passed to setProxy()')
self.proxy = {'http': str(proxy).strip()}
def setParameter(self, key=None, value=None):
- if key != None and value != None and str(key).strip() != '' and str(value).strip() != '':
+ if key is not None and value is not None and str(key).strip() != '' and str(value).strip() != '':
self.parameters[key] = str(value).strip()
else:
raise AIM.AIMError('Incorrect parameters passed to setParameter(): {0}:{1}'.format(key, value))
@@ -194,10 +200,11 @@ class AIM:
responses = ['', 'Approved', 'Declined', 'Error']
return responses[int(self.results[0])]
-def process(creditcard,expiration,total,cvv=None,tax=None,invoice=None,
- login='cnpdev4289', transkey='SR2P8g4jdEn7vFLQ',testmode=True):
- payment = AIM(login,transkey,testmode)
- expiration = expiration.replace('/','')
+
+def process(creditcard, expiration, total, cvv=None, tax=None, invoice=None,
+ login='cnpdev4289', transkey='SR2P8g4jdEn7vFLQ', testmode=True):
+ payment = AIM(login, transkey, testmode)
+ expiration = expiration.replace('/', '')
payment.setTransaction(creditcard, expiration, total, cvv, tax, invoice)
try:
payment.process()
@@ -205,6 +212,7 @@ def process(creditcard,expiration,total,cvv=None,tax=None,invoice=None,
except AIM.AIMError:
return False
+
def test():
import socket
import sys
@@ -215,12 +223,14 @@ def test():
total = '1.00'
cvv = '123'
tax = '0.00'
- invoice = str(time())[4:10] # get a random invoice number
+ invoice = str(time())[4:10] # get a random invoice number
try:
payment = AIM('cnpdev4289', 'SR2P8g4jdEn7vFLQ', True)
- payment.setTransaction(creditcard, expiration, total, cvv, tax, invoice)
- payment.setParameter('x_duplicate_window', 180) # three minutes duplicate windows
+ payment.setTransaction(
+ creditcard, expiration, total, cvv, tax, invoice)
+ payment.setParameter(
+ 'x_duplicate_window', 180) # three minutes duplicate windows
payment.setParameter('x_cust_id', '1324') # customer ID
payment.setParameter('x_first_name', 'John')
payment.setParameter('x_last_name', 'Conde')
@@ -232,7 +242,8 @@ def test():
payment.setParameter('x_country', 'US')
payment.setParameter('x_phone', '800-555-1234')
payment.setParameter('x_description', 'Test Transaction')
- payment.setParameter('x_customer_ip', socket.gethostbyname(socket.gethostname()))
+ payment.setParameter(
+ 'x_customer_ip', socket.gethostbyname(socket.gethostname()))
payment.setParameter('x_email', 'john@example.com')
payment.setParameter('x_email_customer', False)
payment.process()
@@ -251,9 +262,9 @@ def test():
except AIM.AIMError, e:
print "Exception thrown:", e
print 'An error occured'
- print 'approved',payment.isApproved()
- print 'declined',payment.isDeclined()
- print 'error',payment.isError()
+ print 'approved', payment.isApproved()
+ print 'declined', payment.isDeclined()
+ print 'error', payment.isError()
-if __name__=='__main__':
+if __name__ == '__main__':
test()
diff --git a/gluon/contrib/DowCommerce.py b/gluon/contrib/DowCommerce.py
index 03d19fd1..d06b088f 100644
--- a/gluon/contrib/DowCommerce.py
+++ b/gluon/contrib/DowCommerce.py
@@ -15,25 +15,27 @@ __all__ = ['DowCommerce']
from operator import itemgetter
import urllib
+
class DowCommerce:
class DowCommerceError(Exception):
def __init__(self, value):
self.parameter = value
+
def __str__(self):
return str(self.parameter)
def __init__(self, username=None, password=None, demomode=False):
if not demomode:
- if str(username).strip() == '' or username == None:
+ if str(username).strip() == '' or username is None:
raise DowCommerce.DowCommerceError('No username provided')
- if str(password).strip() == '' or password == None:
+ if str(password).strip() == '' or password is None:
raise DowCommerce.DowCommerceError('No password provided')
else:
username = 'demo'
password = 'password'
- self.proxy = None;
+ self.proxy = None
self.delimiter = '&'
self.results = {}
self.error = True
@@ -45,11 +47,11 @@ class DowCommerce:
self.setParameter('username', username)
self.setParameter('password', password)
-
def process(self):
encoded_args = urllib.urlencode(self.parameters)
- if self.proxy == None:
- results = str(urllib.urlopen(self.url, encoded_args).read()).split(self.delimiter)
+ if self.proxy is None:
+ results = str(urllib.urlopen(
+ self.url, encoded_args).read()).split(self.delimiter)
else:
opener = urllib.FancyURLopener(self.proxy)
opened = opener.open(self.url, encoded_args)
@@ -59,7 +61,7 @@ class DowCommerce:
opened.close()
for result in results:
- (key,val) = result.split('=')
+ (key, val) = result.split('=')
self.results[key] = val
if self.results['response'] == '1':
@@ -80,17 +82,18 @@ class DowCommerce:
self.declined = False
raise DowCommerce.DowCommerceError(self.results)
- def setTransaction(self, creditcard, expiration, total, cvv=None, orderid=None, orderdescription=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,
- shipping_city=None, shipping_state=None, shipping_zipcode = None, shipping_country=None, shipping_emailaddress=None):
- if str(creditcard).strip() == '' or creditcard == None:
+ def setTransaction(
+ self, creditcard, expiration, total, cvv=None, orderid=None, orderdescription=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,
+ shipping_city=None, shipping_state=None, shipping_zipcode=None, shipping_country=None, shipping_emailaddress=None):
+ if str(creditcard).strip() == '' or creditcard is None:
raise DowCommerce.DowCommerceError('No credit card number passed to setTransaction(): {0}'.format(creditcard))
- if str(expiration).strip() == '' or expiration == None:
+ if str(expiration).strip() == '' or expiration is None:
raise DowCommerce.DowCommerceError('No expiration number passed to setTransaction(): {0}'.format(expiration))
- if str(total).strip() == '' or total == None:
+ if str(total).strip() == '' or total is None:
raise DowCommerce.DowCommerceError('No total amount passed to setTransaction(): {0}'.format(total))
self.setParameter('ccnumber', creditcard)
@@ -165,12 +168,12 @@ class DowCommerce:
self.setParameter('type', transtype.lower())
def setProxy(self, proxy=None):
- if str(proxy).strip() == '' or proxy == None:
+ if str(proxy).strip() == '' or proxy is None:
raise DowCommerce.DowCommerceError('No proxy passed to setProxy()')
self.proxy = {'http': str(proxy).strip()}
def setParameter(self, key=None, value=None):
- if key != None and value != None and str(key).strip() != '' and str(value).strip() != '':
+ if key is not None and value is not None and str(key).strip() != '' and str(value).strip() != '':
self.parameters[key] = str(value).strip()
else:
raise DowCommerce.DowCommerceError('Incorrect parameters passed to setParameter(): {0}:{1}'.format(key, value))
@@ -194,6 +197,7 @@ class DowCommerce:
def getResponseText(self):
return self.results['responsetext']
+
def test():
import socket
import sys
@@ -212,13 +216,14 @@ def test():
total = '1.00'
cvv = '999'
tax = '0.00'
- orderid = str(time())[4:10] # get a random invoice number
+ orderid = str(time())[4:10] # get a random invoice number
try:
payment = DowCommerce(demomode=True)
- 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.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():
@@ -231,9 +236,9 @@ def test():
except DowCommerce.DowCommerceError, e:
print "Exception thrown:", e
print 'An error occured'
- print 'approved',payment.isApproved()
- print 'declined',payment.isDeclined()
- print 'error',payment.isError()
+ print 'approved', payment.isApproved()
+ print 'declined', payment.isDeclined()
+ print 'error', payment.isError()
-if __name__=='__main__':
+if __name__ == '__main__':
test()
diff --git a/gluon/contrib/__init__.py b/gluon/contrib/__init__.py
index 8b137891..e69de29b 100644
--- a/gluon/contrib/__init__.py
+++ b/gluon/contrib/__init__.py
@@ -1 +0,0 @@
-
diff --git a/gluon/contrib/autolinks.py b/gluon/contrib/autolinks.py
index 05f02b64..48f555cb 100644
--- a/gluon/contrib/autolinks.py
+++ b/gluon/contrib/autolinks.py
@@ -42,7 +42,9 @@ revision3.com
viddler.com
"""
-import re, cgi, sys
+import re
+import cgi
+import sys
from simplejson import loads
import urllib
import uuid
@@ -75,23 +77,28 @@ EMBED_MAPS = [
'http://revision3.com/api/oembed/'),
(re.compile('http://\S+.viddler.com/\S+'),
'http://lab.viddler.com/services/oembed/'),
- ]
+]
+
def image(url):
return '
' % url
+
def audio(url):
return '' % url
+
def video(url):
return '' % url
+
def googledoc_viewer(url):
return '' % urllib.quote(url)
+
def web2py_component(url):
code = str(uuid.uuid4())
- return '' % (code,url,code)
+ return '' % (code, url, code)
EXTENSION_MAPS = {
'png': image,
@@ -126,33 +133,37 @@ EXTENSION_MAPS = {
'xps': googledoc_viewer,
}
+
class VimeoURLOpener(urllib.FancyURLopener):
"Vimeo blocks the urllib user agent for some reason"
version = "Mozilla/4.0"
urllib._urlopener = VimeoURLOpener()
+
def oembed(url):
- for k,v in EMBED_MAPS:
+ for k, v in EMBED_MAPS:
if k.match(url):
- oembed = v+'?format=json&url='+cgi.escape(url)
+ oembed = v + '?format=json&url=' + cgi.escape(url)
try:
data = urllib.urlopen(oembed).read()
print data
- return loads(data) # json!
+ return loads(data) # json!
except:
pass
return {}
+
def extension(url):
return url.split('?')[0].split('.')[-1].lower()
-def expand_one(url,cdict):
+
+def expand_one(url, cdict):
# try ombed but first check in cache
if cdict and url in cdict:
r = cdict[url]
else:
r = oembed(url)
- if isinstance(cdict,dict):
+ if isinstance(cdict, dict):
cdict[url] = r
# if oembed service
if 'html' in r:
@@ -170,21 +181,23 @@ def expand_one(url,cdict):
# else regular link
return '%(u)s' % dict(u=url)
-def expand_html(html,cdict=None):
+
+def expand_html(html, cdict=None):
if not have_soup:
- raise RuntimeError, "Missing BeautifulSoup"
+ raise RuntimeError("Missing BeautifulSoup")
soup = BeautifulSoup(html)
- comments = soup.findAll(text=lambda text:isinstance(text, Comment))
+ comments = soup.findAll(text=lambda text: isinstance(text, Comment))
[comment.extract() for comment in comments]
for txt in soup.findAll(text=True):
- if not txt.parent.name in ('a','script','pre','code','embed','object','audio','video'):
+ if not txt.parent.name in ('a', 'script', 'pre', 'code', 'embed', 'object', 'audio', 'video'):
ntxt = regex_link.sub(
- lambda match: expand_one(match.group(0),cdict), txt)
+ lambda match: expand_one(match.group(0), cdict), txt)
txt.replaceWith(BeautifulSoup(ntxt))
return str(soup)
+
def test():
- example="""
+ example = """
Fringilla nisi parturient nullam
http://www.youtube.com/watch?v=IWBFiI5RrA0
http://www.web2py.com/examples/static/images/logo_bw.png
@@ -198,8 +211,8 @@ laoreet tortor.
"""
return expand_html(example)
-if __name__=="__main__":
- if len(sys.argv)>1:
+if __name__ == "__main__":
+ if len(sys.argv) > 1:
print expand_html(open(sys.argv[1]).read())
else:
print test()
diff --git a/gluon/contrib/gae_memcache.py b/gluon/contrib/gae_memcache.py
index ec08fd6a..67efd499 100644
--- a/gluon/contrib/gae_memcache.py
+++ b/gluon/contrib/gae_memcache.py
@@ -12,6 +12,7 @@ cache.ram=cache.disk=MemcacheClient(request)
import time
from google.appengine.api.memcache import Client
+
class MemcacheClient(object):
client = Client()
@@ -24,12 +25,12 @@ class MemcacheClient(object):
key,
f,
time_expire=300,
- ):
+ ):
key = '%s/%s' % (self.request.application, key)
dt = time_expire
value = None
obj = self.client.get(key)
- if obj and (dt == None or obj[0] > time.time() - dt):
+ if obj and (dt is None or obj[0] > time.time() - dt):
value = obj[1]
elif f is None:
if obj:
@@ -47,21 +48,21 @@ class MemcacheClient(object):
self.client.set(key, (time.time(), value))
return value
- def clear(self, key = None):
+ def clear(self, key=None):
if key:
key = '%s/%s' % (self.request.application, key)
self.client.delete(key)
else:
self.client.flush_all()
- def delete(self,*a,**b):
- return self.client.delete(*a,**b)
+ def delete(self, *a, **b):
+ return self.client.delete(*a, **b)
- def get(self,*a,**b):
- return self.client.delete(*a,**b)
+ def get(self, *a, **b):
+ return self.client.delete(*a, **b)
- def set(self,*a,**b):
- return self.client.delete(*a,**b)
+ def set(self, *a, **b):
+ return self.client.delete(*a, **b)
- def flush_all(self,*a,**b):
- return self.client.delete(*a,**b)
+ def flush_all(self, *a, **b):
+ return self.client.delete(*a, **b)
diff --git a/gluon/contrib/gae_retry.py b/gluon/contrib/gae_retry.py
index 9b0fe426..59844521 100644
--- a/gluon/contrib/gae_retry.py
+++ b/gluon/contrib/gae_retry.py
@@ -51,7 +51,8 @@ def autoretry_datastore_timeouts(attempts=5.0, interval=0.1, exponent=2.0):
:param exponent: rate of exponential back-off.
"""
- import time, logging
+ import time
+ import logging
from google.appengine.api import apiproxy_stub_map
from google.appengine.runtime import apiproxy_errors
from google.appengine.datastore import datastore_pb
@@ -60,8 +61,8 @@ def autoretry_datastore_timeouts(attempts=5.0, interval=0.1, exponent=2.0):
interval = float(interval)
exponent = float(exponent)
wrapped = apiproxy_stub_map.MakeSyncCall
- errors = {datastore_pb.Error.TIMEOUT:'Timeout',
- datastore_pb.Error.CONCURRENT_TRANSACTION:'TransactionFailedError'}
+ errors = {datastore_pb.Error.TIMEOUT: 'Timeout',
+ datastore_pb.Error.CONCURRENT_TRANSACTION: 'TransactionFailedError'}
def wrapper(*args, **kwargs):
count = 0.0
@@ -70,10 +71,12 @@ def autoretry_datastore_timeouts(attempts=5.0, interval=0.1, exponent=2.0):
return wrapped(*args, **kwargs)
except apiproxy_errors.ApplicationError, err:
errno = err.application_error
- if errno not in errors: raise
+ if errno not in errors:
+ raise
sleep = (exponent ** count) * interval
count += 1.0
- if count > attempts: raise
+ if count > attempts:
+ raise
msg = "Datastore %s: retry #%d in %s seconds.\n%s"
vals = ''
if count == 1.0:
diff --git a/gluon/contrib/generics.py b/gluon/contrib/generics.py
index fa074416..f1922975 100644
--- a/gluon/contrib/generics.py
+++ b/gluon/contrib/generics.py
@@ -12,6 +12,7 @@ from gluon.sanitizer import sanitize
from gluon.contrib.markmin.markmin2latex import markmin2latex
from gluon.contrib.markmin.markmin2pdf import markmin2pdf
+
def wrapper(f):
def g(data):
try:
@@ -25,39 +26,47 @@ def wrapper(f):
raise HTTP(405, '%s error' % e)
return g
+
def latex_from_html(html):
- markmin=TAG(html).element('body').flatten(markmin_serializer)
+ markmin = TAG(html).element('body').flatten(markmin_serializer)
return XML(markmin2latex(markmin))
+
def pdflatex_from_html(html):
- if os.system('which pdflatex > /dev/null')==0:
- markmin=TAG(html).element('body').flatten(markmin_serializer)
- out,warnings,errors=markmin2pdf(markmin)
+ if os.system('which pdflatex > /dev/null') == 0:
+ markmin = TAG(html).element('body').flatten(markmin_serializer)
+ out, warnings, errors = markmin2pdf(markmin)
if errors:
- current.response.headers['Content-Type']='text/html'
- raise HTTP(405,HTML(BODY(H1('errors'),
- UL(*errors),
- H1('warnings'),
- UL(*warnings))).xml())
+ current.response.headers['Content-Type'] = 'text/html'
+ raise HTTP(405, HTML(BODY(H1('errors'),
+ UL(*errors),
+ H1('warnings'),
+ UL(*warnings))).xml())
else:
return XML(out)
+
def pyfpdf_from_html(html):
request = current.request
+
def image_map(path):
if path.startswith('/%s/static/' % request.application):
- return os.path.join(request.folder,path.split('/',2)[2])
- return 'http%s://%s%s' % (request.is_https and 's' or '',request.env.http_host, path)
- class MyFPDF(FPDF, HTMLMixin): pass
- pdf=MyFPDF()
+ return os.path.join(request.folder, path.split('/', 2)[2])
+ return 'http%s://%s%s' % (request.is_https and 's' or '', request.env.http_host, path)
+
+ class MyFPDF(FPDF, HTMLMixin):
+ pass
+ pdf = MyFPDF()
pdf.add_page()
- html = sanitize(html, escape=False) #### should have better list of allowed tags
- pdf.write_html(html,image_map=image_map)
+ html = sanitize(
+ html, escape=False) # should have better list of allowed tags
+ pdf.write_html(html, image_map=image_map)
return XML(pdf.output(dest='S'))
+
def pdf_from_html(html):
# try use latex and pdflatex
- if os.system('which pdflatex > /dev/null')==0:
+ if os.system('which pdflatex > /dev/null') == 0:
return pdflatex_from_html(html)
else:
return pyfpdf_from_html(html)
diff --git a/gluon/contrib/google_wallet.py b/gluon/contrib/google_wallet.py
index ffcbd9f8..f24c9074 100644
--- a/gluon/contrib/google_wallet.py
+++ b/gluon/contrib/google_wallet.py
@@ -1,5 +1,6 @@
from gluon import XML
+
def button(merchant_id="123456789012345",
products=[dict(name="shoes",
quantity=1,
@@ -8,8 +9,8 @@ def button(merchant_id="123456789012345",
description="running shoes black")]):
t = ''
list_products = ''
- for k,product in enumerate(products):
- for key,value in product.items():
- list_products += t % dict(k=k+1,key=key,value=value)
+ for k, product in enumerate(products):
+ for key, value in product.items():
+ list_products += t % dict(k=k + 1, key=key, value=value)
button = '' % (merchant_id, list_products, merchant_id)
return XML(button)
diff --git a/gluon/contrib/gql.py b/gluon/contrib/gql.py
index d1023ab1..5438888b 100644
--- a/gluon/contrib/gql.py
+++ b/gluon/contrib/gql.py
@@ -1,5 +1,5 @@
# this file exists for backward compatibility
-__all__ = ['DAL','Field','drivers','gae']
+__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
diff --git a/gluon/contrib/imageutils.py b/gluon/contrib/imageutils.py
index 96facc08..594fe521 100644
--- a/gluon/contrib/imageutils.py
+++ b/gluon/contrib/imageutils.py
@@ -22,6 +22,7 @@
#########################################################################
from gluon import current
+
class RESIZE(object):
def __init__(self, nx=160, ny=80, error_message=' image resize'):
(self.nx, self.ny, self.error_message) = (nx, ny, error_message)
@@ -43,6 +44,7 @@ class RESIZE(object):
else:
return (value, None)
+
def THUMB(image, nx=120, ny=120, gae=False, name='thumb'):
if image:
if not gae:
diff --git a/gluon/contrib/login_methods/__init__.py b/gluon/contrib/login_methods/__init__.py
index b28b04f6..e69de29b 100644
--- a/gluon/contrib/login_methods/__init__.py
+++ b/gluon/contrib/login_methods/__init__.py
@@ -1,3 +0,0 @@
-
-
-
diff --git a/gluon/contrib/login_methods/basic_auth.py b/gluon/contrib/login_methods/basic_auth.py
index fee1c35b..88341d05 100644
--- a/gluon/contrib/login_methods/basic_auth.py
+++ b/gluon/contrib/login_methods/basic_auth.py
@@ -11,9 +11,9 @@ def basic_auth(server="http://127.0.0.1"):
"""
def basic_login_aux(username,
- password,
- server=server):
- key = base64.b64encode(username+':'+password)
+ password,
+ server=server):
+ key = base64.b64encode(username + ':' + password)
headers = {'Authorization': 'Basic ' + key}
request = urllib2.Request(server, None, headers)
try:
@@ -22,5 +22,3 @@ def basic_auth(server="http://127.0.0.1"):
except (urllib2.URLError, urllib2.HTTPError):
return False
return basic_login_aux
-
-
diff --git a/gluon/contrib/login_methods/browserid_account.py b/gluon/contrib/login_methods/browserid_account.py
index 83375c8e..c3ccb38c 100644
--- a/gluon/contrib/login_methods/browserid_account.py
+++ b/gluon/contrib/login_methods/browserid_account.py
@@ -25,6 +25,7 @@ from gluon.storage import Storage
from gluon.tools import fetch
import gluon.contrib.simplejson as json
+
class BrowserID(object):
"""
from gluon.contrib.login_methods.browserid_account import BrowserID
@@ -34,17 +35,17 @@ class BrowserID(object):
"""
def __init__(self,
- request,
- audience = "",
- assertion_post_url = "",
- prompt = "BrowserID Login",
- issuer = "browserid.org",
- verify_url = "https://browserid.org/verify",
- browserid_js = "https://browserid.org/include.js",
- browserid_button = "https://browserid.org/i/sign_in_red.png",
- crypto_js = "https://crypto-js.googlecode.com/files/2.2.0-crypto-md5.js",
- on_login_failure = None,
- ):
+ request,
+ audience="",
+ assertion_post_url="",
+ prompt="BrowserID Login",
+ issuer="browserid.org",
+ verify_url="https://browserid.org/verify",
+ browserid_js="https://browserid.org/include.js",
+ browserid_button="https://browserid.org/i/sign_in_red.png",
+ crypto_js="https://crypto-js.googlecode.com/files/2.2.0-crypto-md5.js",
+ on_login_failure=None,
+ ):
self.request = request
self.audience = audience
@@ -67,13 +68,13 @@ class BrowserID(object):
if request.vars.assertion:
audience = self.audience
issuer = self.issuer
- assertion = XML(request.vars.assertion,sanitize=True)
- verify_data = {'assertion':assertion,'audience':audience}
- auth_info_json = fetch(self.verify_url,data=verify_data)
+ assertion = XML(request.vars.assertion, sanitize=True)
+ verify_data = {'assertion': assertion, 'audience': audience}
+ auth_info_json = fetch(self.verify_url, data=verify_data)
j = json.loads(auth_info_json)
- epoch_time = int(time.time()*1000) # we need 13 digit epoch time
+ epoch_time = int(time.time() * 1000) # we need 13 digit epoch time
if j["status"] == "okay" and j["audience"] == audience and j['issuer'] == issuer and j['expires'] >= epoch_time:
- return dict(email = j['email'])
+ return dict(email=j['email'])
elif self.on_login_failure:
redirect('http://google.com')
else:
@@ -83,9 +84,8 @@ class BrowserID(object):
def login_form(self):
request = self.request
onclick = "javascript:navigator.id.getVerifiedEmail(gotVerifiedEmail) ; return false"
- form = DIV(SCRIPT(_src=self.browserid_js,_type="text/javascript"),
- SCRIPT(_src=self.crypto_js,_type="text/javascript"),
- A(IMG(_src=self.browserid_button,_alt=self.prompt),_href="#",_onclick=onclick,_class="browserid",_title="Login With BrowserID"),
- SCRIPT(self.asertion_js))
+ form = DIV(SCRIPT(_src=self.browserid_js, _type="text/javascript"),
+ SCRIPT(_src=self.crypto_js, _type="text/javascript"),
+ A(IMG(_src=self.browserid_button, _alt=self.prompt), _href="#", _onclick=onclick, _class="browserid", _title="Login With BrowserID"),
+ SCRIPT(self.asertion_js))
return form
-
diff --git a/gluon/contrib/login_methods/cas_auth.py b/gluon/contrib/login_methods/cas_auth.py
index 0c922a56..54abf92e 100644
--- a/gluon/contrib/login_methods/cas_auth.py
+++ b/gluon/contrib/login_methods/cas_auth.py
@@ -11,7 +11,8 @@ Tinkered by Szabolcs Gyuris < szimszo n @ o regpreshaz dot eu>
from gluon import current, redirect
-class CasAuth( object ):
+
+class CasAuth(object):
"""
Login will be done via Web2py's CAS application, instead of web2py's
login form.
@@ -39,101 +40,105 @@ class CasAuth( object ):
user's username.
"""
- def __init__(self, g=None, ### g for backward compatibility ###
- urlbase = "https://web2py.com/cas/cas",
- actions=['login','validate','logout'],
- maps=dict(username=lambda v:v.get('username',v['user']),
- email=lambda v:v.get('email',None),
- user_id=lambda v:v['user']),
- casversion = 1,
- casusername = 'cas:user'
+ def __init__(self, g=None, # g for backward compatibility ###
+ urlbase="https://web2py.com/cas/cas",
+ actions=['login', 'validate', 'logout'],
+ maps=dict(username=lambda v: v.get('username', v['user']),
+ email=lambda v: v.get('email', None),
+ user_id=lambda v: v['user']),
+ casversion=1,
+ casusername='cas:user'
):
- self.urlbase=urlbase
- self.cas_login_url="%s/%s"%(self.urlbase,actions[0])
- self.cas_check_url="%s/%s"%(self.urlbase,actions[1])
- self.cas_logout_url="%s/%s"%(self.urlbase,actions[2])
- self.maps=maps
+ self.urlbase = urlbase
+ self.cas_login_url = "%s/%s" % (self.urlbase, actions[0])
+ self.cas_check_url = "%s/%s" % (self.urlbase, actions[1])
+ self.cas_logout_url = "%s/%s" % (self.urlbase, actions[2])
+ self.maps = maps
self.casversion = casversion
self.casusername = casusername
- http_host=current.request.env.http_x_forwarded_host
- if not http_host: http_host=current.request.env.http_host
- if current.request.env.wsgi_url_scheme in [ 'https', 'HTTPS' ]:
+ http_host = current.request.env.http_x_forwarded_host
+ if not http_host:
+ http_host = current.request.env.http_host
+ if current.request.env.wsgi_url_scheme in ['https', 'HTTPS']:
scheme = 'https'
else:
scheme = 'http'
- self.cas_my_url='%s://%s%s'%( scheme, http_host, current.request.env.path_info )
+ self.cas_my_url = '%s://%s%s' % (
+ scheme, http_host, current.request.env.path_info)
- def login_url( self, next = "/" ):
- current.session.token=self._CAS_login()
+ def login_url(self, next="/"):
+ current.session.token = self._CAS_login()
return next
- def logout_url( self, next = "/" ):
- current.session.token=None
- current.session.auth=None
+
+ def logout_url(self, next="/"):
+ current.session.token = None
+ current.session.auth = None
self._CAS_logout()
return next
- def get_user( self ):
- user=current.session.token
+
+ def get_user(self):
+ user = current.session.token
if user:
- d = {'source':'web2py cas'}
+ d = {'source': 'web2py cas'}
for key in self.maps:
- d[key]=self.maps[key](user)
+ d[key] = self.maps[key](user)
return d
return None
- def _CAS_login( self ):
+
+ def _CAS_login(self):
"""
exposed as CAS.login(request)
returns a token on success, None on failed authentication
"""
import urllib
- self.ticket=current.request.vars.ticket
+ self.ticket = current.request.vars.ticket
if not current.request.vars.ticket:
- redirect( "%s?service=%s"% (self.cas_login_url,
+ redirect("%s?service=%s" % (self.cas_login_url,
self.cas_my_url))
else:
- url="%s?service=%s&ticket=%s" % (self.cas_check_url,
- self.cas_my_url,
- self.ticket )
- data=urllib.urlopen( url ).read()
+ url = "%s?service=%s&ticket=%s" % (self.cas_check_url,
+ self.cas_my_url,
+ self.ticket)
+ data = urllib.urlopen(url).read()
if data.startswith('yes') or data.startswith('no'):
data = data.split('\n')
- if data[0]=='yes':
- if ':' in data[1]: # for Compatibility with Custom CAS
+ if data[0] == 'yes':
+ if ':' in data[1]: # for Compatibility with Custom CAS
items = data[1].split(':')
a = items[0]
- b = len(items)>1 and items[1] or a
- c = len(items)>2 and items[2] or b
+ b = len(items) > 1 and items[1] or a
+ c = len(items) > 2 and items[2] or b
else:
a = b = c = data[1]
- return dict(user=a,email=b,username=c)
+ return dict(user=a, email=b, username=c)
return None
import xml.dom.minidom as dom
import xml.parsers.expat as expat
try:
- dxml=dom.parseString(data)
- envelop = dxml.getElementsByTagName("cas:authenticationSuccess")
- if len(envelop)>0:
+ dxml = dom.parseString(data)
+ envelop = dxml.getElementsByTagName(
+ "cas:authenticationSuccess")
+ if len(envelop) > 0:
res = dict()
for x in envelop[0].childNodes:
if x.nodeName.startswith('cas:') and len(x.childNodes):
key = x.nodeName[4:].encode('utf8')
value = x.childNodes[0].nodeValue.encode('utf8')
if not key in res:
- res[key]=value
+ res[key] = value
else:
- if not isinstance(res[key],list):
- res[key]=[res[key]]
+ if not isinstance(res[key], list):
+ res[key] = [res[key]]
res[key].append(value)
return res
- except expat.ExpatError: pass
- return None # fallback
+ except expat.ExpatError:
+ pass
+ return None # fallback
-
- def _CAS_logout( self ):
+ def _CAS_logout(self):
"""
exposed CAS.logout()
redirects to the CAS logout page
"""
import urllib
- redirect("%s?service=%s" % (self.cas_logout_url,self.cas_my_url))
-
-
+ redirect("%s?service=%s" % (self.cas_logout_url, self.cas_my_url))
diff --git a/gluon/contrib/login_methods/dropbox_account.py b/gluon/contrib/login_methods/dropbox_account.py
index 42877773..8bfc7079 100644
--- a/gluon/contrib/login_methods/dropbox_account.py
+++ b/gluon/contrib/login_methods/dropbox_account.py
@@ -18,11 +18,13 @@ from gluon.tools import fetch
from gluon.storage import Storage
import gluon.contrib.simplejson as json
+
class DropboxAccount(object):
"""
from gluon.contrib.login_methods.dropbox_account import DropboxAccount
- auth.settings.actions_disabled=['register','change_password','request_reset_password']
+ auth.settings.actions_disabled=['register','change_password',
+ 'request_reset_password']
auth.settings.login_form = DropboxAccount(request,
key="...",
secret="...",
@@ -34,47 +36,45 @@ class DropboxAccount(object):
def __init__(self,
request,
- key = "",
- secret = "",
+ key="",
+ secret="",
access_type="app_folder",
- login_url = "",
+ login_url="",
on_login_failure=None,
):
-
- self.request=request
- self.key=key
- self.secret=secret
- self.access_type=access_type
+
+ self.request = request
+ self.key = key
+ self.secret = secret
+ self.access_type = access_type
self.login_url = login_url
self.on_login_failure = on_login_failure
self.sess = session.DropboxSession(
- self.key,self.secret,self.access_type)
-
+ self.key, self.secret, self.access_type)
def get_user(self):
request = self.request
if not current.session.dropbox_request_token:
return None
elif not current.session.dropbox_access_token:
-
- request_token = current.session.dropbox_request_token
- self.sess.set_request_token(request_token[0],request_token[1])
+
+ request_token = current.session.dropbox_request_token
+ self.sess.set_request_token(request_token[0], request_token[1])
access_token = self.sess.obtain_access_token(self.sess.token)
current.session.dropbox_access_token = \
- (access_token.key,access_token.secret)
+ (access_token.key, access_token.secret)
else:
access_token = current.session.dropbox_access_token
- self.sess.set_token(access_token[0],access_token[1])
+ self.sess.set_token(access_token[0], access_token[1])
-
user = Storage()
self.client = client.DropboxClient(self.sess)
data = self.client.account_info()
- display_name = data.get('display_name','').split(' ',1)
- user = dict(email = data.get('email',None),
- first_name = display_name[0],
- last_name = display_name[-1],
- registration_id = data.get('uid',None))
+ display_name = data.get('display_name', '').split(' ', 1)
+ user = dict(email=data.get('email', None),
+ first_name=display_name[0],
+ last_name=display_name[-1],
+ registration_id=data.get('uid', None))
if not user['registration_id'] and self.on_login_failure:
redirect(self.on_login_failure)
return user
@@ -83,7 +83,7 @@ class DropboxAccount(object):
request_token = self.sess.obtain_request_token()
current.session.dropbox_request_token = \
- (request_token.key,request_token.secret)
+ (request_token.key, request_token.secret)
dropbox_url = self.sess.build_authorize_url(request_token,
self.login_url)
redirect(dropbox_url)
@@ -93,29 +93,32 @@ class DropboxAccount(object):
_style="width:400px;height:240px;")
return form
- def logout_url(self, next = "/"):
- current.session.dropbox_request_token=None
- current.session.auth=None
+ def logout_url(self, next="/"):
+ current.session.dropbox_request_token = None
+ current.session.auth = None
redirect('https://www.dropbox.com/logout')
return next
- def put(self,filename,file):
- return json.loads(self.client.put_file(filename,file))['bytes']
- def get(self,filename,file):
+
+ def put(self, filename, file):
+ return json.loads(self.client.put_file(filename, file))['bytes']
+
+ def get(self, filename, file):
return self.client.get_file(filename)
- def dir(self,path):
+
+ def dir(self, path):
return json.loads(self.client.metadata(path))
-def use_dropbox(auth,filename='private/dropbox.key',**kwargs):
- path = os.path.join(current.request.folder,filename)
+
+def use_dropbox(auth, filename='private/dropbox.key', **kwargs):
+ path = os.path.join(current.request.folder, filename)
if os.path.exists(path):
request = current.request
- key,secret,access_type = open(path,'r').read().strip().split(':')
+ key, secret, access_type = open(path, 'r').read().strip().split(':')
host = current.request.env.http_host
login_url = "http://%s/%s/default/user/login" % \
- (host,request.application)
+ (host, request.application)
auth.settings.actions_disabled = \
- ['register','change_password','request_reset_password']
+ ['register', 'change_password', 'request_reset_password']
auth.settings.login_form = DropboxAccount(
- request,key=key,secret=secret,access_type=access_type,
- login_url = login_url,**kwargs)
-
+ request, key=key, secret=secret, access_type=access_type,
+ login_url=login_url, **kwargs)
diff --git a/gluon/contrib/login_methods/email_auth.py b/gluon/contrib/login_methods/email_auth.py
index a53011a2..840fc0c3 100644
--- a/gluon/contrib/login_methods/email_auth.py
+++ b/gluon/contrib/login_methods/email_auth.py
@@ -1,6 +1,7 @@
import smtplib
import logging
+
def email_auth(server="smtp.gmail.com:587",
domain="@gmail.com",
tls_mode=None):
@@ -17,9 +18,9 @@ def email_auth(server="smtp.gmail.com:587",
domain=domain,
tls_mode=tls_mode):
if domain:
- if not isinstance(domain,(list,tuple)):
- domain=[str(domain)]
- if not [d for d in domain if email[-len(d):]==d]:
+ if not isinstance(domain, (list, tuple)):
+ domain = [str(domain)]
+ if not [d for d in domain if email[-len(d):] == d]:
return False
(host, port) = server.split(':')
if tls_mode is None: # then auto detect
@@ -43,4 +44,3 @@ def email_auth(server="smtp.gmail.com:587",
pass
return False
return email_auth_aux
-
diff --git a/gluon/contrib/login_methods/extended_login_form.py b/gluon/contrib/login_methods/extended_login_form.py
index 059d4816..6946531d 100644
--- a/gluon/contrib/login_methods/extended_login_form.py
+++ b/gluon/contrib/login_methods/extended_login_form.py
@@ -8,6 +8,7 @@ So user can choose the built-in login or extended login methods.
from gluon import current, DIV
+
class ExtendedLoginForm(object):
"""
Put extended_login_form under web2py/gluon/contrib/login_methods folder.
@@ -22,7 +23,8 @@ class ExtendedLoginForm(object):
api_key="...",
domain="...",
url = "http://localhost:8000/%s/default/user/login" % request.application)
- extended_login_form = ExtendedLoginForm(auth, alt_login_form, signals=['token'])
+ extended_login_form = ExtendedLoginForm(
+ auth, alt_login_form, signals=['token'])
auth.settings.login_form = extended_login_form
@@ -37,7 +39,7 @@ class ExtendedLoginForm(object):
auth,
alt_login_form,
signals=[],
- login_arg = 'login'
+ login_arg='login'
):
self.auth = auth
self.alt_login_form = alt_login_form
@@ -50,7 +52,7 @@ class ExtendedLoginForm(object):
"""
if hasattr(self.alt_login_form, 'get_user'):
return self.alt_login_form.get_user()
- return None # let gluon.tools.Auth.get_or_create_user do the rest
+ return None # let gluon.tools.Auth.get_or_create_user do the rest
def login_url(self, next):
"""
@@ -91,8 +93,8 @@ class ExtendedLoginForm(object):
args = request.args
if (self.signals and
- any([True for signal in self.signals if request.vars.has_key(signal)])
- ):
+ any([True for signal in self.signals if signal in request.vars])
+ ):
return self.alt_login_form.login_form()
self.auth.settings.login_form = self.auth
@@ -101,5 +103,3 @@ class ExtendedLoginForm(object):
form.components.append(self.alt_login_form.login_form())
return form
-
-
diff --git a/gluon/contrib/login_methods/gae_google_account.py b/gluon/contrib/login_methods/gae_google_account.py
index 9559b42a..49b435b0 100644
--- a/gluon/contrib/login_methods/gae_google_account.py
+++ b/gluon/contrib/login_methods/gae_google_account.py
@@ -11,6 +11,7 @@ Thanks to Hans Donner for GaeGoogleAccount.
from google.appengine.api import users
+
class GaeGoogleAccount(object):
"""
Login will be done via Google's Appengine login object, instead of web2py's
@@ -35,5 +36,3 @@ class GaeGoogleAccount(object):
if user:
return dict(nickname=user.nickname(), email=user.email(),
user_id=user.user_id(), source="google account")
-
-
diff --git a/gluon/contrib/login_methods/ldap_auth.py b/gluon/contrib/login_methods/ldap_auth.py
index 2eb76bcf..a0574318 100644
--- a/gluon/contrib/login_methods/ldap_auth.py
+++ b/gluon/contrib/login_methods/ldap_auth.py
@@ -188,18 +188,23 @@ def ldap_auth(server='ldap', port=None,
str(custom_scope), str(manage_groups)))
if manage_user:
if user_firstname_attrib.count(':') > 0:
- (user_firstname_attrib, user_firstname_part) = user_firstname_attrib.split(':', 1)
+ (user_firstname_attrib,
+ user_firstname_part) = user_firstname_attrib.split(':', 1)
user_firstname_part = (int(user_firstname_part) - 1)
else:
user_firstname_part = None
if user_lastname_attrib.count(':') > 0:
- (user_lastname_attrib, user_lastname_part) = user_lastname_attrib.split(':', 1)
+ (user_lastname_attrib,
+ user_lastname_part) = user_lastname_attrib.split(':', 1)
user_lastname_part = (int(user_lastname_part) - 1)
else:
user_lastname_part = None
- user_firstname_attrib = ldap.filter.escape_filter_chars(user_firstname_attrib)
- user_lastname_attrib = ldap.filter.escape_filter_chars(user_lastname_attrib)
- user_mail_attrib = ldap.filter.escape_filter_chars(user_mail_attrib)
+ user_firstname_attrib = ldap.filter.escape_filter_chars(
+ user_firstname_attrib)
+ user_lastname_attrib = ldap.filter.escape_filter_chars(
+ user_lastname_attrib)
+ user_mail_attrib = ldap.filter.escape_filter_chars(
+ user_mail_attrib)
try:
if allowed_groups:
if not is_user_in_allowed_groups(username, password):
@@ -310,7 +315,8 @@ def ldap_auth(server='ldap', port=None,
basedns = ldap_basedn
else:
basedns = [ldap_basedn]
- filter = '(&(uid=%s)(%s))' % (ldap.filter.escape_filter_chars(username), filterstr)
+ filter = '(&(uid=%s)(%s))' % (
+ ldap.filter.escape_filter_chars(username), filterstr)
found = False
for basedn in basedns:
try:
@@ -338,7 +344,8 @@ def ldap_auth(server='ldap', port=None,
else:
basedns = [ldap_basedn]
filter = '(&(%s=%s)(%s))' % (username_attrib,
- ldap.filter.escape_filter_chars(username),
+ ldap.filter.escape_filter_chars(
+ username),
filterstr)
if custom_scope == 'subtree':
ldap_scope = ldap.SCOPE_SUBTREE
@@ -368,14 +375,16 @@ def ldap_auth(server='ldap', port=None,
logger.info('[%s] Manage user data' % str(username))
try:
if user_firstname_part is not None:
- store_user_firstname = result[user_firstname_attrib][0].split(' ', 1)[user_firstname_part]
+ store_user_firstname = result[user_firstname_attrib][
+ 0].split(' ', 1)[user_firstname_part]
else:
store_user_firstname = result[user_firstname_attrib][0]
except KeyError, e:
store_user_firstname = None
try:
if user_lastname_part is not None:
- store_user_lastname = result[user_lastname_attrib][0].split(' ', 1)[user_lastname_part]
+ store_user_lastname = result[user_lastname_attrib][
+ 0].split(' ', 1)[user_lastname_part]
else:
store_user_lastname = result[user_lastname_attrib][0]
except KeyError, e:
@@ -464,16 +473,19 @@ def ldap_auth(server='ldap', port=None,
#
# Get all group name where the user is in actually in ldap
# #########################################################
- ldap_groups_of_the_user = get_user_groups_from_ldap(username, password)
+ ldap_groups_of_the_user = get_user_groups_from_ldap(
+ username, password)
#
# Get all group name where the user is in actually in local db
# #############################################################
try:
- db_user_id = db(db.auth_user.username == username).select(db.auth_user.id).first().id
+ db_user_id = db(db.auth_user.username == username).select(
+ db.auth_user.id).first().id
except:
try:
- db_user_id = db(db.auth_user.email == username).select(db.auth_user.id).first().id
+ db_user_id = db(db.auth_user.email == username).select(
+ db.auth_user.id).first().id
except AttributeError, e:
#
# There is no user in local db
@@ -486,7 +498,8 @@ def ldap_auth(server='ldap', port=None,
db_user_id = db.auth_user.insert(email=username,
first_name=username)
if not db_user_id:
- logging.error('There is no username or email for %s!' % username)
+ logging.error(
+ 'There is no username or email for %s!' % username)
raise
db_group_search = db((db.auth_membership.user_id == db_user_id) &
(db.auth_user.id == db.auth_membership.user_id) &
@@ -520,7 +533,8 @@ def ldap_auth(server='ldap', port=None,
gid = db.auth_group.insert(role=group_to_add,
description='Generated from LDAP')
else:
- gid = db(db.auth_group.role == group_to_add).select(db.auth_group.id).first().id
+ gid = db(db.auth_group.role == group_to_add).select(
+ db.auth_group.id).first().id
db.auth_membership.insert(user_id=db_user_id,
group_id=gid)
except:
@@ -634,4 +648,3 @@ def ldap_auth(server='ldap', port=None,
if filterstr[0] == '(' and filterstr[-1] == ')': # rfc4515 syntax
filterstr = filterstr[1:-1] # parens added again where used
return ldap_auth_aux
-
diff --git a/gluon/contrib/login_methods/linkedin_account.py b/gluon/contrib/login_methods/linkedin_account.py
index f16deadd..4376a628 100644
--- a/gluon/contrib/login_methods/linkedin_account.py
+++ b/gluon/contrib/login_methods/linkedin_account.py
@@ -14,7 +14,8 @@ from gluon.http import HTTP
try:
import linkedin
except ImportError:
- raise HTTP(400,"linkedin module not found")
+ raise HTTP(400, "linkedin module not found")
+
class LinkedInAccount(object):
"""
@@ -28,9 +29,9 @@ class LinkedInAccount(object):
"""
- def __init__(self,request,key,secret,return_url):
+ def __init__(self, request, key, secret, return_url):
self.request = request
- self.api = linkedin.LinkedIn(key,secret,return_url)
+ self.api = linkedin.LinkedIn(key, secret, return_url)
self.token = result = self.api.requestToken()
def login_url(self, next="/"):
@@ -40,13 +41,12 @@ class LinkedInAccount(object):
return ''
def get_user(self):
- result = self.request.vars.verifier and self.api.accessToken(verifier = self.request.vars.verifier )
+ result = self.request.vars.verifier and self.api.accessToken(
+ verifier=self.request.vars.verifier)
if result:
profile = self.api.GetProfile()
- profile = self.api.GetProfile(profile).public_url = "http://www.linkedin.com/in/ozgurv"
- return dict(first_name = profile.first_name,
- last_name = profile.last_name,
- username = profile.id)
-
-
-
+ profile = self.api.GetProfile(
+ profile).public_url = "http://www.linkedin.com/in/ozgurv"
+ return dict(first_name=profile.first_name,
+ last_name=profile.last_name,
+ username=profile.id)
diff --git a/gluon/contrib/login_methods/loginza.py b/gluon/contrib/login_methods/loginza.py
index a54e3ca9..9c688f77 100644
--- a/gluon/contrib/login_methods/loginza.py
+++ b/gluon/contrib/login_methods/loginza.py
@@ -13,6 +13,7 @@ from gluon.tools import fetch
from gluon.storage import Storage
import gluon.contrib.simplejson as json
+
class Loginza(object):
"""
@@ -23,13 +24,13 @@ class Loginza(object):
def __init__(self,
request,
- url = "",
- embed = True,
- auth_url = "http://loginza.ru/api/authinfo",
- language = "en",
- prompt = "loginza",
- on_login_failure = None,
- ):
+ url="",
+ embed=True,
+ auth_url="http://loginza.ru/api/authinfo",
+ language="en",
+ prompt="loginza",
+ on_login_failure=None,
+ ):
self.request = request
self.token_url = url
@@ -46,49 +47,50 @@ class Loginza(object):
# FIXME: what if email is unique=True
self.mappings["http://twitter.com/"] = lambda profile:\
- dict(registration_id = profile.get("identity",""),
- username = profile.get("nickname",""),
- email = profile.get("email",""),
- last_name = profile.get("name","").get("full_name",""),
+ dict(registration_id=profile.get("identity", ""),
+ username=profile.get("nickname", ""),
+ email=profile.get("email", ""),
+ last_name=profile.get("name", "").get("full_name", ""),
#avatar = profile.get("photo",""),
- )
+ )
self.mappings["https://www.google.com/accounts/o8/ud"] = lambda profile:\
- dict(registration_id = profile.get("identity",""),
- username = profile.get("name","").get("full_name",""),
- email = profile.get("email",""),
- first_name = profile.get("name","").get("first_name",""),
- last_name = profile.get("name","").get("last_name",""),
+ dict(registration_id=profile.get("identity", ""),
+ username=profile.get("name", "").get("full_name", ""),
+ email=profile.get("email", ""),
+ first_name=profile.get("name", "").get("first_name", ""),
+ last_name=profile.get("name", "").get("last_name", ""),
#avatar = profile.get("photo",""),
- )
+ )
self.mappings["http://vkontakte.ru/"] = lambda profile:\
- dict(registration_id=profile.get("identity",""),
- username = profile.get("name","").get("full_name",""),
- email = profile.get("email",""),
- first_name = profile.get("name","").get("first_name",""),
- last_name = profile.get("name","").get("last_name",""),
+ dict(registration_id=profile.get("identity", ""),
+ username=profile.get("name", "").get("full_name", ""),
+ email=profile.get("email", ""),
+ first_name=profile.get("name", "").get("first_name", ""),
+ last_name=profile.get("name", "").get("last_name", ""),
#avatar = profile.get("photo",""),
- )
+ )
self.mappings.default = lambda profile:\
- dict(registration_id = profile.get("identity",""),
- username = profile.get("name","").get("full_name"),
- email = profile.get("email",""),
- first_name = profile.get("name","").get("first_name",""),
- last_name = profile.get("name","").get("last_name",""),
+ dict(registration_id=profile.get("identity", ""),
+ username=profile.get("name", "").get("full_name"),
+ email=profile.get("email", ""),
+ first_name=profile.get("name", "").get("first_name", ""),
+ last_name=profile.get("name", "").get("last_name", ""),
#avatar = profile.get("photo",""),
- )
+ )
def get_user(self):
request = self.request
if request.vars.token:
user = Storage()
- data = urllib.urlencode(dict(token = request.vars.token))
- auth_info_json = fetch(self.auth_url+'?'+data)
+ data = urllib.urlencode(dict(token=request.vars.token))
+ auth_info_json = fetch(self.auth_url + '?' + data)
#print auth_info_json
auth_info = json.loads(auth_info_json)
- if auth_info["identity"] != None:
+ if auth_info["identity"] is not None:
self.profile = auth_info
provider = self.profile["provider"]
- user = self.mappings.get(provider, self.mappings.default)(self.profile)
+ user = self.mappings.get(
+ provider, self.mappings.default)(self.profile)
#user["password"] = ???
#user["avatar"] = ???
return user
@@ -106,8 +108,8 @@ class Loginza(object):
_frameborder="no",
_style="width:359px;height:300px;")
else:
- form = DIV(A(self.prompt, _href=LOGINZA_URL % (self.language, self.token_url), _class="loginza"),
- SCRIPT(_src="https://s3-eu-west-1.amazonaws.com/s1.loginza.ru/js/widget.js", _type="text/javascript"))
+ form = DIV(
+ A(self.prompt, _href=LOGINZA_URL % (
+ self.language, self.token_url), _class="loginza"),
+ SCRIPT(_src="https://s3-eu-west-1.amazonaws.com/s1.loginza.ru/js/widget.js", _type="text/javascript"))
return form
-
-
diff --git a/gluon/contrib/login_methods/motp_auth.py b/gluon/contrib/login_methods/motp_auth.py
index 8d2bfa70..aad9d27b 100644
--- a/gluon/contrib/login_methods/motp_auth.py
+++ b/gluon/contrib/login_methods/motp_auth.py
@@ -4,6 +4,7 @@ import time
from hashlib import md5
from gluon.dal import DAL
+
def motp_auth(db=DAL('sqlite://storage.sqlite'),
time_offset=60):
@@ -44,7 +45,8 @@ def motp_auth(db=DAL('sqlite://storage.sqlite'),
writable=False, readable=False, default=''))
##validators
- custom_auth_table = db[auth.settings.table_user_name] # get the custom_auth_table
+ custom_auth_table = db[auth.settings.table_user_name]
+ # get the custom_auth_table
custom_auth_table.first_name.requires = \
IS_NOT_EMPTY(error_message=auth.messages.is_empty)
custom_auth_table.last_name.requires = \
@@ -76,14 +78,15 @@ def motp_auth(db=DAL('sqlite://storage.sqlite'),
- as of now user field is hardcoded to email. Some way of selecting user table and user field.
"""
- def verify_otp(otp,pin,secret,offset=60):
+ def verify_otp(otp, pin, secret, offset=60):
epoch_time = int(time.time())
time_start = int(str(epoch_time - offset)[:-1])
time_end = int(str(epoch_time + offset)[:-1])
- for t in range(time_start-1,time_end+1):
- to_hash = str(t)+secret+pin
+ for t in range(time_start - 1, time_end + 1):
+ to_hash = str(t) + secret + pin
hash = md5(to_hash).hexdigest()[:6]
- if otp == hash: return True
+ if otp == hash:
+ return True
return False
def motp_auth_aux(email,
@@ -91,15 +94,18 @@ def motp_auth(db=DAL('sqlite://storage.sqlite'),
db=db,
offset=time_offset):
if db:
- user_data = db(db.auth_user.email == email ).select().first()
+ user_data = db(db.auth_user.email == email).select().first()
if user_data:
if user_data['motp_secret'] and user_data['motp_pin']:
motp_secret = user_data['motp_secret']
motp_pin = user_data['motp_pin']
- otp_check = verify_otp(password,motp_pin,motp_secret,offset=offset)
- if otp_check: return True
- else: return False
- else: return False
+ otp_check = verify_otp(
+ password, motp_pin, motp_secret, offset=offset)
+ if otp_check:
+ return True
+ else:
+ return False
+ else:
+ return False
return False
return motp_auth_aux
-
diff --git a/gluon/contrib/login_methods/oauth10a_account.py b/gluon/contrib/login_methods/oauth10a_account.py
index 534a7582..1f464f8c 100644
--- a/gluon/contrib/login_methods/oauth10a_account.py
+++ b/gluon/contrib/login_methods/oauth10a_account.py
@@ -19,6 +19,7 @@ from urllib2 import urlopen
import urllib2
from urllib import urlencode
+
class OAuthAccount(object):
"""
Login will be done via OAuth Framework, instead of web2py's
@@ -51,7 +52,8 @@ class OAuthAccount(object):
TOKEN_URL="..."
ACCESS_TOKEN_URL="..."
from gluon.contrib.login_methods.oauth10a_account import OAuthAccount
- auth.settings.login_form=OAuthAccount(globals(),CLIENT_ID,CLIENT_SECRET, AUTH_URL, TOKEN_URL, ACCESS_TOKEN_URL)
+ auth.settings.login_form=OAuthAccount(globals(
+ ),CLIENT_ID,CLIENT_SECRET, AUTH_URL, TOKEN_URL, ACCESS_TOKEN_URL)
"""
@@ -61,20 +63,20 @@ class OAuthAccount(object):
Appends the _next action to the generated url so the flows continues.
"""
r = self.request
- http_host=r.env.http_x_forwarded_for
- if not http_host: http_host=r.env.http_host
+ http_host = r.env.http_x_forwarded_for
+ if not http_host:
+ http_host = r.env.http_host
url_scheme = r.env.wsgi_url_scheme
if next:
path_info = next
else:
path_info = r.env.path_info
- uri = '%s://%s%s' %(url_scheme, http_host, path_info)
+ uri = '%s://%s%s' % (url_scheme, http_host, path_info)
if r.get_vars and not next:
uri += '?' + urlencode(r.get_vars)
return uri
-
def accessToken(self):
"""Return the access token generated by the authenticating server.
@@ -97,12 +99,11 @@ class OAuthAccount(object):
token.set_verifier(self.request.vars.oauth_verifier)
client = oauth.Client(self.consumer, token)
-
resp, content = client.request(self.access_token_url, "POST")
if str(resp['status']) != '200':
self.session.request_token = None
- self.globals['redirect'](self.globals['URL'](f='user',args='logout'))
-
+ self.globals['redirect'](self.globals[
+ 'URL'](f='user', args='logout'))
self.session.access_token = oauth.Token.from_string(content)
@@ -111,7 +112,7 @@ class OAuthAccount(object):
self.session.access_token = None
return None
- def __init__(self, g, client_id, client_secret, auth_url, token_url, access_token_url):
+ def __init__(self, g, client_id, client_secret, auth_url, token_url, access_token_url):
self.globals = g
self.client_id = client_id
self.client_secret = client_secret
@@ -125,7 +126,6 @@ class OAuthAccount(object):
# consumer init
self.consumer = oauth.Consumer(self.client_id, self.client_secret)
-
def login_url(self, next="/"):
self.__oauth_login(next)
return next
@@ -142,7 +142,7 @@ class OAuthAccount(object):
is, this function must be implemented for the specific
provider.
'''
- raise NotImplementedError, "Must override get_user()"
+ raise NotImplementedError("Must override get_user()")
def __oauth_login(self, next):
'''This method redirects the user to the authenticating form
@@ -163,10 +163,11 @@ class OAuthAccount(object):
# putting it in the body seems to work.
callback_url = self.__redirect_uri(next)
data = urlencode(dict(oauth_callback=callback_url))
- resp, content = client.request(self.token_url, "POST", body=data)
+ resp, content = client.request(self.token_url, "POST", body=data)
if resp['status'] != '200':
self.session.request_token = None
- self.globals['redirect'](self.globals['URL'](f='user',args='logout'))
+ self.globals['redirect'](self.globals[
+ 'URL'](f='user', args='logout'))
# Store the request token in session.
request_token = self.session.request_token = oauth.Token.from_string(content)
@@ -174,18 +175,12 @@ class OAuthAccount(object):
# Redirect the user to the authentication URL and pass the callback url.
data = urlencode(dict(oauth_token=request_token.key,
oauth_callback=callback_url))
- auth_request_url = self.auth_url + '?' +data
-
+ auth_request_url = self.auth_url + '?' + data
HTTP = self.globals['HTTP']
-
raise HTTP(307,
"You are not authenticated: you are being redirected to the authentication server",
Location=auth_request_url)
return None
-
-
-
-
diff --git a/gluon/contrib/login_methods/oauth20_account.py b/gluon/contrib/login_methods/oauth20_account.py
index e3d38321..0ed3adb2 100644
--- a/gluon/contrib/login_methods/oauth20_account.py
+++ b/gluon/contrib/login_methods/oauth20_account.py
@@ -17,6 +17,7 @@ import urllib2
from urllib import urlencode
from gluon import current, redirect, HTTP
+
class OAuthAccount(object):
"""
Login will be done via OAuth Framework, instead of web2py's
@@ -84,7 +85,8 @@ class OAuthAccount(object):
username = user['id'])
- auth.settings.actions_disabled=['register','change_password','request_reset_password','profile']
+ auth.settings.actions_disabled=['register',
+ 'change_password','request_reset_password','profile']
auth.settings.login_form=FaceBookAccount()
Any optional arg in the constructor will be passed asis to remote
@@ -99,8 +101,9 @@ server for requests. It can be used for the optional"scope" parameters for Face
"""
r = current.request
- http_host=r.env.http_x_forwarded_for
- if not http_host: http_host=r.env.http_host
+ http_host = r.env.http_x_forwarded_for
+ if not http_host:
+ http_host = r.env.http_host
url_scheme = r.env.wsgi_url_scheme
if next:
@@ -112,7 +115,6 @@ server for requests. It can be used for the optional"scope" parameters for Face
uri += '?' + urlencode(r.get_vars)
return uri
-
def __build_url_opener(self, uri):
"""
Build the url opener for managing HTTP Basic Athentication
@@ -128,7 +130,6 @@ server for requests. It can be used for the optional"scope" parameters for Face
opener = urllib2.build_opener(auth_handler)
return opener
-
def accessToken(self):
"""
Return the access token generated by the authenticating server.
@@ -137,7 +138,7 @@ server for requests. It can be used for the optional"scope" parameters for Face
Otherwise the token is fetched from the auth server.
"""
- if current.session.token and current.session.token.has_key('expires'):
+ if current.session.token and 'expires' in current.session.token:
expires = current.session.token['expires']
# reuse token until expiration
if expires == 0 or expires > time.time():
@@ -159,19 +160,19 @@ server for requests. It can be used for the optional"scope" parameters for Face
print tmp
raise Exception(tmp)
finally:
- del current.session.code # throw it away
+ del current.session.code # throw it away
if open_url:
try:
data = open_url.read()
tokendata = cgi.parse_qs(data)
current.session.token = \
- dict([(k,v[-1]) for k,v in tokendata.items()])
+ dict([(k, v[-1]) for k, v in tokendata.items()])
# set expiration absolute time try to avoid broken
# implementations where "expires_in" becomes "expires"
- if current.session.token.has_key('expires_in'):
+ if 'expires_in' in current.session.token:
exps = 'expires_in'
- elif current.session.token.has_key('expires'):
+ elif 'expires' in current.session.token:
exps = 'expires'
else:
exps = None
@@ -217,11 +218,12 @@ server for requests. It can be used for the optional"scope" parameters for Face
Override this method by sublcassing the class.
"""
- if not current.session.token: return None
- return dict(first_name = 'Pinco',
- last_name = 'Pallino',
- username = 'pincopallino')
- raise NotImplementedError, "Must override get_user()"
+ if not current.session.token:
+ return None
+ return dict(first_name='Pinco',
+ last_name='Pallino',
+ username='pincopallino')
+ raise NotImplementedError("Must override get_user()")
# Following code is never executed. It can be used as example
# for overriding in subclasses.
@@ -239,10 +241,9 @@ server for requests. It can be used for the optional"scope" parameters for Face
self.graph = None
if user:
- return dict(first_name = user['first_name'],
- last_name = user['last_name'],
- username = user['id'])
-
+ return dict(first_name=user['first_name'],
+ last_name=user['last_name'],
+ username=user['id'])
def __oauth_login(self, next):
"""
@@ -258,13 +259,13 @@ server for requests. It can be used for the optional"scope" parameters for Face
if not self.accessToken():
if not current.request.vars.code:
- current.session.redirect_uri=self.__redirect_uri(next)
+ current.session.redirect_uri = self.__redirect_uri(next)
data = dict(redirect_uri=current.session.redirect_uri,
- response_type='code',
- client_id=self.client_id)
+ response_type='code',
+ client_id=self.client_id)
if self.args:
data.update(self.args)
- auth_request_url = self.auth_url + "?" +urlencode(data)
+ auth_request_url = self.auth_url + "?" + urlencode(data)
raise HTTP(307,
"You are not authenticated: you are being redirected to the authentication server",
Location=auth_request_url)
@@ -273,5 +274,3 @@ server for requests. It can be used for the optional"scope" parameters for Face
self.accessToken()
return current.session.code
return None
-
-
diff --git a/gluon/contrib/login_methods/openid_auth.py b/gluon/contrib/login_methods/openid_auth.py
index a2c22633..4e977030 100644
--- a/gluon/contrib/login_methods/openid_auth.py
+++ b/gluon/contrib/login_methods/openid_auth.py
@@ -49,6 +49,7 @@ except ImportError, err:
DEFAULT = lambda: None
+
class OpenIDAuth(object):
"""
OpenIDAuth
@@ -94,7 +95,7 @@ class OpenIDAuth(object):
if not auth.settings.table_user:
raise
self.table_user = self.auth.settings.table_user
- self.openid_expiration = 15 #minutes
+ self.openid_expiration = 15 # minutes
self.messages = self._define_messages()
@@ -116,7 +117,7 @@ class OpenIDAuth(object):
messages.flash_openid_associated = 'OpenID associated'
messages.flash_associate_openid = 'Please login or register an account for this OpenID.'
messages.p_openid_not_registered = "This Open ID haven't be registered. " \
- + "Please login to associate with it or register an account for it."
+ + "Please login to associate with it or register an account for it."
messages.flash_openid_authenticated = 'OpenID authenticated successfully.'
messages.flash_openid_fail_authentication = 'OpenID authentication failed. (Error message: %s)'
messages.flash_openid_canceled = 'OpenID authentication canceled by user.'
@@ -158,7 +159,7 @@ class OpenIDAuth(object):
and not processed yet. Else return the OpenID form for login.
"""
request = current.request
- if request.vars.has_key('janrain_nonce') and not self._processed():
+ if 'janrain_nonce' in request.vars and not self._processed():
self._process_response()
return self.auth()
return self._form()
@@ -172,12 +173,12 @@ class OpenIDAuth(object):
args = request.args
if args[0] == 'logout':
- return True # Let logout_url got called
+ return True # Let logout_url got called
if current.session.w2popenid:
w2popenid = current.session.w2popenid
db = self.db
- if (w2popenid.ok is True and w2popenid.oid): # OpenID authenticated
+ if (w2popenid.ok is True and w2popenid.oid): # OpenID authenticated
if self._w2popenid_expired(w2popenid):
del(current.session.w2popenid)
flash = self.messages.flash_openid_expired
@@ -196,22 +197,23 @@ class OpenIDAuth(object):
if current.session.w2popenid:
del(current.session.w2popenid)
current.session.flash = self.messages.flash_openid_associated
- if request.vars.has_key(nextvar):
+ if nextvar in request.vars:
redirect(request.vars[nextvar])
redirect(self.auth.settings.login_next)
- if not request.vars.has_key(nextvar):
+ if nextvar not in request.vars:
# no next var, add it and do login again
# so if user login or register can go back here to associate the OpenID
redirect(URL(r=request,
- args=['login'],
- vars={nextvar:self.login_url}))
+ args=['login'],
+ vars={nextvar: self.login_url}))
self.login_form = self._form_with_notification()
current.session.flash = self.messages.flash_associate_openid
- return None # need to login or register to associate this openid
+ return None # need to login or register to associate this openid
# Get existed OpenID user
- user = db(self.table_user.id==alt_login.user).select().first()
+ user = db(
+ self.table_user.id == alt_login.user).select().first()
if user:
if current.session.w2popenid:
del(current.session.w2popenid)
@@ -219,16 +221,17 @@ class OpenIDAuth(object):
username = 'username'
elif 'email' in self.table_user.fields():
username = 'email'
- return {username: user[username]} if user else None # login success (almost)
+ return {username: user[username]} if user else None # login success (almost)
- return None # just start to login
+ return None # just start to login
def _find_matched_openid(self, db, oid, type_='openid'):
"""
Get the matched OpenID for given
"""
- query = ((db.alt_logins.username == oid) & (db.alt_logins.type == type_))
- alt_login = db(query).select().first() # Get the OpenID record
+ query = (
+ (db.alt_logins.username == oid) & (db.alt_logins.type == type_))
+ alt_login = db(query).select().first() # Get the OpenID record
return alt_login
def _associate_user_openid(self, user, oid):
@@ -275,7 +278,6 @@ class OpenIDAuth(object):
self.db)
return self.consumerhelper
-
def _form(self, style=None):
form = DIV(H3(self.messages.h_openid_login), self._login_form(style))
return form
@@ -300,7 +302,7 @@ background-color: transparent;
padding-left: 18px;
width: 400px;
"""
- style = style.replace("\n","")
+ style = style.replace("\n", "")
request = current.request
session = current.session
@@ -308,21 +310,25 @@ width: 400px;
hidden_next_input = ""
if _next == 'profile':
profile_url = URL(r=request, f='user', args=['profile'])
- hidden_next_input = INPUT(_type="hidden", _name="_next", _value=profile_url)
- form = FORM(openid_field_label or self.messages.label_alt_login_username,
- INPUT(_type="input", _name="oid",
- requires=IS_NOT_EMPTY(error_message=messages.openid_fail_discover),
- _style=style),
- hidden_next_input,
- INPUT(_type="submit", _value=submit_button or messages.submit_button),
- " ",
- A(messages.comment_openid_signin,
- _href=messages.comment_openid_help_url,
- _title=messages.comment_openid_help_title,
- _class='openid-identifier',
- _target="_blank"),
- _action=self.login_url
- )
+ hidden_next_input = INPUT(
+ _type="hidden", _name="_next", _value=profile_url)
+ form = FORM(
+ openid_field_label or self.messages.label_alt_login_username,
+ INPUT(_type="input", _name="oid",
+ requires=IS_NOT_EMPTY(
+ error_message=messages.openid_fail_discover),
+ _style=style),
+ hidden_next_input,
+ INPUT(_type="submit",
+ _value=submit_button or messages.submit_button),
+ " ",
+ A(messages.comment_openid_signin,
+ _href=messages.comment_openid_help_url,
+ _title=messages.comment_openid_help_title,
+ _class='openid-identifier',
+ _target="_blank"),
+ _action=self.login_url
+ )
if form.accepts(request.vars, session):
oid = request.vars.oid
consumerhelper = self._init_consumerhelper()
@@ -332,8 +338,9 @@ width: 400px;
warning_openid_fail(session)
redirect(url)
try:
- if request.vars.has_key('_next'):
- return_to_url = self.return_to_url + '?_next=' + request.vars._next
+ if '_next' in request.vars:
+ return_to_url = self.return_to_url + \
+ '?_next=' + request.vars._next
url = consumerhelper.begin(oid, self.realm, return_to_url)
except DiscoveryFailure:
warning_openid_fail(session)
@@ -353,7 +360,8 @@ width: 400px;
"""
Set expiration for OpenID authentication.
"""
- w2popenid.expiration = datetime.now() + timedelta(minutes=self.openid_expiration)
+ w2popenid.expiration = datetime.now(
+ ) + timedelta(minutes=self.openid_expiration)
def _w2popenid_expired(self, w2popenid):
"""
@@ -369,7 +377,8 @@ width: 400px;
request = current.request
request_vars = request.vars
consumerhelper = self._init_consumerhelper()
- process_status = consumerhelper.process_response(request_vars, self.return_to_url)
+ process_status = consumerhelper.process_response(
+ request_vars, self.return_to_url)
if process_status == "success":
w2popenid = current.session.w2popenid
user_data = self.consumerhelper.sreg()
@@ -388,7 +397,7 @@ width: 400px;
def list_user_openids(self):
messages = self.messages
request = current.request
- if request.vars.has_key('delete_openid'):
+ if 'delete_openid' in request.vars:
self.remove_openid(request.vars.delete_openid)
query = self.db.alt_logins.user == self.auth.user.id
@@ -397,8 +406,8 @@ width: 400px;
for alt_login in alt_logins:
username = alt_login.username
delete_href = URL(r=request, f='user',
- args=['profile'],
- vars={'delete_openid': username})
+ args=['profile'],
+ vars={'delete_openid': username})
delete_link = A(messages.a_delete, _href=delete_href)
l.append(LI(username, " ", delete_link))
@@ -409,23 +418,23 @@ width: 400px;
_next='profile',
submit_button=messages.submit_button_add,
openid_field_label=messages.label_add_alt_login_username)
- )
+ )
return openid_list
-
def remove_openid(self, openid):
query = self.db.alt_logins.username == openid
self.db(query).delete()
+
class ConsumerHelper(object):
"""
ConsumerHelper knows the python-openid and
"""
def __init__(self, session, db):
- self.session = session
- store = self._init_store(db)
- self.consumer = openid.consumer.consumer.Consumer(session, store)
+ self.session = session
+ store = self._init_store(db)
+ self.consumer = openid.consumer.consumer.Consumer(session, store)
def _init_store(self, db):
"""
@@ -434,7 +443,7 @@ class ConsumerHelper(object):
if not hasattr(self, "store"):
store = Web2pyStore(db)
session = self.session
- if not session.has_key('w2popenid'):
+ if 'w2popenid' not in session:
session.w2popenid = Storage()
self.store = store
return self.store
@@ -446,7 +455,7 @@ class ConsumerHelper(object):
w2popenid = self.session.w2popenid
w2popenid.oid = oid
auth_req = self.consumer.begin(oid)
- auth_req.addExtension(SRegRequest(required=['email','nickname']))
+ auth_req.addExtension(SRegRequest(required=['email', 'nickname']))
url = auth_req.redirectURL(return_to=return_to_url, realm=realm)
return url
@@ -504,19 +513,27 @@ class Web2pyStore(OpenIDStore):
if self.table_oid_associations_name not in self.database:
self.database.define_table(self.table_oid_associations_name,
- Field('server_url', 'string', length=2047, required=True),
- Field('handle', 'string', length=255, required=True),
- Field('secret', 'blob', required=True),
- Field('issued', 'integer', required=True),
- Field('lifetime', 'integer', required=True),
- Field('assoc_type', 'string', length=64, required=True)
- )
+ Field('server_url',
+ 'string', length=2047, required=True),
+ Field('handle',
+ 'string', length=255, required=True),
+ Field('secret', 'blob', required=True),
+ Field('issued',
+ 'integer', required=True),
+ Field('lifetime',
+ 'integer', required=True),
+ Field('assoc_type',
+ 'string', length=64, required=True)
+ )
if self.table_oid_nonces_name not in self.database:
self.database.define_table(self.table_oid_nonces_name,
- Field('server_url', 'string', length=2047, required=True),
- Field('timestamp', 'integer', required=True),
- Field('salt', 'string', length=40, required=True)
- )
+ Field('server_url',
+ 'string', length=2047, required=True),
+ Field('timestamp',
+ 'integer', required=True),
+ Field('salt', 'string',
+ length=40, required=True)
+ )
def storeAssociation(self, server_url, association):
"""
@@ -525,14 +542,15 @@ class Web2pyStore(OpenIDStore):
"""
db = self.database
- query = (db.oid_associations.server_url == server_url) & (db.oid_associations.handle == association.handle)
+ query = (db.oid_associations.server_url == server_url) & (
+ db.oid_associations.handle == association.handle)
db(query).delete()
- db.oid_associations.insert(server_url = server_url,
- handle = association.handle,
- secret = association.secret,
- issued = association.issued,
- lifetime = association.lifetime,
- assoc_type = association.assoc_type), 'insert '*10
+ db.oid_associations.insert(server_url=server_url,
+ handle=association.handle,
+ secret=association.secret,
+ issued=association.issued,
+ lifetime=association.lifetime,
+ assoc_type=association.assoc_type), 'insert ' * 10
def getAssociation(self, server_url, handle=None):
"""
@@ -550,7 +568,8 @@ class Web2pyStore(OpenIDStore):
if len(keep_assoc) == 0:
return None
else:
- assoc = keep_assoc.pop() # pop the last one as it should be the latest one
+ assoc = keep_assoc.pop(
+ ) # pop the last one as it should be the latest one
return Association(assoc['handle'],
assoc['secret'],
assoc['issued'],
@@ -559,8 +578,9 @@ class Web2pyStore(OpenIDStore):
def removeAssociation(self, server_url, handle):
db = self.database
- query = (db.oid_associations.server_url == server_url) & (db.oid_associations.handle == handle)
- return db(query).delete() != None
+ query = (db.oid_associations.server_url == server_url) & (
+ db.oid_associations.handle == handle)
+ return db(query).delete() is not None
def useNonce(self, server_url, timestamp, salt):
"""
@@ -575,10 +595,10 @@ class Web2pyStore(OpenIDStore):
if db(query).count() > 0:
return False
else:
- db.oid_nonces.insert(server_url = server_url,
- timestamp = timestamp,
- salt = salt)
- return True
+ db.oid_nonces.insert(server_url=server_url,
+ timestamp=timestamp,
+ salt=salt)
+ return True
def _removeExpiredAssocations(self, rows):
"""
@@ -599,7 +619,7 @@ class Web2pyStore(OpenIDStore):
keep_assoc.append(r)
for r in remove_assoc:
del db.oid_associations[r['id']]
- return (keep_assoc, len(remove_assoc)) # return tuple (list of valid associations, number of deleted associations)
+ return (keep_assoc, len(remove_assoc)) # return tuple (list of valid associations, number of deleted associations)
def cleanupNonces(self):
"""
@@ -619,7 +639,7 @@ class Web2pyStore(OpenIDStore):
db = self.database
query = (db.oid_associations.id > 0)
- return self._removeExpiredAssocations(db(query).select())[1] #return number of assoc removed
+ return self._removeExpiredAssocations(db(query).select())[1] # return number of assoc removed
def cleanup(self):
"""
@@ -628,6 +648,3 @@ class Web2pyStore(OpenIDStore):
"""
return self.cleanupNonces(), self.cleanupAssociations()
-
-
-
diff --git a/gluon/contrib/login_methods/pam_auth.py b/gluon/contrib/login_methods/pam_auth.py
index 31c343e0..03564bf2 100644
--- a/gluon/contrib/login_methods/pam_auth.py
+++ b/gluon/contrib/login_methods/pam_auth.py
@@ -1,5 +1,6 @@
from gluon.contrib.pam import authenticate
+
def pam_auth():
"""
to use pam_login:
@@ -19,5 +20,3 @@ def pam_auth():
return authenticate(username, password)
return pam_auth_aux
-
-
diff --git a/gluon/contrib/login_methods/rpx_account.py b/gluon/contrib/login_methods/rpx_account.py
index 34688a69..0cd1c56a 100644
--- a/gluon/contrib/login_methods/rpx_account.py
+++ b/gluon/contrib/login_methods/rpx_account.py
@@ -19,11 +19,13 @@ from gluon.tools import fetch
from gluon.storage import Storage
import gluon.contrib.simplejson as json
+
class RPXAccount(object):
"""
from gluon.contrib.login_methods.rpx_account import RPXAccount
- auth.settings.actions_disabled=['register','change_password','request_reset_password']
+ auth.settings.actions_disabled=['register','change_password',
+ 'request_reset_password']
auth.settings.login_form = RPXAccount(request,
api_key="...",
domain="...",
@@ -32,18 +34,18 @@ class RPXAccount(object):
def __init__(self,
request,
- api_key = "",
- domain = "",
- url = "",
- embed = True,
- auth_url = "https://rpxnow.com/api/v2/auth_info",
- language= "en",
+ api_key="",
+ domain="",
+ url="",
+ embed=True,
+ auth_url="https://rpxnow.com/api/v2/auth_info",
+ language="en",
prompt='rpx',
- on_login_failure = None,
+ on_login_failure=None,
):
- self.request=request
- self.api_key=api_key
+ self.request = request
+ self.api_key = api_key
self.embed = embed
self.auth_url = auth_url
self.domain = domain
@@ -54,38 +56,40 @@ class RPXAccount(object):
self.on_login_failure = on_login_failure
self.mappings = Storage()
- dn = {'givenName':'','familyName':''}
+ dn = {'givenName': '', 'familyName': ''}
self.mappings.Facebook = lambda profile, dn=dn:\
- dict(registration_id = profile.get("identifier",""),
- username = profile.get("preferredUsername",""),
- email = profile.get("email",""),
- first_name = profile.get("name",dn).get("givenName",""),
- last_name = profile.get("name",dn).get("familyName",""))
+ dict(registration_id=profile.get("identifier", ""),
+ username=profile.get("preferredUsername", ""),
+ email=profile.get("email", ""),
+ first_name=profile.get("name", dn).get("givenName", ""),
+ last_name=profile.get("name", dn).get("familyName", ""))
self.mappings.Google = lambda profile, dn=dn:\
- dict(registration_id=profile.get("identifier",""),
- username=profile.get("preferredUsername",""),
- email=profile.get("email",""),
- first_name=profile.get("name",dn).get("givenName",""),
- last_name=profile.get("name",dn).get("familyName",""))
+ dict(registration_id=profile.get("identifier", ""),
+ username=profile.get("preferredUsername", ""),
+ email=profile.get("email", ""),
+ first_name=profile.get("name", dn).get("givenName", ""),
+ last_name=profile.get("name", dn).get("familyName", ""))
self.mappings.default = lambda profile:\
- dict(registration_id=profile.get("identifier",""),
- username=profile.get("preferredUsername",""),
- email=profile.get("email",""),
- first_name=profile.get("preferredUsername",""),
+ dict(registration_id=profile.get("identifier", ""),
+ username=profile.get("preferredUsername", ""),
+ email=profile.get("email", ""),
+ first_name=profile.get("preferredUsername", ""),
last_name='')
def get_user(self):
request = self.request
if request.vars.token:
user = Storage()
- data = urllib.urlencode(dict(apiKey = self.api_key, token=request.vars.token))
- auth_info_json = fetch(self.auth_url+'?'+data)
+ data = urllib.urlencode(
+ dict(apiKey=self.api_key, token=request.vars.token))
+ auth_info_json = fetch(self.auth_url + '?' + data)
auth_info = json.loads(auth_info_json)
if auth_info['stat'] == 'ok':
self.profile = auth_info['profile']
- provider = re.sub('[^\w\-]','',self.profile['providerName'])
- user = self.mappings.get(provider,self.mappings.default)(self.profile)
+ provider = re.sub('[^\w\-]', '', self.profile['providerName'])
+ user = self.mappings.get(
+ provider, self.mappings.default)(self.profile)
return user
elif self.on_login_failure:
redirect(self.on_login_failure)
@@ -95,12 +99,14 @@ class RPXAccount(object):
request = self.request
args = request.args
if self.embed:
- JANRAIN_URL = \
- "https://%s.rpxnow.com/openid/embed?token_url=%s&language_preference=%s"
- rpxform = IFRAME(_src=JANRAIN_URL % (self.domain,self.token_url,self.language),
- _scrolling="no",
- _frameborder="no",
- _style="width:400px;height:240px;")
+ JANRAIN_URL = \
+ "https://%s.rpxnow.com/openid/embed?token_url=%s&language_preference=%s"
+ rpxform = IFRAME(
+ _src=JANRAIN_URL % (
+ self.domain, self.token_url, self.language),
+ _scrolling="no",
+ _frameborder="no",
+ _style="width:400px;height:240px;")
else:
JANRAIN_URL = \
"https://%s.rpxnow.com/openid/v2/signin?token_url=%s"
@@ -114,15 +120,15 @@ class RPXAccount(object):
_type="text/javascript"))
return rpxform
-def use_janrain(auth,filename='private/janrain.key',**kwargs):
- path = os.path.join(current.request.folder,filename)
+
+def use_janrain(auth, filename='private/janrain.key', **kwargs):
+ path = os.path.join(current.request.folder, filename)
if os.path.exists(path):
request = current.request
- domain,key = open(path,'r').read().strip().split(':')
+ domain, key = open(path, 'r').read().strip().split(':')
host = current.request.env.http_host
url = URL('default', 'user', args='login', scheme=True)
auth.settings.actions_disabled = \
- ['register','change_password','request_reset_password']
+ ['register', 'change_password', 'request_reset_password']
auth.settings.login_form = RPXAccount(
- request, api_key=key,domain=domain, url = url,**kwargs)
-
+ request, api_key=key, domain=domain, url=url, **kwargs)
diff --git a/gluon/contrib/login_methods/x509_auth.py b/gluon/contrib/login_methods/x509_auth.py
index 36db643d..7dbb9a64 100644
--- a/gluon/contrib/login_methods/x509_auth.py
+++ b/gluon/contrib/login_methods/x509_auth.py
@@ -11,13 +11,12 @@ Adds support for x509 authentication.
from gluon.globals import current
from gluon.storage import Storage
-from gluon.http import HTTP,redirect
+from gluon.http import HTTP, redirect
#requires M2Crypto
from M2Crypto import X509
-
class X509Auth(object):
"""
Login using x509 cert from client.
@@ -29,8 +28,6 @@ class X509Auth(object):
"""
-
-
def __init__(self):
self.request = current.request
self.ssl_client_raw_cert = self.request.env.ssl_client_raw_cert
@@ -41,10 +38,11 @@ class X509Auth(object):
if self.ssl_client_raw_cert:
- x509=X509.load_cert_string(self.ssl_client_raw_cert, X509.FORMAT_PEM)
+ x509 = X509.load_cert_string(
+ self.ssl_client_raw_cert, X509.FORMAT_PEM)
# extract it from the cert
- self.serial = self.request.env.ssl_client_serial or ('%x' % x509.get_serial_number()).upper()
-
+ self.serial = self.request.env.ssl_client_serial or (
+ '%x' % x509.get_serial_number()).upper()
subject = x509.get_subject()
@@ -53,23 +51,17 @@ class X509Auth(object):
# cn = self.subject.cn
self.subject = Storage(filter(None,
map(lambda x:
- (x,map(lambda y:
- y.get_data().as_text(),
- subject.get_entries_by_nid(subject.nid[x]))),
+ (x, map(lambda y:
+ y.get_data(
+ ).as_text(),
+ subject.get_entries_by_nid(subject.nid[x]))),
subject.nid.keys())))
-
-
def login_form(self, **args):
- raise HTTP(403,'Login not allowed. No valid x509 crentials')
-
-
+ raise HTTP(403, 'Login not allowed. No valid x509 crentials')
def login_url(self, next="/"):
- raise HTTP(403,'Login not allowed. No valid x509 crentials')
-
-
-
+ raise HTTP(403, 'Login not allowed. No valid x509 crentials')
def logout_url(self, next="/"):
return next
@@ -86,10 +78,14 @@ class X509Auth(object):
p = profile = dict()
- username = p['username'] = reduce(lambda a,b: '%s | %s' % (a,b), self.subject.CN or self.subject.commonName)
- p['first_name'] = reduce(lambda a,b: '%s | %s' % (a,b),self.subject.givenName or username)
- p['last_name'] = reduce(lambda a,b: '%s | %s' % (a,b),self.subject.surname)
- p['email'] = reduce(lambda a,b: '%s | %s' % (a,b),self.subject.Email or self.subject.emailAddress)
+ username = p['username'] = reduce(lambda a, b: '%s | %s' % (
+ a, b), self.subject.CN or self.subject.commonName)
+ p['first_name'] = reduce(lambda a, b: '%s | %s' % (a, b),
+ self.subject.givenName or username)
+ p['last_name'] = reduce(
+ lambda a, b: '%s | %s' % (a, b), self.subject.surname)
+ p['email'] = reduce(lambda a, b: '%s | %s' % (
+ a, b), self.subject.Email or self.subject.emailAddress)
# IMPORTANT WE USE THE CERT SERIAL AS UNIQUE KEY FOR THE USER
p['registration_id'] = self.serial
@@ -100,6 +96,3 @@ class X509Auth(object):
p['certificate'] = self.ssl_client_raw_cert
return profile
-
-
-
diff --git a/gluon/contrib/memdb.py b/gluon/contrib/memdb.py
index 527b051a..382739e8 100644
--- a/gluon/contrib/memdb.py
+++ b/gluon/contrib/memdb.py
@@ -44,22 +44,21 @@ SQL_DIALECTS = {'memcache': {
'is not null': 'IS NOT NULL',
'extract': None,
'left join': None,
- }}
+}}
def cleanup(text):
if re.compile('[^0-9a-zA-Z_]').findall(text):
- raise SyntaxError, \
- 'Can\'t cleanup \'%s\': only [0-9a-zA-Z_] allowed in table and field names' % text
+ raise SyntaxError('Can\'t cleanup \'%s\': only [0-9a-zA-Z_] allowed in table and field names' % text)
return text
def assert_filter_fields(*fields):
for field in fields:
if isinstance(field, (Field, Expression)) and field.type\
- in ['text', 'blob']:
- raise SyntaxError, 'AppEngine does not index by: %s'\
- % field.type
+ in ['text', 'blob']:
+ raise SyntaxError('AppEngine does not index by: %s'
+ % field.type)
def dateobj_to_datetime(object):
@@ -78,7 +77,7 @@ def dateobj_to_datetime(object):
object.minute,
object.second,
object.microsecond,
- )
+ )
return object
@@ -96,7 +95,7 @@ def sqlhtml_validators(field_type, length):
'time': validators.IS_TIME(),
'datetime': validators.IS_DATETIME(),
'reference': validators.IS_INT_IN_RANGE(0, 1e100),
- }
+ }
try:
return v[field_type[:9]]
except KeyError:
@@ -114,7 +113,8 @@ class DALStorage(dict):
def __setattr__(self, key, value):
if key in self:
- raise SyntaxError, 'Object \'%s\'exists and cannot be redefined' % key
+ raise SyntaxError(
+ 'Object \'%s\'exists and cannot be redefined' % key)
self[key] = value
def __repr__(self):
@@ -151,14 +151,14 @@ class MEMDB(DALStorage):
tablename,
*fields,
**args
- ):
+ ):
tablename = cleanup(tablename)
if tablename in dir(self) or tablename[0] == '_':
- raise SyntaxError, 'invalid table name: %s' % tablename
+ raise SyntaxError('invalid table name: %s' % tablename)
if not tablename in self.tables:
self.tables.append(tablename)
else:
- raise SyntaxError, 'table already defined: %s' % tablename
+ raise SyntaxError('table already defined: %s' % tablename)
t = self[tablename] = Table(self, tablename, *fields)
t._create()
return t
@@ -190,7 +190,7 @@ class Table(DALStorage):
db,
tablename,
*fields
- ):
+ ):
self._db = db
self._tablename = tablename
self.fields = SQLCallableList()
@@ -219,24 +219,24 @@ class Table(DALStorage):
if field.type[:9] == 'reference':
referenced = field.type[10:].strip()
if not referenced:
- raise SyntaxError, \
- 'Table %s: reference \'%s\' to nothing!' % (self._tablename, k)
+ raise SyntaxError('Table %s: reference \'%s\' to nothing!' % (
+ self._tablename, k))
if not referenced in self._db:
- raise SyntaxError, \
- 'Table: table %s does not exist' % referenced
+ raise SyntaxError(
+ 'Table: table %s does not exist' % referenced)
referee = self._db[referenced]
ftype = \
self._db._translator[field.type[:9]](
self._db[referenced]._tableobj)
if self._tablename in referee.fields: # ## THIS IS OK
- raise SyntaxError, \
- 'Field: table \'%s\' has same name as a field ' \
- 'in referenced table \'%s\'' % (self._tablename, referenced)
+ raise SyntaxError('Field: table \'%s\' has same name as a field '
+ 'in referenced table \'%s\'' % (
+ self._tablename, referenced))
self._db[referenced]._referenced_by.append((self._tablename,
- field.name))
+ field.name))
elif not field.type in self._db._translator\
- or not self._db._translator[field.type]:
- raise SyntaxError, 'Field: unkown field type %s' % field.type
+ or not self._db._translator[field.type]:
+ raise SyntaxError('Field: unkown field type %s' % field.type)
self._tableobj = self._db.client
return None
@@ -269,11 +269,11 @@ class Table(DALStorage):
def update(self, id, **fields):
for field in fields:
if not field in fields and self[field].default\
- != None:
+ is not None:
fields[field] = self[field].default
if field in fields:
fields[field] = obj_represent(fields[field],
- self[field].type, self._db)
+ self[field].type, self._db)
return self._tableobj.set(self._id_to_key(id), fields)
def delete(self, id):
@@ -293,7 +293,7 @@ class Table(DALStorage):
if self._tableobj.set(shard_id, '0'):
id = 0
else:
- raise Exception, 'cannot set memcache'
+ raise Exception('cannot set memcache')
return long(str(shard) + str(id))
def __str__(self):
@@ -307,7 +307,7 @@ class Expression(object):
name,
type='string',
db=None,
- ):
+ ):
(self.name, self.type, self._db) = (name, type, db)
def __str__(self):
@@ -393,11 +393,11 @@ class Field(Expression):
notnull=False,
unique=False,
uploadfield=True,
- ):
+ ):
self.name = cleanup(fieldname)
if fieldname in dir(Table) or fieldname[0] == '_':
- raise SyntaxError, 'Field: invalid field name: %s' % fieldname
+ raise SyntaxError('Field: invalid field name: %s' % fieldname)
if isinstance(type, Table):
type = 'reference ' + type._tablename
if not length:
@@ -437,9 +437,9 @@ MEMDB.Field = Field # ## required by gluon/globals.py session.connect
def obj_represent(object, fieldtype, db):
- if object != None:
+ if object is not None:
if fieldtype == 'date' and not isinstance(object,
- datetime.date):
+ datetime.date):
(y, m, d) = [int(x) for x in str(object).strip().split('-')]
object = datetime.date(y, m, d)
elif fieldtype == 'time' and not isinstance(object, datetime.time):
@@ -450,7 +450,7 @@ def obj_represent(object, fieldtype, db):
(h, mi, s) = time_items + [0]
object = datetime.time(h, mi, s)
elif fieldtype == 'datetime' and not isinstance(object,
- datetime.datetime):
+ datetime.datetime):
(y, m, d) = [int(x) for x in
str(object)[:10].strip().split('-')]
time_items = [int(x) for x in
@@ -466,7 +466,7 @@ def obj_represent(object, fieldtype, db):
h,
mi,
s,
- )
+ )
elif fieldtype == 'integer' and not isinstance(object, long):
object = long(object)
@@ -496,10 +496,10 @@ class Query(object):
left,
op=None,
right=None,
- ):
+ ):
if isinstance(right, (Field, Expression)):
- raise SyntaxError, \
- 'Query: right side of filter must be a value or entity'
+ raise SyntaxError(
+ 'Query: right side of filter must be a value or entity')
if isinstance(left, Field) and left.name == 'id':
if op == '=':
self.get_one = \
@@ -507,8 +507,8 @@ class Query(object):
id=long(right))
return
else:
- raise SyntaxError, 'only equality by id is supported'
- raise SyntaxError, 'not supported'
+ raise SyntaxError('only equality by id is supported')
+ raise SyntaxError('not supported')
def __str__(self):
return str(self.left)
@@ -539,7 +539,7 @@ class Set(object):
self.where = where
self._tables.insert(0, where.get_all)
elif hasattr(where, 'get_one') and isinstance(where.get_one,
- QueryException):
+ QueryException):
self.where = where.get_one
else:
@@ -553,9 +553,8 @@ class Set(object):
def __call__(self, where):
if isinstance(self.where, QueryException) or isinstance(where,
- QueryException):
- raise SyntaxError, \
- 'neither self.where nor where can be a QueryException instance'
+ QueryException):
+ raise SyntaxError('neither self.where nor where can be a QueryException instance')
if self.where:
return Set(self._db, self.where & where)
else:
@@ -564,9 +563,9 @@ class Set(object):
def _get_table_or_raise(self):
tablenames = list(set(self._tables)) # unique
if len(tablenames) < 1:
- raise SyntaxError, 'Set: no tables selected'
+ raise SyntaxError('Set: no tables selected')
if len(tablenames) > 1:
- raise SyntaxError, 'Set: no join in appengine'
+ raise SyntaxError('Set: no join in appengine')
return self._db[tablenames[0]]._tableobj
def _getitem_exception(self):
@@ -597,7 +596,7 @@ class Set(object):
if isinstance(self.where, QueryException):
return self._select_except()
else:
- raise SyntaxError, 'select arguments not supported'
+ raise SyntaxError('select arguments not supported')
def count(self):
return len(self.select())
@@ -609,7 +608,7 @@ class Set(object):
return
self._db[tablename].delete(id)
else:
- raise Exception, 'deletion not implemented'
+ raise Exception('deletion not implemented')
def update(self, **update_fields):
if isinstance(self.where, QueryException):
@@ -620,7 +619,7 @@ class Set(object):
setattr(item, key, value)
self._db[tablename].update(id, **item)
else:
- raise Exception, 'update not implemented'
+ raise Exception('update not implemented')
def update_record(
@@ -628,7 +627,7 @@ def update_record(
s,
id,
a,
- ):
+):
item = s.get(id)
for (key, value) in a.items():
t[key] = value
@@ -650,7 +649,7 @@ class Rows(object):
db,
response,
*colnames
- ):
+ ):
self._db = db
self.colnames = colnames
self.response = response
@@ -660,9 +659,9 @@ class Rows(object):
def __getitem__(self, i):
if i >= len(self.response) or i < 0:
- raise SyntaxError, 'Rows: no such row: %i' % i
+ raise SyntaxError('Rows: no such row: %i' % i)
if len(self.response[0]) != len(self.colnames):
- raise SyntaxError, 'Rows: internal error'
+ raise SyntaxError('Rows: internal error')
row = DALStorage()
for j in xrange(len(self.colnames)):
value = self.response[i][j]
@@ -684,7 +683,7 @@ class Rows(object):
referee = field.type[10:].strip()
rid = value
row[tablename][fieldname] = rid
- elif field.type == 'boolean' and value != None:
+ elif field.type == 'boolean' and value is not None:
# row[tablename][fieldname]=Set(self._db[referee].id==rid)
@@ -692,13 +691,13 @@ class Rows(object):
row[tablename][fieldname] = True
else:
row[tablename][fieldname] = False
- elif field.type == 'date' and value != None\
- and not isinstance(value, datetime.date):
+ elif field.type == 'date' and value is not None\
+ and not isinstance(value, datetime.date):
(y, m, d) = [int(x) for x in
str(value).strip().split('-')]
row[tablename][fieldname] = datetime.date(y, m, d)
- elif field.type == 'time' and value != None\
- and not isinstance(value, datetime.time):
+ elif field.type == 'time' and value is not None\
+ and not isinstance(value, datetime.time):
time_items = [int(x) for x in
str(value).strip().split(':')[:3]]
if len(time_items) == 3:
@@ -706,8 +705,8 @@ class Rows(object):
else:
(h, mi, s) = time_items + [0]
row[tablename][fieldname] = datetime.time(h, mi, s)
- elif field.type == 'datetime' and value != None\
- and not isinstance(value, datetime.datetime):
+ elif field.type == 'datetime' and value is not None\
+ and not isinstance(value, datetime.datetime):
(y, m, d) = [int(x) for x in
str(value)[:10].strip().split('-')]
time_items = [int(x) for x in
@@ -723,19 +722,19 @@ class Rows(object):
h,
mi,
s,
- )
+ )
else:
row[tablename][fieldname] = value
if fieldname == 'id':
id = row[tablename].id
row[tablename].update_record = lambda t = row[tablename], \
s = self._db[tablename], id = id, **a: update_record(t,
- s, id, a)
+ s, id, a)
for (referee_table, referee_name) in \
- table._referenced_by:
+ table._referenced_by:
s = self._db[referee_table][referee_name]
row[tablename][referee_table] = Set(self._db, s
- == id)
+ == id)
if len(row.keys()) == 1:
return row[row.keys()[0]]
return row
diff --git a/gluon/contrib/minify/cssmin.py b/gluon/contrib/minify/cssmin.py
index 0a8853cf..f9ed89f9 100644
--- a/gluon/contrib/minify/cssmin.py
+++ b/gluon/contrib/minify/cssmin.py
@@ -11,7 +11,7 @@ Modified for inclusion into web2py by: Ross Peoples
"""
-from StringIO import StringIO # The pure-Python StringIO supports unicode.
+from StringIO import StringIO # The pure-Python StringIO supports unicode.
import re
@@ -20,7 +20,7 @@ __version__ = '0.1.4'
def remove_comments(css):
"""Remove all CSS comment blocks."""
-
+
iemac = False
preserve = False
comment_start = css.find("/*")
@@ -28,7 +28,7 @@ def remove_comments(css):
# Preserve comments that look like `/*!...*/`.
# Slicing is used to make sure we don"t get an IndexError.
preserve = css[comment_start + 2:comment_start + 3] == "!"
-
+
comment_end = css.find("*/", comment_start + 2)
if comment_end < 0:
if not preserve:
@@ -48,22 +48,22 @@ def remove_comments(css):
else:
comment_start = comment_end + 2
comment_start = css.find("/*", comment_start)
-
+
return css
def remove_unnecessary_whitespace(css):
"""Remove unnecessary whitespace characters."""
-
+
def pseudoclasscolon(css):
-
+
"""
Prevents 'p :link' from becoming 'p:link'.
-
+
Translates 'p :link' into 'p ___PSEUDOCLASSCOLON___link'; this is
translated back again later.
"""
-
+
regex = re.compile(r"(^|\})(([^\{\:])+\:)+([^\{]*\{)")
match = regex.search(css)
while match:
@@ -73,43 +73,43 @@ def remove_unnecessary_whitespace(css):
css[match.end():]])
match = regex.search(css)
return css
-
+
css = pseudoclasscolon(css)
# Remove spaces from before things.
css = re.sub(r"\s+([!{};:>+\(\)\],])", r"\1", css)
-
+
# If there is a `@charset`, then only allow one, and move to the beginning.
css = re.sub(r"^(.*)(@charset \"[^\"]*\";)", r"\2\1", css)
css = re.sub(r"^(\s*@charset [^;]+;\s*)+", r"\1", css)
-
+
# Put the space back in for a few cases, such as `@media screen` and
# `(-webkit-min-device-pixel-ratio:0)`.
css = re.sub(r"\band\(", "and (", css)
-
+
# Put the colons back.
css = css.replace('___PSEUDOCLASSCOLON___', ':')
-
+
# Remove spaces from after things.
css = re.sub(r"([!{}:;>+\(\[,])\s+", r"\1", css)
-
+
return css
def remove_unnecessary_semicolons(css):
"""Remove unnecessary semicolons."""
-
+
return re.sub(r";+\}", "}", css)
def remove_empty_rules(css):
"""Remove empty rules."""
-
+
return re.sub(r"[^\}\{]+\{\}", "", css)
def normalize_rgb_colors_to_hex(css):
"""Convert `rgb(51,102,153)` to `#336699`."""
-
+
regex = re.compile(r"rgb\s*\(\s*([0-9,\s]+)\s*\)")
match = regex.search(css)
while match:
@@ -122,39 +122,40 @@ def normalize_rgb_colors_to_hex(css):
def condense_zero_units(css):
"""Replace `0(px, em, %, etc)` with `0`."""
-
+
return re.sub(r"([\s:])(0)(px|em|%|in|cm|mm|pc|pt|ex)", r"\1\2", css)
def condense_multidimensional_zeros(css):
"""Replace `:0 0 0 0;`, `:0 0 0;` etc. with `:0;`."""
-
+
css = css.replace(":0 0 0 0;", ":0;")
css = css.replace(":0 0 0;", ":0;")
css = css.replace(":0 0;", ":0;")
-
+
# Revert `background-position:0;` to the valid `background-position:0 0;`.
css = css.replace("background-position:0;", "background-position:0 0;")
-
+
return css
def condense_floating_points(css):
"""Replace `0.6` with `.6` where possible."""
-
+
return re.sub(r"(:|\s)0+\.(\d+)", r"\1.\2", css)
def condense_hex_colors(css):
"""Shorten colors from #AABBCC to #ABC where possible."""
-
+
regex = re.compile(r"([^\"'=\s])(\s*)#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])")
match = regex.search(css)
while match:
first = match.group(3) + match.group(5) + match.group(7)
second = match.group(4) + match.group(6) + match.group(8)
if first.lower() == second.lower():
- css = css.replace(match.group(), match.group(1) + match.group(2) + '#' + first)
+ css = css.replace(
+ match.group(), match.group(1) + match.group(2) + '#' + first)
match = regex.search(css, match.end() - 3)
else:
match = regex.search(css, match.end())
@@ -163,19 +164,19 @@ def condense_hex_colors(css):
def condense_whitespace(css):
"""Condense multiple adjacent whitespace characters into one."""
-
+
return re.sub(r"\s+", " ", css)
def condense_semicolons(css):
"""Condense multiple adjacent semicolon characters into one."""
-
+
return re.sub(r";;+", ";", css)
def wrap_css_lines(css, line_length):
"""Wrap the lines of the given CSS to an approximate length."""
-
+
lines = []
line_start = 0
for i, char in enumerate(css):
@@ -183,7 +184,7 @@ def wrap_css_lines(css, line_length):
if char == '}' and (i - line_start >= line_length):
lines.append(css[line_start:i + 1])
line_start = i + 1
-
+
if line_start < len(css):
lines.append(css[line_start:])
return '\n'.join(lines)
@@ -212,19 +213,19 @@ def cssmin(css, wrap=None):
def main():
import optparse
import sys
-
+
p = optparse.OptionParser(
prog="cssmin", version=__version__,
usage="%prog [--wrap N]",
description="""Reads raw CSS from stdin, and writes compressed CSS to stdout.""")
-
+
p.add_option(
'-w', '--wrap', type='int', default=None, metavar='N',
help="Wrap output to approximately N chars per line.")
-
+
options, args = p.parse_args()
sys.stdout.write(cssmin(sys.stdin.read(), wrap=options.wrap))
if __name__ == '__main__':
- main()
\ No newline at end of file
+ main()
diff --git a/gluon/contrib/minify/htmlmin.py b/gluon/contrib/minify/htmlmin.py
index fbb3896b..ea4971ea 100644
--- a/gluon/contrib/minify/htmlmin.py
+++ b/gluon/contrib/minify/htmlmin.py
@@ -2,12 +2,14 @@
import re
+
def minify(response):
- def _replace(match):
- match = match.group()
- # save whole ,