Merge github.com:web2py/web2py
This commit is contained in:
@@ -1 +1 @@
|
||||
Version 2.2.1 (2012-10-22 15:07:32) stable
|
||||
Version 2.2.1 (2012-10-26 15:51:12) stable
|
||||
|
||||
@@ -998,11 +998,11 @@ def design():
|
||||
statics.sort()
|
||||
|
||||
# Get all languages
|
||||
langpath = os.path.join(apath(app, r=request),'languages')
|
||||
languages = dict([(lang, info) for lang, info
|
||||
in read_possible_languages(
|
||||
apath(app, r=request)).iteritems()
|
||||
in read_possible_languages(langpath).iteritems()
|
||||
if info[2] != 0]) # info[2] is langfile_mtime:
|
||||
# get only existed files
|
||||
# get only existed files
|
||||
|
||||
#Get crontab
|
||||
cronfolder = apath('%s/cron' % app, r=request)
|
||||
|
||||
+2
-1
@@ -396,7 +396,8 @@ def build_environment(request, response, session, store_current=True):
|
||||
response.models_to_run = [r'^\w+\.py$', r'^%s/\w+\.py$' % request.controller,
|
||||
r'^%s/%s/\w+\.py$' % (request.controller, request.function)]
|
||||
|
||||
t = environment['T'] = translator(request)
|
||||
t = environment['T'] = translator(os.path.join(request.folder,'languages'),
|
||||
request.env.http_accept_language)
|
||||
c = environment['cache'] = Cache(request)
|
||||
|
||||
if store_current:
|
||||
|
||||
@@ -64,7 +64,7 @@ def new(key, mode=MODE_CBC, IV=None):
|
||||
return ECBMode(AES(key))
|
||||
elif mode == MODE_CBC:
|
||||
if IV is None:
|
||||
raise ValueError, "CBC mode needs an IV value!"
|
||||
raise ValueError("CBC mode needs an IV value!")
|
||||
|
||||
return CBCMode(AES(key), IV)
|
||||
else:
|
||||
@@ -91,7 +91,7 @@ class AES(object):
|
||||
elif self.key_size == 32:
|
||||
self.rounds = 14
|
||||
else:
|
||||
raise ValueError, "Key length must be 16, 24 or 32 bytes"
|
||||
raise ValueError("Key length must be 16, 24 or 32 bytes")
|
||||
|
||||
self.expand_key()
|
||||
|
||||
@@ -313,7 +313,7 @@ class ECBMode(object):
|
||||
"""Perform ECB mode with the given function"""
|
||||
|
||||
if len(data) % self.block_size != 0:
|
||||
raise ValueError, "Plaintext length must be multiple of 16"
|
||||
raise ValueError("Plaintext length must be multiple of 16")
|
||||
|
||||
block_size = self.block_size
|
||||
data = array('B', data)
|
||||
@@ -357,7 +357,7 @@ class CBCMode(object):
|
||||
|
||||
block_size = self.block_size
|
||||
if len(data) % block_size != 0:
|
||||
raise ValueError, "Plaintext length must be multiple of 16"
|
||||
raise ValueError("Plaintext length must be multiple of 16")
|
||||
|
||||
data = array('B', data)
|
||||
IV = self.IV
|
||||
@@ -381,7 +381,7 @@ class CBCMode(object):
|
||||
|
||||
block_size = self.block_size
|
||||
if len(data) % block_size != 0:
|
||||
raise ValueError, "Ciphertext length must be multiple of 16"
|
||||
raise ValueError("Ciphertext length must be multiple of 16")
|
||||
|
||||
data = array('B', data)
|
||||
IV = self.IV
|
||||
|
||||
@@ -222,7 +222,8 @@ def ldap_auth(server='ldap', port=None,
|
||||
con.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
|
||||
# In cases where ForestDnsZones and DomainDnsZones are found,
|
||||
# result will look like the following:
|
||||
# ['ldap://ForestDnsZones.domain.com/DC=ForestDnsZones,DC=domain,DC=com']
|
||||
# ['ldap://ForestDnsZones.domain.com/DC=ForestDnsZones,
|
||||
# DC=domain,DC=com']
|
||||
if ldap_binddn:
|
||||
# need to search directory with an admin account 1st
|
||||
con.simple_bind_s(ldap_binddn, ldap_bindpw)
|
||||
@@ -238,8 +239,9 @@ def ldap_auth(server='ldap', port=None,
|
||||
user_mail_attrib])
|
||||
result = con.search_ext_s(
|
||||
ldap_basedn, ldap.SCOPE_SUBTREE,
|
||||
"(&(sAMAccountName=%s)(%s))" % (ldap.filter.escape_filter_chars(username_bare),
|
||||
filterstr),
|
||||
"(&(sAMAccountName=%s)(%s))" % (
|
||||
ldap.filter.escape_filter_chars(username_bare),
|
||||
filterstr),
|
||||
requested_attrs)[0][1]
|
||||
if not isinstance(result, dict):
|
||||
# result should be a dict in the form
|
||||
@@ -292,8 +294,9 @@ def ldap_auth(server='ldap', port=None,
|
||||
# bind anonymously
|
||||
con.simple_bind_s(dn, pw)
|
||||
# search by e-mail address
|
||||
filter = '(&(mail=%s)(%s))' % (ldap.filter.escape_filter_chars(username),
|
||||
filterstr)
|
||||
filter = '(&(mail=%s)(%s))' % (
|
||||
ldap.filter.escape_filter_chars(username),
|
||||
filterstr)
|
||||
# find the uid
|
||||
attrs = ['uid']
|
||||
if manage_user:
|
||||
@@ -330,8 +333,10 @@ def ldap_auth(server='ldap', port=None,
|
||||
break
|
||||
except ldap.LDAPError, detail:
|
||||
(exc_type, exc_value) = sys.exc_info()[:2]
|
||||
logger.warning("ldap_auth: searching %s for %s resulted in %s: %s\n" %
|
||||
(basedn, filter, exc_type, exc_value))
|
||||
logger.warning(
|
||||
"ldap_auth: searching %s for %s resulted in %s: %s\n" %
|
||||
(basedn, filter, exc_type, exc_value)
|
||||
)
|
||||
if not found:
|
||||
logger.warning('User [%s] not found!' % username)
|
||||
return False
|
||||
@@ -365,8 +370,10 @@ def ldap_auth(server='ldap', port=None,
|
||||
break
|
||||
except ldap.LDAPError, detail:
|
||||
(exc_type, exc_value) = sys.exc_info()[:2]
|
||||
logger.warning("ldap_auth: searching %s for %s resulted in %s: %s\n" %
|
||||
(basedn, filter, exc_type, exc_value))
|
||||
logger.warning(
|
||||
"ldap_auth: searching %s for %s resulted in %s: %s\n" %
|
||||
(basedn, filter, exc_type, exc_value)
|
||||
)
|
||||
if not found:
|
||||
logger.warning('User [%s] not found!' % username)
|
||||
return False
|
||||
@@ -502,8 +509,8 @@ def ldap_auth(server='ldap', port=None,
|
||||
'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) &
|
||||
(db.auth_group.id == db.auth_membership.group_id))
|
||||
(db.auth_user.id == db.auth_membership.user_id) &
|
||||
(db.auth_group.id == db.auth_membership.group_id))
|
||||
db_groups_of_the_user = list()
|
||||
db_group_id = dict()
|
||||
|
||||
@@ -522,7 +529,8 @@ def ldap_auth(server='ldap', port=None,
|
||||
for group_to_del in db_groups_of_the_user:
|
||||
if ldap_groups_of_the_user.count(group_to_del) == 0:
|
||||
db((db.auth_membership.user_id == db_user_id) &
|
||||
(db.auth_membership.group_id == db_group_id[group_to_del])).delete()
|
||||
(db.auth_membership.group_id == \
|
||||
db_group_id[group_to_del])).delete()
|
||||
|
||||
#
|
||||
# Create user membership in groups where user is not in already
|
||||
@@ -531,7 +539,7 @@ def ldap_auth(server='ldap', port=None,
|
||||
if db_groups_of_the_user.count(group_to_add) == 0:
|
||||
if db(db.auth_group.role == group_to_add).count() == 0:
|
||||
gid = db.auth_group.insert(role=group_to_add,
|
||||
description='Generated from LDAP')
|
||||
description='Generated from LDAP')
|
||||
else:
|
||||
gid = db(db.auth_group.role == group_to_add).select(
|
||||
db.auth_group.id).first().id
|
||||
@@ -608,7 +616,8 @@ def ldap_auth(server='ldap', port=None,
|
||||
con.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
|
||||
# In cases where ForestDnsZones and DomainDnsZones are found,
|
||||
# result will look like the following:
|
||||
# ['ldap://ForestDnsZones.domain.com/DC=ForestDnsZones,DC=domain,DC=com']
|
||||
# ['ldap://ForestDnsZones.domain.com/DC=ForestDnsZones,
|
||||
# DC=domain,DC=com']
|
||||
if ldap_binddn:
|
||||
# need to search directory with an admin account 1st
|
||||
con.simple_bind_s(ldap_binddn, ldap_bindpw)
|
||||
@@ -620,7 +629,8 @@ def ldap_auth(server='ldap', port=None,
|
||||
# We have to use the full string
|
||||
username = con.search_ext_s(base_dn, ldap.SCOPE_SUBTREE,
|
||||
"(&(sAMAccountName=%s)(%s))" %
|
||||
(ldap.filter.escape_filter_chars(username_bare), filterstr), ["cn"])[0][0]
|
||||
(ldap.filter.escape_filter_chars(username_bare),
|
||||
filterstr), ["cn"])[0][0]
|
||||
else:
|
||||
if ldap_binddn:
|
||||
# need to search directory with an bind_dn account 1st
|
||||
@@ -630,7 +640,9 @@ def ldap_auth(server='ldap', port=None,
|
||||
con.simple_bind_s('', '')
|
||||
|
||||
# search for groups where user is in
|
||||
filter = '(&(%s=%s)(%s))' % (ldap.filter.escape_filter_chars(group_member_attrib),
|
||||
filter = '(&(%s=%s)(%s))' % (ldap.filter.escape_filter_chars(
|
||||
group_member_attrib
|
||||
),
|
||||
ldap.filter.escape_filter_chars(username),
|
||||
group_filterstr)
|
||||
group_search_result = con.search_s(group_dn,
|
||||
@@ -648,3 +660,4 @@ 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
|
||||
|
||||
|
||||
@@ -1262,8 +1262,9 @@ def render(text,
|
||||
t = t or ''
|
||||
a = escape(a) if a else ''
|
||||
if k:
|
||||
if k.startswith('#'):
|
||||
k = '#'+id_prefix+k[1:]
|
||||
if '#' in k and not ':' in k.split('#')[0]:
|
||||
# wikipage, not external url
|
||||
k=k.replace('#','#'+id_prefix)
|
||||
k = escape(k)
|
||||
title = ' title="%s"' % a.replace(META, DISABLED_META) if a else ''
|
||||
target = ' target="_blank"' if p == 'popup' else ''
|
||||
|
||||
+297
-266
File diff suppressed because it is too large
Load Diff
+4
-1
@@ -388,7 +388,10 @@ class Response(Storage):
|
||||
if not items:
|
||||
raise HTTP(404)
|
||||
(t, f) = (items.group('table'), items.group('field'))
|
||||
field = db[t][f]
|
||||
try:
|
||||
field = db[t][f]
|
||||
except AttributeError:
|
||||
raise HTTP(404)
|
||||
try:
|
||||
(filename, stream) = field.retrieve(name)
|
||||
except IOError:
|
||||
|
||||
+3
-2
@@ -1482,8 +1482,9 @@ class A(DIV):
|
||||
(self['callback'], self['target'] or '', d)
|
||||
self['_href'] = self['_href'] or '#null'
|
||||
elif self['cid']:
|
||||
self['_onclick'] = 'web2py_component("%s","%s");%sreturn false;' % \
|
||||
(self['_href'], self['cid'], d)
|
||||
pre = self['pre_call'] + ';' if self['pre_call'] else ''
|
||||
self['_onclick'] = '%sweb2py_component("%s","%s");%sreturn false;' % \
|
||||
(pre,self['_href'], self['cid'], d)
|
||||
return DIV.xml(self)
|
||||
|
||||
|
||||
|
||||
+38
-30
@@ -12,17 +12,24 @@ Plural subsystem is created by Vladyslav Kozlovskyy (Ukraine)
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import pkgutil
|
||||
from utf8 import Utf8
|
||||
from cgi import escape
|
||||
import portalocker
|
||||
import logging
|
||||
import marshal
|
||||
import copy_reg
|
||||
from cgi import escape
|
||||
from threading import RLock
|
||||
|
||||
try:
|
||||
import copyreg as copy_reg # python 3
|
||||
except ImportError:
|
||||
import copy_reg # python 2
|
||||
|
||||
from portalocker import read_locked, LockedFile
|
||||
from utf8 import Utf8
|
||||
|
||||
from fileutils import listdir
|
||||
import settings
|
||||
from cfs import getcfs
|
||||
from thread import allocate_lock
|
||||
from html import XML, xmlescape
|
||||
from contrib.markmin.markmin2html import render, markmin_escape
|
||||
from string import maketrans
|
||||
@@ -35,7 +42,7 @@ pjoin = os.path.join
|
||||
pexists = os.path.exists
|
||||
pdirname = os.path.dirname
|
||||
isdir = os.path.isdir
|
||||
is_gae = settings.global_settings.web2py_runtime_gae
|
||||
is_gae = False # settings.global_settings.web2py_runtime_gae
|
||||
|
||||
DEFAULT_LANGUAGE = 'en'
|
||||
DEFAULT_LANGUAGE_NAME = 'English'
|
||||
@@ -137,7 +144,7 @@ def get_from_cache(cache, val, fun):
|
||||
|
||||
def clear_cache(filename):
|
||||
cache = global_language_cache.setdefault(
|
||||
filename, ({}, allocate_lock()))
|
||||
filename, ({}, RLock()))
|
||||
lang_dict, lock = cache
|
||||
lock.acquire()
|
||||
try:
|
||||
@@ -147,11 +154,12 @@ def clear_cache(filename):
|
||||
|
||||
|
||||
def read_dict_aux(filename):
|
||||
lang_text = portalocker.read_locked(filename).replace('\r\n', '\n')
|
||||
lang_text = read_locked(filename).replace('\r\n', '\n')
|
||||
clear_cache(filename)
|
||||
try:
|
||||
return safe_eval(lang_text) or {}
|
||||
except Exception, e:
|
||||
except Exception:
|
||||
e = sys.exc_info()[1]
|
||||
status = 'Syntax error in %s (%s)' % (filename, e)
|
||||
logging.error(status)
|
||||
return {'__corrupted__': status}
|
||||
@@ -187,7 +195,8 @@ def read_possible_plural_rules():
|
||||
DEFAULT_CONSTRUCT_PLURAL_FORM)
|
||||
plurals[lang] = (lang, nplurals, get_plural_id,
|
||||
construct_plural_form)
|
||||
except ImportError, e:
|
||||
except ImportError:
|
||||
e = sys.exc_info()[1]
|
||||
logging.warn('Unable to import plural rules: %s' % e)
|
||||
return plurals
|
||||
|
||||
@@ -261,17 +270,17 @@ def read_possible_languages_aux(langdir):
|
||||
return langs
|
||||
|
||||
|
||||
def read_possible_languages(appdir):
|
||||
langdir = pjoin(appdir, 'languages')
|
||||
return getcfs('langs:' + langdir, langdir,
|
||||
lambda: read_possible_languages_aux(langdir))
|
||||
def read_possible_languages(langpath):
|
||||
return getcfs('langs:' + langpath, langpath,
|
||||
lambda: read_possible_languages_aux(langpath))
|
||||
|
||||
|
||||
def read_plural_dict_aux(filename):
|
||||
lang_text = portalocker.read_locked(filename).replace('\r\n', '\n')
|
||||
lang_text = read_locked(filename).replace('\r\n', '\n')
|
||||
try:
|
||||
return eval(lang_text) or {}
|
||||
except Exception, e:
|
||||
except Exception:
|
||||
e = sys.exc_info()[1]
|
||||
status = 'Syntax error in %s (%s)' % (filename, e)
|
||||
logging.error(status)
|
||||
return {'__corrupted__': status}
|
||||
@@ -286,7 +295,7 @@ def write_plural_dict(filename, contents):
|
||||
if '__corrupted__' in contents:
|
||||
return
|
||||
try:
|
||||
fp = portalocker.LockedFile(filename, 'w')
|
||||
fp = LockedFile(filename, 'w')
|
||||
fp.write('#!/usr/bin/env python\n{\n# "singular form (0)": ["first plural form (1)", "second plural form (2)", ...],\n')
|
||||
# coding: utf8\n{\n')
|
||||
for key in sorted(contents, lambda x, y: cmp(unicode(x, 'utf-8').lower(), unicode(y, 'utf-8').lower())):
|
||||
@@ -306,7 +315,7 @@ def write_dict(filename, contents):
|
||||
if '__corrupted__' in contents:
|
||||
return
|
||||
try:
|
||||
fp = portalocker.LockedFile(filename, 'w')
|
||||
fp = LockedFile(filename, 'w')
|
||||
except (IOError, OSError):
|
||||
if not settings.global_settings.web2py_runtime_gae:
|
||||
logging.warning('Unable to write to file %s' % filename)
|
||||
@@ -434,11 +443,9 @@ class translator(object):
|
||||
xx-yy.py -> xx.py -> xx-yy*.py -> xx*.py
|
||||
"""
|
||||
|
||||
def __init__(self, request):
|
||||
self.request = request
|
||||
self.folder = request.folder
|
||||
self.langpath = pjoin(self.folder, 'languages')
|
||||
self.http_accept_language = request.env.http_accept_language
|
||||
def __init__(self, langpath, http_accept_language):
|
||||
self.langpath = langpath
|
||||
self.http_accept_language = http_accept_language
|
||||
self.is_writable = not is_gae
|
||||
# filled in self.force():
|
||||
#------------------------
|
||||
@@ -493,7 +500,7 @@ class translator(object):
|
||||
construct_plural_form) # construct_plural_form() for current language
|
||||
}
|
||||
"""
|
||||
info = read_possible_languages(self.folder)
|
||||
info = read_possible_languages(self.langpath)
|
||||
if lang:
|
||||
info = info.get(lang)
|
||||
return info
|
||||
@@ -501,7 +508,7 @@ class translator(object):
|
||||
def get_possible_languages(self):
|
||||
""" get list of all possible languages for current applications """
|
||||
return list(set(self.current_languages +
|
||||
[lang for lang in read_possible_languages(self.folder).iterkeys()
|
||||
[lang for lang in read_possible_languages(self.langpath).iterkeys()
|
||||
if lang != 'default']))
|
||||
|
||||
def set_current_languages(self, *languages):
|
||||
@@ -581,7 +588,7 @@ class translator(object):
|
||||
default language will be selected if none
|
||||
of them matches possible_languages.
|
||||
"""
|
||||
pl_info = read_possible_languages(self.folder)
|
||||
pl_info = read_possible_languages(self.langpath)
|
||||
|
||||
def set_plural(language):
|
||||
"""
|
||||
@@ -642,14 +649,14 @@ class translator(object):
|
||||
self.t = read_dict(self.language_file)
|
||||
self.cache = global_language_cache.setdefault(
|
||||
self.language_file,
|
||||
({}, allocate_lock()))
|
||||
({}, RLock()))
|
||||
set_plural(language)
|
||||
self.accepted_language = language
|
||||
return languages
|
||||
self.accepted_language = language or self.current_languages[0]
|
||||
self.language_file = self.default_language_file
|
||||
self.cache = global_language_cache.setdefault(self.language_file,
|
||||
({}, allocate_lock()))
|
||||
({}, RLock()))
|
||||
self.t = self.default_t
|
||||
set_plural(self.accepted_language)
|
||||
return languages
|
||||
@@ -670,7 +677,8 @@ class translator(object):
|
||||
try:
|
||||
otherT = self.otherTs[language]
|
||||
except KeyError:
|
||||
otherT = self.otherTs[language] = translator(self.request)
|
||||
otherT = self.otherTs[language] = translator(
|
||||
self.langpath, self.http_accept_language)
|
||||
otherT.force(language)
|
||||
return otherT(message, symbols, lazy=lazy)
|
||||
|
||||
@@ -892,7 +900,7 @@ def findT(path, language=DEFAULT_LANGUAGE):
|
||||
for filename in \
|
||||
listdir(mp, '^.+\.py$', 0) + listdir(cp, '^.+\.py$', 0)\
|
||||
+ listdir(vp, '^.+\.html$', 0) + listdir(mop, '^.+\.py$', 0):
|
||||
data = portalocker.read_locked(filename)
|
||||
data = read_locked(filename)
|
||||
items = regex_translate.findall(data)
|
||||
for item in items:
|
||||
try:
|
||||
|
||||
+1
-1
@@ -460,7 +460,7 @@ def wsgibase(environ, responder):
|
||||
is_https=env.wsgi_url_scheme in HTTPS_SCHEMES
|
||||
or request.env.http_x_forwarded_proto in HTTPS_SCHEMES
|
||||
or env.https == 'on')
|
||||
request.uuid = request.compute_uuid() # requires client
|
||||
request.compute_uuid() # requires client
|
||||
request.url = environ['PATH_INFO']
|
||||
|
||||
# ##################################################
|
||||
|
||||
@@ -167,5 +167,5 @@ if __name__ == '__main__':
|
||||
f.write('test ok')
|
||||
f.close()
|
||||
f = LockedFile('test.txt', mode='rb')
|
||||
print f.read()
|
||||
sys.stdout.write(f.read()+'\n')
|
||||
f.close()
|
||||
|
||||
+3
-3
@@ -1192,7 +1192,7 @@ re_REQUEST_LINE = re.compile(r"""^
|
||||
(?P<host>[^/]+) # Host
|
||||
)? #
|
||||
(?P<path>(\*|/[^ \?]*)) # Path
|
||||
(\? (?P<query_string>[^ ]+))? # Query String
|
||||
(\? (?P<query_string>[^ ]*))? # Query String
|
||||
\ # (single space)
|
||||
(?P<protocol>HTTPS?/1\.[01]) # Protocol
|
||||
$
|
||||
@@ -1670,8 +1670,8 @@ class WSGIWorker(Worker):
|
||||
peercert = conn.socket.getpeercert(binary_form=True)
|
||||
environ['SSL_CLIENT_RAW_CERT'] = \
|
||||
peercert and ssl.DER_cert_to_PEM_cert(peercert)
|
||||
except Exception, e:
|
||||
print e
|
||||
except Exception:
|
||||
print sys.exc_info()[1]
|
||||
|
||||
if environ.get('HTTP_TRANSFER_ENCODING', '') == 'chunked':
|
||||
environ['wsgi.input'] = ChunkedReader(sock_file)
|
||||
|
||||
+6
-6
@@ -63,7 +63,6 @@ import os
|
||||
import time
|
||||
import multiprocessing
|
||||
import sys
|
||||
import cStringIO
|
||||
import threading
|
||||
import traceback
|
||||
import signal
|
||||
@@ -206,7 +205,6 @@ def executor(queue, task, out):
|
||||
if task.app:
|
||||
os.chdir(os.environ['WEB2PY_PATH'])
|
||||
from gluon.shell import env, parse_path_info
|
||||
from gluon.dal import BaseAdapter
|
||||
from gluon import current
|
||||
level = logging.getLogger().getEffectiveLevel()
|
||||
logging.getLogger().setLevel(logging.WARN)
|
||||
@@ -788,9 +786,9 @@ class Scheduler(MetaScheduler):
|
||||
#the scheduler): then it wasn't expired, but now it is
|
||||
db(st.status.belongs(
|
||||
(QUEUED, ASSIGNED)))(st.stop_time < now).update(status=EXPIRED)
|
||||
|
||||
|
||||
all_available = db(st.status.belongs((QUEUED, ASSIGNED)))((st.times_run < st.repeats) | (st.repeats == 0))(st.start_time <= now)((st.stop_time == None) | (st.stop_time > now))(st.next_run_time <= now)(st.enabled == True)
|
||||
limit = len(all_workers) * (50 / len(wkgroups))
|
||||
limit = len(all_workers) * (50 / (len(wkgroups) or 1))
|
||||
#if there are a moltitude of tasks, let's figure out a maximum of tasks per worker.
|
||||
#this can be adjusted with some added intelligence (like esteeming how many tasks will
|
||||
#a worker complete before the ticker reassign them around, but the gain is quite small
|
||||
@@ -804,11 +802,13 @@ class Scheduler(MetaScheduler):
|
||||
|
||||
#let's freeze it up
|
||||
db.commit()
|
||||
x = 0
|
||||
for group in wkgroups.keys():
|
||||
tasks = all_available(st.group_name==group).select(
|
||||
limitby=(0, limit), orderby=st.next_run_time)
|
||||
#let's break up the queue evenly among workers
|
||||
for task in tasks:
|
||||
x += 1
|
||||
gname = task.group_name
|
||||
ws = wkgroups.get(gname)
|
||||
if ws:
|
||||
@@ -827,10 +827,10 @@ class Scheduler(MetaScheduler):
|
||||
|
||||
db.commit()
|
||||
#I didn't report tasks but I'm working nonetheless!!!!
|
||||
if len(tasks) > 0:
|
||||
if x > 0:
|
||||
self.empty_runs = 0
|
||||
logger.info('TICKER: workers are %s' % len(all_workers))
|
||||
logger.info('TICKER: tasks are %s' % len(tasks))
|
||||
logger.info('TICKER: tasks are %s' % x)
|
||||
|
||||
def sleep(self):
|
||||
time.sleep(self.heartbeat * self.worker_status[1])
|
||||
|
||||
+1
-1
@@ -1581,7 +1581,7 @@ class SQLFORM(FORM):
|
||||
label = isinstance(
|
||||
field.label, str) and T(field.label) or field.label
|
||||
selectfields.append(OPTION(label, _value=str(field)))
|
||||
operators = SELECT(*[T(option) for option in options])
|
||||
operators = SELECT(*[OPTION(T(option), _value=option) for option in options])
|
||||
if field.type == 'boolean':
|
||||
value_input = SELECT(
|
||||
OPTION(T("True"), _value="T"),
|
||||
|
||||
+10
-6
@@ -16,9 +16,13 @@ Contributors:
|
||||
|
||||
import os
|
||||
import cgi
|
||||
import cStringIO
|
||||
import logging
|
||||
from re import compile, sub, escape, DOTALL
|
||||
try:
|
||||
import cStringIO as StringIO
|
||||
except:
|
||||
from io import StringIO
|
||||
|
||||
try:
|
||||
# have web2py
|
||||
from restricted import RestrictedError
|
||||
@@ -791,13 +795,13 @@ def get_parsed(text):
|
||||
|
||||
class DummyResponse():
|
||||
def __init__(self):
|
||||
self.body = cStringIO.StringIO()
|
||||
self.body = StringIO.StringIO()
|
||||
|
||||
def write(self, data, escape=True):
|
||||
if not escape:
|
||||
self.body.write(str(data))
|
||||
elif hasattr(data, 'xml') and callable(data.xml):
|
||||
self.body.write(data.xml())
|
||||
elif hasattr(data, 'as_html') and callable(data.as_html):
|
||||
self.body.write(data.as_html())
|
||||
else:
|
||||
# make it a string
|
||||
if not isinstance(data, (str, unicode)):
|
||||
@@ -870,7 +874,7 @@ def render(content="hello world",
|
||||
# save current response class
|
||||
if context and 'response' in context:
|
||||
old_response_body = context['response'].body
|
||||
context['response'].body = cStringIO.StringIO()
|
||||
context['response'].body = StringIO.StringIO()
|
||||
else:
|
||||
old_response_body = None
|
||||
context['response'] = Response()
|
||||
@@ -887,7 +891,7 @@ def render(content="hello world",
|
||||
stream = open(filename, 'rb')
|
||||
close_stream = True
|
||||
elif content:
|
||||
stream = cStringIO.StringIO(content)
|
||||
stream = StringIO.StringIO(content)
|
||||
|
||||
# Execute the template.
|
||||
code = str(TemplateParser(stream.read(
|
||||
|
||||
@@ -13,7 +13,10 @@ else:
|
||||
|
||||
import unittest
|
||||
import datetime
|
||||
import cStringIO
|
||||
try:
|
||||
import cStringIO as StringIO
|
||||
except:
|
||||
from io import StringIO
|
||||
from dal import DAL, Field, Table, SQLALL
|
||||
|
||||
ALLOWED_DATATYPES = [
|
||||
@@ -555,11 +558,11 @@ class TestImportExportFields(unittest.TestCase):
|
||||
id = db.person.insert(name=str(k))
|
||||
db.pet.insert(friend=id,name=str(k))
|
||||
db.commit()
|
||||
stream = cStringIO.StringIO()
|
||||
stream = StringIO.StringIO()
|
||||
db.export_to_csv_file(stream)
|
||||
db(db.pet).delete()
|
||||
db(db.person).delete()
|
||||
stream = cStringIO.StringIO(stream.getvalue())
|
||||
stream = StringIO.StringIO(stream.getvalue())
|
||||
db.import_from_csv_file(stream)
|
||||
assert db(db.person.id==db.pet.friend)(db.person.name==db.pet.name).count()==10
|
||||
db.pet.drop()
|
||||
@@ -579,9 +582,9 @@ class TestImportExportUuidFields(unittest.TestCase):
|
||||
id = db.person.insert(name=str(k),uuid=str(k))
|
||||
db.pet.insert(friend=id,name=str(k))
|
||||
db.commit()
|
||||
stream = cStringIO.StringIO()
|
||||
stream = StringIO.StringIO()
|
||||
db.export_to_csv_file(stream)
|
||||
stream = cStringIO.StringIO(stream.getvalue())
|
||||
stream = StringIO.StringIO(stream.getvalue())
|
||||
db.import_from_csv_file(stream)
|
||||
assert db(db.person).count()==10
|
||||
assert db(db.person.id==db.pet.friend)(db.person.name==db.pet.name).count()==20
|
||||
|
||||
@@ -57,20 +57,18 @@ try:
|
||||
class TestTranslations(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.request = Storage()
|
||||
if os.path.isdir('gluon'):
|
||||
self.request.folder = 'applications/welcome'
|
||||
self.langpath = 'applications/welcome/languages'
|
||||
else:
|
||||
self.request.folder = os.path.realpath(
|
||||
'../../applications/welcome')
|
||||
self.request.env = Storage()
|
||||
self.request.env.http_accept_language = 'en'
|
||||
self.langpath = os.path.realpath(
|
||||
'../../applications/welcome/languages')
|
||||
self.http_accept_language = 'en'
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def test_plain(self):
|
||||
T = languages.translator(self.request)
|
||||
T = languages.translator(self.langpath, self.http_accept_language)
|
||||
self.assertEqual(str(T('Hello World')),
|
||||
'Hello World')
|
||||
self.assertEqual(str(T('Hello World## comment')),
|
||||
|
||||
+24
-23
@@ -5035,30 +5035,31 @@ class Wiki(object):
|
||||
if True:
|
||||
submenu = []
|
||||
menu.append((current.T('[Wiki]'), None, None, submenu))
|
||||
if URL() == URL(controller, function):
|
||||
if not str(request.args(0)).startswith('_'):
|
||||
slug = request.args(0) or 'index'
|
||||
mode = 1
|
||||
elif request.args(0) == '_edit':
|
||||
slug = request.args(1) or 'index'
|
||||
mode = 2
|
||||
elif request.args(0) == '_editmedia':
|
||||
slug = request.args(1) or 'index'
|
||||
mode = 3
|
||||
else:
|
||||
mode = 0
|
||||
if mode in (2, 3):
|
||||
submenu.append((current.T('View Page'), None,
|
||||
URL(controller, function, args=slug)))
|
||||
if mode in (1, 3):
|
||||
submenu.append((current.T('Edit Page'), None,
|
||||
URL(controller, function, args=('_edit', slug))))
|
||||
if mode in (1, 2):
|
||||
submenu.append((current.T('Edit Page Media'), None,
|
||||
URL(controller, function, args=('_editmedia', slug))))
|
||||
if self.auth.user:
|
||||
if URL() == URL(controller, function):
|
||||
if not str(request.args(0)).startswith('_'):
|
||||
slug = request.args(0) or 'index'
|
||||
mode = 1
|
||||
elif request.args(0) == '_edit':
|
||||
slug = request.args(1) or 'index'
|
||||
mode = 2
|
||||
elif request.args(0) == '_editmedia':
|
||||
slug = request.args(1) or 'index'
|
||||
mode = 3
|
||||
else:
|
||||
mode = 0
|
||||
if mode in (2, 3):
|
||||
submenu.append((current.T('View Page'), None,
|
||||
URL(controller, function, args=slug)))
|
||||
if mode in (1, 3):
|
||||
submenu.append((current.T('Edit Page'), None,
|
||||
URL(controller, function, args=('_edit', slug))))
|
||||
if mode in (1, 2):
|
||||
submenu.append((current.T('Edit Page Media'), None,
|
||||
URL(controller, function, args=('_editmedia', slug))))
|
||||
|
||||
submenu.append((current.T('Create New Page'), None,
|
||||
URL(controller, function, args=('_create'))))
|
||||
submenu.append((current.T('Create New Page'), None,
|
||||
URL(controller, function, args=('_create'))))
|
||||
if self.can_manage():
|
||||
submenu.append((current.T('Manage Pages'), None,
|
||||
URL(controller, function, args=('_pages'))))
|
||||
|
||||
+30
-9
@@ -19,22 +19,37 @@ import random
|
||||
import time
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import logging
|
||||
import socket
|
||||
import cPickle
|
||||
import base64
|
||||
import zlib
|
||||
|
||||
python_version = sys.version_info[0]
|
||||
|
||||
if python_version == 2:
|
||||
import cPickle as pickle
|
||||
else:
|
||||
import pickle
|
||||
|
||||
|
||||
try:
|
||||
from Crypto.Cipher import AES
|
||||
except ImportError:
|
||||
from contrib import aes as AES
|
||||
try:
|
||||
from .aes import AES
|
||||
except (ImportError, ValueError):
|
||||
from contrib.aes import AES
|
||||
|
||||
try:
|
||||
from contrib.pbkdf2 import pbkdf2_hex
|
||||
HAVE_PBKDF2 = True
|
||||
except ImportError:
|
||||
HAVE_PBKDF2 = False
|
||||
try:
|
||||
from .pbkdf2 import pbkdf2_hex
|
||||
HAVE_PBKDF2 = True
|
||||
except (ImportError, ValueError):
|
||||
HAVE_PBKDF2 = False
|
||||
|
||||
logger = logging.getLogger("web2py")
|
||||
|
||||
@@ -115,7 +130,7 @@ def pad(s, n=32, padchar='.'):
|
||||
def secure_dumps(data, encryption_key, hash_key=None, compression_level=None):
|
||||
if not hash_key:
|
||||
hash_key = hashlib.sha1(encryption_key).hexdigest()
|
||||
dump = cPickle.dumps(data)
|
||||
dump = pickle.dumps(data)
|
||||
if compression_level:
|
||||
dump = zlib.compress(dump, compression_level)
|
||||
key = pad(encryption_key[:32])
|
||||
@@ -141,8 +156,8 @@ def secure_loads(data, encryption_key, hash_key=None, compression_level=None):
|
||||
data = data.rstrip(' ')
|
||||
if compression_level:
|
||||
data = zlib.decompress(data)
|
||||
return cPickle.loads(data)
|
||||
except (TypeError, cPickle.UnpicklingError):
|
||||
return pickle.loads(data)
|
||||
except (TypeError, pickle.UnpicklingError):
|
||||
return None
|
||||
|
||||
### compute constant CTOKENS
|
||||
@@ -173,7 +188,10 @@ def initialize_urandom():
|
||||
# try to add process-specific entropy
|
||||
frandom = open('/dev/urandom', 'wb')
|
||||
try:
|
||||
frandom.write(''.join(chr(t) for t in ctokens))
|
||||
if python_version == 2:
|
||||
frandom.write(''.join(chr(t) for t in ctokens)) # python 2
|
||||
else:
|
||||
frandom.write(bytes([]).join(bytes([t]) for t in ctokens)) # python 3
|
||||
finally:
|
||||
frandom.close()
|
||||
except IOError:
|
||||
@@ -185,8 +203,11 @@ def initialize_urandom():
|
||||
"""Cryptographically secure session management is not possible on your system because
|
||||
your system does not provide a cryptographically secure entropy source.
|
||||
This is not specific to web2py; consider deploying on a different operating system.""")
|
||||
unpacked_ctokens = struct.unpack('=QQ', string.join(
|
||||
(chr(x) for x in ctokens), ''))
|
||||
if python_version == 2:
|
||||
packed = ''.join(chr(x) for x in ctokens) # python 2
|
||||
else:
|
||||
packed = bytes([]).join(bytes([x]) for x in ctokens) # python 3
|
||||
unpacked_ctokens = struct.unpack('=QQ', packed)
|
||||
return unpacked_ctokens, have_urandom
|
||||
UNPACKED_CTOKENS, HAVE_URANDOM = initialize_urandom()
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ Typical usage:
|
||||
"""
|
||||
|
||||
from __future__ import with_statement
|
||||
from gluon import current
|
||||
from gluon.storage import Storage
|
||||
from optparse import OptionParser
|
||||
import cPickle
|
||||
@@ -93,10 +94,7 @@ class SessionSetDb(SessionSet):
|
||||
def get(self):
|
||||
"""Return list of SessionDb instances for existing sessions."""
|
||||
sessions = []
|
||||
tablename = 'web2py_session'
|
||||
from gluon import current
|
||||
(record_id_name, table, record_id, unique_key) = \
|
||||
current.response._dbtable_and_field
|
||||
table = current.response.session_db_table
|
||||
for row in table._db(table.id > 0).select():
|
||||
sessions.append(SessionDb(row))
|
||||
return sessions
|
||||
@@ -121,9 +119,7 @@ class SessionDb(object):
|
||||
self.row = row
|
||||
|
||||
def delete(self):
|
||||
from gluon import current
|
||||
(record_id_name, table, record_id, unique_key) = \
|
||||
current.response._dbtable_and_field
|
||||
table = current.response.session_db_table
|
||||
self.row.delete_record()
|
||||
table._db.commit()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user