Compare commits

..

21 Commits

Author SHA1 Message Date
mdipierro
961d143f7d 2.7.2 2013-10-07 08:40:39 -05:00
mdipierro
0e98544a79 Merge pull request #242 from rhr/master
fix for using the shell with IPython >= 1.0
2013-10-06 19:37:56 -07:00
mdipierro
86d8b8dece Merge pull request #241 from spametki/master
IMAP fixed patch for google code issue 1707
2013-10-06 19:37:11 -07:00
Rick Ree
46e2a663e9 fix for using the shell with IPython >= 1.0 2013-10-06 17:18:04 -05:00
spametki
e7fbd0095f IMAP google code issue 1707: fixed patch 2013-10-06 14:39:23 -03:00
mdipierro
add6fa526e fixed regex status in http.py 2013-10-06 11:52:23 -05:00
mdipierro
47e77e9a9c Merge pull request #239 from abastardi/patch-1
Fixed problem with Rows.render
2013-10-06 08:15:09 -07:00
mdipierro
81036ac997 Merge pull request #237 from alfonsodg/master
Added gitignore restrictions and changes for admin.py
2013-10-06 08:13:58 -07:00
mdipierro
77df883566 Merge pull request #236 from niphlod/enhancement/anyserver_options
fixed gevent workers
2013-10-06 08:11:03 -07:00
mdipierro
bfc7e3b4e9 Merge pull request #238 from houdinihound/patch-1
Support for HTTP Status Code: 429 - Too Many Requests
2013-10-06 08:09:52 -07:00
spametki
e05fe15470 IMAP .insert support for custom date (Google Code issue 1707) 2013-10-06 12:09:44 -03:00
mdipierro
2a062a2ff5 fixed setup scripts for apache to use processes, not threads, thanks Thomas 2013-10-06 10:08:40 -05:00
abastardi
44e7b70dbc Fixed problem with Rows.render 2013-10-06 09:04:47 -04:00
Jose C
88abefb896 Support for HTTP Status Code: 429 - Too Many Requests
Currently raising HTTP 429 results in HTTP 500 being sent.  This patch resolves that issue.
2013-10-05 15:42:48 +01:00
mdipierro
06ca5e6857 grid refcator patch for ajax, thanks Niphlod 2013-10-05 08:52:45 -05:00
Alfonso de la Guarda Reyes
c1f8d34892 Minor fixes for pep and styles widget.py 2013-10-05 08:08:37 -05:00
Alfonso de la Guarda Reyes
5679661914 Minor fixes for pep and style 2013-10-05 08:03:50 -05:00
Alfonso de la Guarda Reyes
cd957cf52b Fixes for some pep and code syntax 2013-10-05 07:59:04 -05:00
Alfonso de la Guarda Reyes
fff798c1cc Added restriction for .idea inside gitignore 2013-10-05 07:51:12 -05:00
niphlod
b464d3185e fixed gevent workers 2013-10-05 13:43:03 +02:00
mdipierro
cfb68ff90f fixed ldap_auth.py 2013-10-04 21:31:39 -05:00
20 changed files with 107 additions and 115 deletions

1
.gitignore vendored
View File

@@ -55,3 +55,4 @@ applications/admin/cron/cron.master
HOWTO-web2py-devel
*.sublime-project
*.sublime-workspace
.idea/*

View File

@@ -1,4 +1,4 @@
## 2.7.1
## 2.7.1 - 2.7.2
- jQuery 1.10.2
- codemirror 3.18, thanks Paolo

View File

@@ -30,7 +30,7 @@ update:
echo "remember that pymysql was tweaked"
src:
### Use semantic versioning
echo 'Version 2.7.1-stable+timestamp.'`date +%Y.%m.%d.%H.%M.%S` > VERSION
echo 'Version 2.7.2-stable+timestamp.'`date +%Y.%m.%d.%H.%M.%S` > VERSION
### rm -f all junk files
make clean
### clean up baisc apps

View File

@@ -1 +1 @@
Version 2.7.1-stable+timestamp.2013.10.04.15.14.09
Version 2.7.2-stable+timestamp.2013.10.07.08.39.32

View File

@@ -33,7 +33,7 @@ class Servers:
@staticmethod
def wsgiref(app, address, **options): # pragma: no cover
from wsgiref.simple_server import make_server, WSGIRequestHandler
options = {}
class QuietHandler(WSGIRequestHandler):
def log_request(*args, **kw):
pass
@@ -71,6 +71,7 @@ class Servers:
@staticmethod
def paste(app, address, **options):
options = {}
from paste import httpserver
from paste.translogger import TransLogger
httpserver.serve(app, host=address[0], port=address[1], **options)
@@ -90,10 +91,12 @@ class Servers:
@staticmethod
def gevent(app, address, **options):
options = options['options']
workers = options.workers
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 and Pool(
int(options.workers)) or 'default', log=None).serve_forever()
@staticmethod
def bjoern(app, address, **options):
@@ -130,6 +133,7 @@ class Servers:
@staticmethod
def gunicorn(app, address, **options):
options = {}
from gunicorn.app.base import Application
config = {'bind': "%s:%d" % address}
config.update(options)
@@ -176,27 +180,6 @@ class Servers:
s = wsgi.WSGIServer(callable=app, bind="%s:%d" % address)
s.start()
def run(servername, ip, port, softcron=True, logging=False, profiler=None):
if servername == 'gevent':
from gevent import monkey
monkey.patch_all()
elif servername == 'eventlet':
import eventlet
eventlet.monkey_patch()
import gluon.main
if logging:
application = gluon.main.appfactory(wsgiapp=gluon.main.wsgibase,
logfilename='httpserver.log',
profiler_dir=profiler)
else:
application = gluon.main.wsgibase
if softcron:
from gluon.settings import global_settings
global_settings.web2py_crontype = 'soft'
getattr(Servers, servername)(application, (ip, int(port)))
def mongrel2_handler(application, conn, debug=False):
"""
@@ -303,6 +286,30 @@ def mongrel2_handler(application, conn, debug=False):
req, data, code=code, status=status, headers=headers)
def run(servername, ip, port, softcron=True, logging=False, profiler=None,
options=None):
if servername == 'gevent':
from gevent import monkey
monkey.patch_all()
elif servername == 'eventlet':
import eventlet
eventlet.monkey_patch()
import gluon.main
if logging:
application = gluon.main.appfactory(wsgiapp=gluon.main.wsgibase,
logfilename='httpserver.log',
profiler_dir=profiler)
else:
application = gluon.main.wsgibase
if softcron:
from gluon.settings import global_settings
global_settings.web2py_crontype = 'soft'
getattr(Servers, servername)(application, (ip, int(port)), options=options)
def main():
usage = "python anyserver.py -s tornado -i 127.0.0.1 -p 8000 -l -P"
try:
@@ -339,14 +346,15 @@ def main():
help='port number')
parser.add_option('-w',
'--workers',
default='',
default=None,
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_dir)
logging=options.logging, profiler=options.profiler_dir,
options=options)
if __name__ == '__main__':
main()

View File

@@ -10,6 +10,7 @@
'(requires internet access, experimental)': '(requires internet access, experimental)',
'(something like "it-it")': '(algo como "it-it")',
'@markmin\x01(file **gluon/contrib/plural_rules/%s.py** is not found)': '(file **gluon/contrib/plural_rules/%s.py** is not found)',
'@markmin\x01An error occured, please [[reload %s]] the page': 'An error occured, please [[reload %s]] the page',
'@markmin\x01Searching: **%s** %%{file}': 'Searching: **%s** files',
'A new version of web2py is available': 'Hay una nueva versión de web2py disponible',
'A new version of web2py is available: %s': 'Hay una nueva versión de web2py disponible: %s',
@@ -31,6 +32,7 @@
'appadmin': 'appadmin',
'appadmin is disabled because insecure channel': 'admin deshabilitado, el canal no es seguro',
'application "%s" uninstalled': 'aplicación "%s" desinstalada',
'application %(appname)s installed with md5sum: %(digest)s': 'application %(appname)s installed with md5sum: %(digest)s',
'application compiled': 'aplicación compilada',
'application is compiled and cannot be designed': 'la aplicación está compilada y no puede ser modificada',
'Application name:': 'Application name:',
@@ -92,6 +94,7 @@
'Create new application using the Wizard': 'Create new application using the Wizard',
'create new application:': 'nombre de la nueva aplicación:',
'Create new simple application': 'Cree una nueva aplicación',
'Create/Upload': 'Create/Upload',
'created by': 'creado por',
'crontab': 'crontab',
'Current request': 'Solicitud en curso',

View File

@@ -264,16 +264,6 @@
}
});
},
trap_link: function (target) {
$('#' + target + ' a.w2p_trap').each(function (i) {
var link = $(this);
link.click(function (e) {
web2py.hide_flash();
web2py.ajax_page('get', link.attr('href'), [], target, $(this));
e.preventDefault();
});
});
},
ajax_page: function (method, action, data, target, element) {
/* element is a new parameter, but should be put be put in front */
if(element == undefined) element = $(document);
@@ -307,7 +297,6 @@
web2py.fire(element, 'ajax:complete', [xhr, status], target);
web2py.updatePage(xhr, target); /* Parse and load the html received */
web2py.trap_form(action, target);
web2py.trap_link(target);
web2py.ajax_init('#' + target);
web2py.after_ajax(xhr);
}
@@ -692,10 +681,8 @@ collapse = jQuery.web2py.collapse;
fade = jQuery.web2py.fade;
/* internals - shouldn't be needed
web2py_ajax_init = jQuery.web2py.ajax_init;
web2py_event_handlers = jQuery.web2py.event_handlers;
web2py_trap_link = jQuery.web2py.trap_link;
web2py_calc_entropy = jQuery.web2py.calc_entropy;
*/

View File

@@ -264,16 +264,6 @@
}
});
},
trap_link: function (target) {
$('#' + target + ' a.w2p_trap').each(function (i) {
var link = $(this);
link.click(function (e) {
web2py.hide_flash();
web2py.ajax_page('get', link.attr('href'), [], target, $(this));
e.preventDefault();
});
});
},
ajax_page: function (method, action, data, target, element) {
/* element is a new parameter, but should be put be put in front */
if(element == undefined) element = $(document);
@@ -307,7 +297,6 @@
web2py.fire(element, 'ajax:complete', [xhr, status], target);
web2py.updatePage(xhr, target); /* Parse and load the html received */
web2py.trap_form(action, target);
web2py.trap_link(target);
web2py.ajax_init('#' + target);
web2py.after_ajax(xhr);
}
@@ -692,10 +681,8 @@ collapse = jQuery.web2py.collapse;
fade = jQuery.web2py.fade;
/* internals - shouldn't be needed
web2py_ajax_init = jQuery.web2py.ajax_init;
web2py_event_handlers = jQuery.web2py.event_handlers;
web2py_trap_link = jQuery.web2py.trap_link;
web2py_calc_entropy = jQuery.web2py.calc_entropy;
*/

View File

@@ -264,16 +264,6 @@
}
});
},
trap_link: function (target) {
$('#' + target + ' a.w2p_trap').each(function (i) {
var link = $(this);
link.click(function (e) {
web2py.hide_flash();
web2py.ajax_page('get', link.attr('href'), [], target, $(this));
e.preventDefault();
});
});
},
ajax_page: function (method, action, data, target, element) {
/* element is a new parameter, but should be put be put in front */
if(element == undefined) element = $(document);
@@ -307,7 +297,6 @@
web2py.fire(element, 'ajax:complete', [xhr, status], target);
web2py.updatePage(xhr, target); /* Parse and load the html received */
web2py.trap_form(action, target);
web2py.trap_link(target);
web2py.ajax_init('#' + target);
web2py.after_ajax(xhr);
}
@@ -692,10 +681,8 @@ collapse = jQuery.web2py.collapse;
fade = jQuery.web2py.fade;
/* internals - shouldn't be needed
web2py_ajax_init = jQuery.web2py.ajax_init;
web2py_event_handlers = jQuery.web2py.event_handlers;
web2py_trap_link = jQuery.web2py.trap_link;
web2py_calc_entropy = jQuery.web2py.calc_entropy;
*/

View File

@@ -353,7 +353,7 @@ def plugin_install(app, fobj, request, filename):
return False
def check_new_version(myversion, version_URL):
def check_new_version(myversion, version_url):
"""
Compares current web2py's version with the latest stable web2py version.
@@ -374,7 +374,7 @@ def check_new_version(myversion, version_URL):
"""
try:
from urllib import urlopen
version = urlopen(version_URL).read()
version = urlopen(version_url).read()
pversion = parse_version(version)
pmyversion = parse_version(myversion)
except IOError:
@@ -398,7 +398,7 @@ def unzip(filename, dir, subfolder=''):
raise RuntimeError('Not a valid zipfile')
zf = zipfile.ZipFile(filename)
if not subfolder.endswith('/'):
subfolder = subfolder + '/'
subfolder += '/'
n = len(subfolder)
for name in sorted(zf.namelist()):
if not name.startswith(subfolder):
@@ -432,11 +432,11 @@ def upgrade(request, url='http://web2py.com'):
web2py_version = request.env.web2py_version
gluon_parent = request.env.gluon_parent
if not gluon_parent.endswith('/'):
gluon_parent = gluon_parent + '/'
gluon_parent += '/'
(check, version) = check_new_version(web2py_version,
url + '/examples/default/version')
if not check:
return (False, 'Already latest version')
return False, 'Already latest version'
if os.path.exists(os.path.join(gluon_parent, 'web2py.exe')):
version_type = 'win'
destination = gluon_parent
@@ -452,7 +452,6 @@ def upgrade(request, url='http://web2py.com'):
full_url = url + '/examples/static/web2py_%s.zip' % version_type
filename = abspath('web2py_%s_downloaded.zip' % version_type)
file = None
try:
write_file(filename, urllib.urlopen(full_url).read(), 'wb')
except Exception, e:

View File

@@ -19,7 +19,6 @@ When web2py is running on Google App Engine,
caching will be provided by the GAE memcache
(see gluon.contrib.gae_memcache)
"""
import traceback
import time
import portalocker
import shelve
@@ -278,7 +277,7 @@ class CacheOnDisk(CacheAbstract):
storage = shelve.open(self.shelve_name)
except:
logger.error('corrupted cache file %s, will try rebuild it'
% (self.shelve_name))
% self.shelve_name)
storage = None
if not storage and os.path.exists(self.shelve_name):
os.unlink(self.shelve_name)
@@ -479,7 +478,6 @@ class Cache(object):
if not session_ and public_:
cache_control += ', public'
expires = (current.request.utcnow + datetime.timedelta(seconds=time_expire)).strftime('%a, %d %b %Y %H:%M:%S GMT')
vary = None
else:
cache_control += ', private'
expires = 'Fri, 01 Jan 1990 00:00:00 GMT'

View File

@@ -640,10 +640,10 @@ def ldap_auth(server='ldap', port=None,
else:
# bind as anonymous
con.simple_bind_s('', '')
# if username is None, return empty list
if username is None:
return list()
# if username is None, return empty list
if username is None:
return list()
# search for groups where user is in
filter = '(&(%s=%s)(%s))' % (ldap.filter.escape_filter_chars(
group_member_attrib

View File

@@ -6124,7 +6124,7 @@ class IMAPAdapter(NoSQLAdapter):
else:
return (uid_list[0], uid_list[-1])
def convert_date(self, date, add=None):
def convert_date(self, date, add=None, imf=False):
if add is None:
add = datetime.timedelta()
""" Convert a date object to a string
@@ -6138,7 +6138,10 @@ class IMAPAdapter(NoSQLAdapter):
if isinstance(date, basestring):
# Prevent unexpected date response format
try:
dayname, datestring = date.split(",")
if "," in date:
dayname, datestring = date.split(",")
else:
dayname, datestring = None, date
date_list = datestring.strip().split()
year = int(date_list[2])
month = months.index(date_list[1].upper())
@@ -6150,8 +6153,10 @@ class IMAPAdapter(NoSQLAdapter):
LOGGER.error("Could not parse date text: %s. %s" %
(date, e))
return None
elif isinstance(date, (datetime.datetime, datetime.date)):
return (date + add).strftime("%d-%b-%Y")
elif isinstance(date, (datetime.date, datetime.datetime)):
if imf: date_format = "%a, %d %b %Y %H:%M:%S %z"
else: date_format = "%d-%b-%Y"
return (date + add).strftime(date_format)
else:
return None
@@ -6532,7 +6537,8 @@ class IMAPAdapter(NoSQLAdapter):
mailbox = table.mailbox
d = dict(((k.name, v) for k, v in fields))
date_time = (d.get("created", datetime.datetime.now())).timetuple()
date_time = d.get("created", datetime.datetime.now())
struct_time = date_time.timetuple()
if len(d) > 0:
message = d.get("email", None)
attachments = d.get("attachments", [])
@@ -6547,6 +6553,8 @@ class IMAPAdapter(NoSQLAdapter):
message = Message()
message["from"] = d.get("sender", "")
message["subject"] = d.get("subject", "")
message["date"] = self.convert_date(date_time, imf=True)
if mime:
message.set_type(mime)
if charset:
@@ -6569,7 +6577,7 @@ class IMAPAdapter(NoSQLAdapter):
[add_payload(message, c) for c in content]
[add_payload(message, a) for a in attachments]
message = message.as_string()
return (mailbox, flags, date_time, message)
return (mailbox, flags, struct_time, message)
else:
raise NotImplementedError("IMAP empty insert is not implemented")
@@ -10501,7 +10509,7 @@ class Rows(object):
if i is None:
return (self.repr(i, fields=fields) for i in range(len(self)))
return (self.render(i, fields=fields) for i in range(len(self)))
import sqlhtml
row = copy.deepcopy(self.records[i])
keys = row.keys()

View File

@@ -44,6 +44,7 @@ defined_status = {
416: 'REQUESTED RANGE NOT SATISFIABLE',
417: 'EXPECTATION FAILED',
422: 'UNPROCESSABLE ENTITY',
429: 'TOO MANY REQUESTS',
451: 'UNAVAILABLE FOR LEGAL REASONS', # http://www.451unavailable.org/
500: 'INTERNAL SERVER ERROR',
501: 'NOT IMPLEMENTED',
@@ -53,8 +54,7 @@ defined_status = {
505: 'HTTP VERSION NOT SUPPORTED',
}
regex_status = re.compile('^\d{3} \w+$')
regex_status = re.compile('^\d{3} [0-9A-Z ]+$')
class HTTP(Exception):

View File

@@ -288,7 +288,10 @@ def run(
else:
try:
import IPython
if IPython.__version__ >= '0.11':
if IPython.__version__ >= '1.0':
IPython.start_ipython(user_ns=_env)
return
elif IPython.__version__ >= '0.11':
from IPython.frontend.terminal.embed import InteractiveShellEmbed
shell = InteractiveShellEmbed(user_ns=_env)
shell()

View File

@@ -45,11 +45,6 @@ except ImportError:
table_field = re.compile('[\w_]+\.[\w_]+')
widget_class = re.compile('^\w*')
def trap_class(_class=None, trap=True):
return (trap and 'w2p_trap' or '') + (_class and ' ' + _class or '')
def represent(field, value, record):
f = field.represent
if not callable(f):
@@ -1897,7 +1892,8 @@ class SQLFORM(FORM):
callback=callback,
delete=delete,
noconfirm=noconfirm,
_class=trap_class(ui.get('button'), trap))
_class=ui.get('button'),
cid=request.cid)
else:
return A(SPAN(_class=ui.get(buttonclass)),
_href=buttonurl,
@@ -1905,7 +1901,8 @@ class SQLFORM(FORM):
delete=delete,
noconfirm=noconfirm,
_title=T(buttontext),
_class=trap_class(ui.get('buttontext'), trap))
_class=ui.get('buttontext'),
cid=request.cid)
dbset = db(query,ignore_common_filters=ignore_common_filters)
tablenames = db._adapter.tables(dbset.query)
@@ -2057,7 +2054,22 @@ class SQLFORM(FORM):
if ondelete:
ondelete(table, request.args[-1])
record.delete_record()
redirect(referrer, client_side=client_side_delete)
if request.ajax:
#this means javascript is enabled, so we don't need to do
#a redirect
if not client_side_delete:
#if it's an ajax request and we don't need to reload the
#entire page, let's just inform that there have been no
#exceptions and don't regenerate the grid
raise HTTP(200)
else:
#if it's requested that the grid gets reloaded on delete
#on ajax, the redirect should be on the original location
newloc = request.env.http_web2py_component_location
redirect(newloc, client_side=client_side_delete)
else:
#we need to do a redirect because javascript is not enabled
redirect(referrer, client_side=client_side_delete)
exportManager = dict(
csv_with_hidden_cols=(ExporterCSV, 'CSV (hidden cols)'),
@@ -2221,7 +2233,7 @@ class SQLFORM(FORM):
marker = sorter_icons[1]
header = A(header, marker, _href=url(vars=dict(
keywords=request.vars.keywords or '',
order=key)), _class=trap_class())
order=key)), cid=request.cid)
headcols.append(TH(header, _class=ui.get('default')))
toadd = []
@@ -2269,7 +2281,6 @@ class SQLFORM(FORM):
cacheable=True,*table_fields)
next_cursor = dbset._db.get('_lastcursor', None)
else:
# print('table_fields: %s' %([f_.name for f_ in table_fields],))
rows = dbset.select(left=left,orderby=orderby,
groupby=groupby,limitby=limitby,
cacheable=True,*table_fields)
@@ -2303,7 +2314,7 @@ class SQLFORM(FORM):
if order: d['order']=order
if request.vars.keywords: d['keywords']=request.vars.keywords
paginator.append(LI(
A('next',_href=url(vars=d),_class=trap_class())))
A('next',_href=url(vars=d),cid=request.cid)))
elif paginate and paginate<nrows:
npages, reminder = divmod(nrows, paginate)
if reminder:
@@ -2319,7 +2330,7 @@ class SQLFORM(FORM):
d['order'] = order
if request.vars.keywords:
d['keywords'] = request.vars.keywords
return A(name, _href=url(vars=d), _class=trap_class())
return A(name, _href=url(vars=d), cid=request.cid)
NPAGES = 5 # window is 2*NPAGES
if page > NPAGES + 1:
paginator.append(LI(self_link('<<', 0)))
@@ -2329,7 +2340,7 @@ class SQLFORM(FORM):
for p in pages:
if p == page:
paginator.append(LI(A(p + 1, _onclick='return false'),
_class=trap_class('current')))
_class='current'))
else:
paginator.append(LI(self_link(p + 1, p)))
if page < npages - NPAGES:
@@ -2598,13 +2609,13 @@ class SQLFORM(FORM):
name = format(db[referee],record)
breadcrumbs.append(
LI(A(T(db[referee]._plural),
_class=trap_class(),
cid=request.cid,
_href=url()),
SPAN(divider, _class='divider'),
_class='w2p_grid_breadcrumb_elem'))
if kwargs.get('details', True):
breadcrumbs.append(
LI(A(name, _class=trap_class(),
LI(A(name, cid=request.cid,
_href=url(args=['view', referee, id])),
SPAN(divider, _class='divider'),
_class='w2p_grid_breadcrumb_elem'))
@@ -2617,7 +2628,7 @@ class SQLFORM(FORM):
# if isinstance(linked_tables, dict):
# linked_tables = linked_tables.get(table._tablename, [])
if linked_tables is None or referee in linked_tables:
field.represent = lambda id, r=None, referee=referee, rep=field.represent: A(callable(rep) and rep(id) or id, _class=trap_class(), _href=url(args=['view', referee, id]))
field.represent = lambda id, r=None, referee=referee, rep=field.represent: A(callable(rep) and rep(id) or id, cid=request.cid, _href=url(args=['view', referee, id]))
except (KeyError, ValueError, TypeError):
redirect(URL(args=table._tablename))
if nargs == len(args) + 1:
@@ -2668,7 +2679,7 @@ class SQLFORM(FORM):
args0 = tablename + '.' + fieldname
links.append(
lambda row, t=t, nargs=nargs, args0=args0:
A(SPAN(t), _class=trap_class(), _href=url(
A(SPAN(t), cid=request.cid, _href=url(
args=[args0, row[id_field_name]])))
grid = SQLFORM.grid(query, args=request.args[:nargs], links=links,
@@ -2679,7 +2690,7 @@ class SQLFORM(FORM):
header = table._plural
next = grid.create_form or grid.update_form or grid.view_form
breadcrumbs.append(LI(
A(T(header), _class=trap_class(),_href=url()),
A(T(header), cid=request.cid,_href=url()),
SPAN(divider, _class='divider') if next else '',
_class='active w2p_grid_breadcrumb_elem'))
if grid.create_form:
@@ -2694,7 +2705,7 @@ class SQLFORM(FORM):
grid.view_form.record))
if next:
breadcrumbs.append(LI(
A(T(header), _class=trap_class(),_href=url()),
A(T(header), cid=request.cid,_href=url()),
_class='active w2p_grid_breadcrumb_elem'))
grid.insert(
0, DIV(UL(*breadcrumbs, **{'_class': breadcrumbs_class}),

View File

@@ -1005,7 +1005,7 @@ def console():
if not os.path.exists('applications/__init__.py'):
write_file('applications/__init__.py', '')
return (options, args)
return options, args
def check_existent_app(options, appname):
@@ -1022,7 +1022,7 @@ def get_code_for_scheduler(app, options):
code = code % ("','".join(app[1:]))
app_ = app[0]
if not check_existent_app(options, app_):
print "Application '%s' doesn't exist, skipping" % (app_)
print "Application '%s' doesn't exist, skipping" % app_
return None, None
return app_, code

View File

@@ -299,7 +299,7 @@ NameVirtualHost *:80
NameVirtualHost *:443
<VirtualHost *:80>
WSGIDaemonProcess web2py user=apache group=apache
WSGIDaemonProcess web2py user=apache group=apache processes=1 threads=1
WSGIProcessGroup web2py
WSGIScriptAlias / /opt/web-apps/web2py/wsgihandler.py

View File

@@ -301,7 +301,7 @@ NameVirtualHost *:80
NameVirtualHost *:443
<VirtualHost *:80>
WSGIDaemonProcess web2py user=apache group=apache
WSGIDaemonProcess web2py user=apache group=apache processes=1 threads=1
WSGIProcessGroup web2py
WSGIScriptAlias / /opt/web-apps/web2py/wsgihandler.py
WSGIPassAuthorization On

View File

@@ -91,7 +91,7 @@ NameVirtualHost *:443
# within a virtual host container, only WSGI applications associated with
# virtual hosts with the same server name as that virtual host can be
# delegated to that set of daemon processes.
WSGIDaemonProcess web2py user=www-data group=www-data
WSGIDaemonProcess web2py user=www-data group=www-data processes=1 threads=1
<VirtualHost *:80>
WSGIProcessGroup web2py