Compare commits
64
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f31c9002f7 | ||
|
|
6354fbedf8 | ||
|
|
cc11a14ce3 | ||
|
|
2fa9597cd8 | ||
|
|
c9d656ea45 | ||
|
|
1eec01b830 | ||
|
|
c10983b191 | ||
|
|
975ab7b923 | ||
|
|
16f60d5cff | ||
|
|
930370ee91 | ||
|
|
215abc9e4f | ||
|
|
b6e5e16526 | ||
|
|
b2548f5631 | ||
|
|
f14c384d83 | ||
|
|
9f186e5d5d | ||
|
|
51dd427b9e | ||
|
|
7b3fe560ed | ||
|
|
bd526452a8 | ||
|
|
d862da3543 | ||
|
|
0165cfadef | ||
|
|
46b7716b1d | ||
|
|
7e5277030a | ||
|
|
b2e03c9dee | ||
|
|
0644df5283 | ||
|
|
4acd9f8f2b | ||
|
|
ce0c5f2d5a | ||
|
|
28b0385d9b | ||
|
|
ac9bccb9a2 | ||
|
|
aa5b40528f | ||
|
|
96efc7bfce | ||
|
|
aa584faed6 | ||
|
|
e7cab3b975 | ||
|
|
867f93b634 | ||
|
|
efff27ffe4 | ||
|
|
637579f531 | ||
|
|
52fe4407b8 | ||
|
|
fc0add67b5 | ||
|
|
3d2834c81a | ||
|
|
0b8ecea4dc | ||
|
|
67945c2d5c | ||
|
|
c600854f4b | ||
|
|
2c70a858f1 | ||
|
|
ad9ebea900 | ||
|
|
c72330f2cd | ||
|
|
091d9c74b0 | ||
|
|
bebdbd9d5e | ||
|
|
05e28ddffd | ||
|
|
e19435dbcf | ||
|
|
90ee6f3754 | ||
|
|
d51ea90e18 | ||
|
|
3fed558bdd | ||
|
|
870d9d3e57 | ||
|
|
0a07af55f9 | ||
|
|
f7adfbde76 | ||
|
|
75c1d80824 | ||
|
|
c64a9192d4 | ||
|
|
8e79e49ae3 | ||
|
|
46ce04355f | ||
|
|
6b1225da02 | ||
|
|
4ea31820aa | ||
|
|
8e1630843a | ||
|
|
2d4817841f | ||
|
|
4226b6d0e1 | ||
|
|
3e2b8f89aa |
@@ -13,6 +13,7 @@
|
|||||||
*.orig
|
*.orig
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
*.DS_Store
|
||||||
index.yaml
|
index.yaml
|
||||||
routes.py
|
routes.py
|
||||||
logging.conf
|
logging.conf
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
language: python
|
language: python
|
||||||
|
|
||||||
sudo: false
|
sudo: required
|
||||||
|
|
||||||
cache: pip
|
cache: pip
|
||||||
|
|
||||||
|
|||||||
@@ -465,6 +465,7 @@ def ccache():
|
|||||||
ram['keys'].append((key, GetInHMS(time.time() - value[0])))
|
ram['keys'].append((key, GetInHMS(time.time() - value[0])))
|
||||||
|
|
||||||
for key in cache.disk.storage:
|
for key in cache.disk.storage:
|
||||||
|
value = cache.disk.storage[key]
|
||||||
if key == 'web2py_cache_statistics' and isinstance(value[1], dict):
|
if key == 'web2py_cache_statistics' and isinstance(value[1], dict):
|
||||||
disk['hits'] = value[1]['hit_total'] - value[1]['misses']
|
disk['hits'] = value[1]['hit_total'] - value[1]['misses']
|
||||||
disk['misses'] = value[1]['misses']
|
disk['misses'] = value[1]['misses']
|
||||||
|
|||||||
@@ -1960,7 +1960,7 @@ def git_push():
|
|||||||
|
|
||||||
def plugins():
|
def plugins():
|
||||||
app = request.args(0)
|
app = request.args(0)
|
||||||
from serializers import loads_json
|
from gluon.serializers import loads_json
|
||||||
if not session.plugins:
|
if not session.plugins:
|
||||||
try:
|
try:
|
||||||
rawlist = urlopen("http://www.web2pyslices.com/" +
|
rawlist = urlopen("http://www.web2pyslices.com/" +
|
||||||
|
|||||||
@@ -352,9 +352,9 @@
|
|||||||
'modules': 'modules',
|
'modules': 'modules',
|
||||||
'Multi User Mode': 'Multi User Mode',
|
'Multi User Mode': 'Multi User Mode',
|
||||||
'Must include at least %s %s': 'Moet ten minste bevatten %s %s',
|
'Must include at least %s %s': 'Moet ten minste bevatten %s %s',
|
||||||
'Must include at least %s lower case': 'Moet ten minste bevatten %s lower case',
|
'Must include at least %s lowercase': 'Moet ten minste bevatten %s kleine letter',
|
||||||
'Must include at least %s of the following : %s': 'Moet ten minste bevatten %s van het volgende : %s',
|
'Must include at least %s of the following : %s': 'Moet ten minste bevatten %s van het volgende : %s',
|
||||||
'Must include at least %s upper case': 'Moet ten minste bevatten %s upper case',
|
'Must include at least %s uppercase': 'Moet ten minste bevatten %s hoofdletter',
|
||||||
'new application "%s" created': 'nieuwe applicatie "%s" gemaakt',
|
'new application "%s" created': 'nieuwe applicatie "%s" gemaakt',
|
||||||
'new application "%s" imported': 'new application "%s" imported',
|
'new application "%s" imported': 'new application "%s" imported',
|
||||||
'New Application Wizard': 'Nieuwe Applicatie Wizard',
|
'New Application Wizard': 'Nieuwe Applicatie Wizard',
|
||||||
|
|||||||
@@ -356,9 +356,9 @@
|
|||||||
'modules': 'модулі',
|
'modules': 'модулі',
|
||||||
'Multi User Mode': 'Multi User Mode',
|
'Multi User Mode': 'Multi User Mode',
|
||||||
'Must include at least %s %s': 'Має вміщувати щонайменше %s %s',
|
'Must include at least %s %s': 'Має вміщувати щонайменше %s %s',
|
||||||
'Must include at least %s lower case': 'Повинен включати щонайменше %s малих букв',
|
'Must include at least %s lowercase': 'Повинен включати щонайменше %s малих букв',
|
||||||
'Must include at least %s of the following : %s': 'Має включати не менше %s таких символів : %s',
|
'Must include at least %s of the following : %s': 'Має включати не менше %s таких символів : %s',
|
||||||
'Must include at least %s upper case': 'Повинен включати щонайменше %s великих букв',
|
'Must include at least %s uppercase': 'Повинен включати щонайменше %s великих букв',
|
||||||
'new application "%s" created': 'новий додаток "%s" створено',
|
'new application "%s" created': 'новий додаток "%s" створено',
|
||||||
'new application "%s" imported': 'new application "%s" imported',
|
'new application "%s" imported': 'new application "%s" imported',
|
||||||
'New Application Wizard': 'Майстер створення нового додатку',
|
'New Application Wizard': 'Майстер створення нового додатку',
|
||||||
|
|||||||
+3
-3
@@ -314,8 +314,8 @@
|
|||||||
// Vim does not support modifier only keys.
|
// Vim does not support modifier only keys.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// TODO: Current bindings expect the character to be lower case, but
|
// TODO: Current bindings expect the character to be lowercase, but
|
||||||
// it looks like vim key notation uses upper case.
|
// it looks like vim key notation uses uppercase.
|
||||||
if (isUpperCase(lastPiece)) {
|
if (isUpperCase(lastPiece)) {
|
||||||
pieces[pieces.length - 1] = lastPiece.toLowerCase();
|
pieces[pieces.length - 1] = lastPiece.toLowerCase();
|
||||||
}
|
}
|
||||||
@@ -3644,7 +3644,7 @@
|
|||||||
* Extract the regular expression from the query and return a Regexp object.
|
* Extract the regular expression from the query and return a Regexp object.
|
||||||
* Returns null if the query is blank.
|
* Returns null if the query is blank.
|
||||||
* If ignoreCase is passed in, the Regexp object will have the 'i' flag set.
|
* If ignoreCase is passed in, the Regexp object will have the 'i' flag set.
|
||||||
* If smartCase is passed in, and the query contains upper case letters,
|
* If smartCase is passed in, and the query contains uppercase letters,
|
||||||
* then ignoreCase is overridden, and the 'i' flag will not be set.
|
* then ignoreCase is overridden, and the 'i' flag will not be set.
|
||||||
* If the query contains the /i in the flag part of the regular expression,
|
* If the query contains the /i in the flag part of the regular expression,
|
||||||
* then both ignoreCase and smartCase are ignored, and 'i' will be passed
|
* then both ignoreCase and smartCase are ignored, and 'i' will be passed
|
||||||
|
|||||||
+760
-202
File diff suppressed because it is too large
Load Diff
@@ -168,7 +168,8 @@
|
|||||||
* and require no dom manipulations
|
* and require no dom manipulations
|
||||||
*/
|
*/
|
||||||
var doc = $(document);
|
var doc = $(document);
|
||||||
doc.on('click', '.w2p_flash', function () {
|
doc.on('click', '.w2p_flash', function (event) {
|
||||||
|
event.preventDefault();
|
||||||
var t = $(this);
|
var t = $(this);
|
||||||
if (t.css('top') == '0px') t.slideUp('slow');
|
if (t.css('top') == '0px') t.slideUp('slow');
|
||||||
else t.fadeOut();
|
else t.fadeOut();
|
||||||
@@ -316,6 +317,7 @@
|
|||||||
'beforeSend': function (xhr, settings) {
|
'beforeSend': function (xhr, settings) {
|
||||||
xhr.setRequestHeader('web2py-component-location', document.location);
|
xhr.setRequestHeader('web2py-component-location', document.location);
|
||||||
xhr.setRequestHeader('web2py-component-element', target);
|
xhr.setRequestHeader('web2py-component-element', target);
|
||||||
|
web2py.fire(element, 'w2p:componentBegin', [xhr, settings], target);
|
||||||
return web2py.fire(element, 'ajax:beforeSend', [xhr, settings], target); //test a usecase, should stop here if returns false
|
return web2py.fire(element, 'ajax:beforeSend', [xhr, settings], target); //test a usecase, should stop here if returns false
|
||||||
},
|
},
|
||||||
'success': function (data, status, xhr) {
|
'success': function (data, status, xhr) {
|
||||||
|
|||||||
@@ -465,6 +465,7 @@ def ccache():
|
|||||||
ram['keys'].append((key, GetInHMS(time.time() - value[0])))
|
ram['keys'].append((key, GetInHMS(time.time() - value[0])))
|
||||||
|
|
||||||
for key in cache.disk.storage:
|
for key in cache.disk.storage:
|
||||||
|
value = cache.disk.storage[key]
|
||||||
if key == 'web2py_cache_statistics' and isinstance(value[1], dict):
|
if key == 'web2py_cache_statistics' and isinstance(value[1], dict):
|
||||||
disk['hits'] = value[1]['hit_total'] - value[1]['misses']
|
disk['hits'] = value[1]['hit_total'] - value[1]['misses']
|
||||||
disk['misses'] = value[1]['misses']
|
disk['misses'] = value[1]['misses']
|
||||||
|
|||||||
@@ -168,7 +168,8 @@
|
|||||||
* and require no dom manipulations
|
* and require no dom manipulations
|
||||||
*/
|
*/
|
||||||
var doc = $(document);
|
var doc = $(document);
|
||||||
doc.on('click', '.w2p_flash', function () {
|
doc.on('click', '.w2p_flash', function (event) {
|
||||||
|
event.preventDefault();
|
||||||
var t = $(this);
|
var t = $(this);
|
||||||
if (t.css('top') == '0px') t.slideUp('slow');
|
if (t.css('top') == '0px') t.slideUp('slow');
|
||||||
else t.fadeOut();
|
else t.fadeOut();
|
||||||
@@ -316,6 +317,7 @@
|
|||||||
'beforeSend': function (xhr, settings) {
|
'beforeSend': function (xhr, settings) {
|
||||||
xhr.setRequestHeader('web2py-component-location', document.location);
|
xhr.setRequestHeader('web2py-component-location', document.location);
|
||||||
xhr.setRequestHeader('web2py-component-element', target);
|
xhr.setRequestHeader('web2py-component-element', target);
|
||||||
|
web2py.fire(element, 'w2p:componentBegin', [xhr, settings], target);
|
||||||
return web2py.fire(element, 'ajax:beforeSend', [xhr, settings], target); //test a usecase, should stop here if returns false
|
return web2py.fire(element, 'ajax:beforeSend', [xhr, settings], target); //test a usecase, should stop here if returns false
|
||||||
},
|
},
|
||||||
'success': function (data, status, xhr) {
|
'success': function (data, status, xhr) {
|
||||||
|
|||||||
@@ -17,10 +17,10 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<a class="btn btn180 rounded green" href="http://www.web2py.com/examples/static/web2py_win.zip">For Windows</a>
|
<a class="btn btn180 rounded green" href="https://mdipierro.pythonanywhere.com/examples/static/web2py_win.zip">For Windows</a>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a class="btn btn180 rounded yellow" href="http://www.web2py.com/examples/static/nightly/web2py_win.zip">For Windows</a>
|
<a class="btn btn180 rounded yellow" href="https://mdipierro.pythonanywhere.com/examples/static/nightly/web2py_win.zip">For Windows</a>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a class="btn btn180 rounded red" href="http://github.com/web2py/web2py/">Git Repository</a>
|
<a class="btn btn180 rounded red" href="http://github.com/web2py/web2py/">Git Repository</a>
|
||||||
@@ -28,19 +28,19 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<a class="btn btn180 rounded green" href="http://www.web2py.com/examples/static/web2py_osx.zip">For Mac</a>
|
<a class="btn btn180 rounded green" href="https://mdipierro.pythonanywhere.com/examples/static/web2py_osx.zip">For Mac</a>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a class="btn btn180 rounded yellow" href="http://www.web2py.com/examples/static/nightly/web2py_osx.zip">For Mac</a>
|
<a class="btn btn180 rounded yellow" href="https://mdipierro.pythonanywhere.com/examples/static/nightly/web2py_osx.zip">For Mac</a>
|
||||||
</td>
|
</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<a class="btn btn180 rounded green" href="http://www.web2py.com/examples/static/web2py_src.zip">Source Code</a>
|
<a class="btn btn180 rounded green" href="https://mdipierro.pythonanywhere.com/examples/static/web2py_src.zip">Source Code</a>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a class="btn btn180 rounded yellow" href="http://www.web2py.com/examples/static/nightly/web2py_src.zip">Source Code</a>
|
<a class="btn btn180 rounded yellow" href="https://mdipierro.pythonanywhere.com/examples/static/nightly/web2py_src.zip">Source Code</a>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a class="btn btn180 rounded red" href="http://web2py.readthedocs.org/en/latest/">Source code docs</a>
|
<a class="btn btn180 rounded red" href="http://web2py.readthedocs.org/en/latest/">Source code docs</a>
|
||||||
|
|||||||
@@ -465,6 +465,7 @@ def ccache():
|
|||||||
ram['keys'].append((key, GetInHMS(time.time() - value[0])))
|
ram['keys'].append((key, GetInHMS(time.time() - value[0])))
|
||||||
|
|
||||||
for key in cache.disk.storage:
|
for key in cache.disk.storage:
|
||||||
|
value = cache.disk.storage[key]
|
||||||
if key == 'web2py_cache_statistics' and isinstance(value[1], dict):
|
if key == 'web2py_cache_statistics' and isinstance(value[1], dict):
|
||||||
disk['hits'] = value[1]['hit_total'] - value[1]['misses']
|
disk['hits'] = value[1]['hit_total'] - value[1]['misses']
|
||||||
disk['misses'] = value[1]['misses']
|
disk['misses'] = value[1]['misses']
|
||||||
|
|||||||
@@ -168,7 +168,8 @@
|
|||||||
* and require no dom manipulations
|
* and require no dom manipulations
|
||||||
*/
|
*/
|
||||||
var doc = $(document);
|
var doc = $(document);
|
||||||
doc.on('click', '.w2p_flash', function () {
|
doc.on('click', '.w2p_flash', function (event) {
|
||||||
|
event.preventDefault();
|
||||||
var t = $(this);
|
var t = $(this);
|
||||||
if (t.css('top') == '0px') t.slideUp('slow');
|
if (t.css('top') == '0px') t.slideUp('slow');
|
||||||
else t.fadeOut();
|
else t.fadeOut();
|
||||||
@@ -316,6 +317,7 @@
|
|||||||
'beforeSend': function (xhr, settings) {
|
'beforeSend': function (xhr, settings) {
|
||||||
xhr.setRequestHeader('web2py-component-location', document.location);
|
xhr.setRequestHeader('web2py-component-location', document.location);
|
||||||
xhr.setRequestHeader('web2py-component-element', target);
|
xhr.setRequestHeader('web2py-component-element', target);
|
||||||
|
web2py.fire(element, 'w2p:componentBegin', [xhr, settings], target);
|
||||||
return web2py.fire(element, 'ajax:beforeSend', [xhr, settings], target); //test a usecase, should stop here if returns false
|
return web2py.fire(element, 'ajax:beforeSend', [xhr, settings], target); //test a usecase, should stop here if returns false
|
||||||
},
|
},
|
||||||
'success': function (data, status, xhr) {
|
'success': function (data, status, xhr) {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
# it is not safe to use as a generic.jsonp because of security implications.
|
# it is not safe to use as a generic.jsonp because of security implications.
|
||||||
|
|
||||||
if response.view == 'generic.jsonp':
|
if response.view == 'generic.jsonp':
|
||||||
raise HTTP(501,'generic.jsonp diasbled for security reasons')
|
raise HTTP(501,'generic.jsonp disabled for security reasons')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from gluon.serializers import json
|
from gluon.serializers import json
|
||||||
|
|||||||
Vendored
+3
-2
@@ -1,7 +1,8 @@
|
|||||||
from fabric.api import *
|
from fabric.api import *
|
||||||
from fabric.operations import put, get
|
from fabric.operations import put, get
|
||||||
from fabric.contrib.files import exists
|
from fabric.contrib.files import exists, append, uncomment
|
||||||
import os
|
import os
|
||||||
|
import crypt
|
||||||
import datetime
|
import datetime
|
||||||
import getpass
|
import getpass
|
||||||
|
|
||||||
@@ -19,11 +20,11 @@ def create_user(username):
|
|||||||
"""fab -H root@host create_user:username"""
|
"""fab -H root@host create_user:username"""
|
||||||
password = getpass.getpass('password for %s> ' % username)
|
password = getpass.getpass('password for %s> ' % username)
|
||||||
run('useradd -m -G www-data -s /bin/bash -p %s %s' % (crypt.crypt(password, 'salt'), username))
|
run('useradd -m -G www-data -s /bin/bash -p %s %s' % (crypt.crypt(password, 'salt'), username))
|
||||||
|
local('ssh-copy-id %s' % env.hosts[0])
|
||||||
run('cp /etc/sudoers /tmp/sudoers.new')
|
run('cp /etc/sudoers /tmp/sudoers.new')
|
||||||
append('/tmp/sudoers.new', '%s ALL=(ALL) NOPASSWD:ALL' % username, use_sudo=True)
|
append('/tmp/sudoers.new', '%s ALL=(ALL) NOPASSWD:ALL' % username, use_sudo=True)
|
||||||
run('visudo -c -f /tmp/sudoers.new')
|
run('visudo -c -f /tmp/sudoers.new')
|
||||||
run('EDITOR="cp /tmp/sudoers.new" visudo')
|
run('EDITOR="cp /tmp/sudoers.new" visudo')
|
||||||
local('ssh-copy-id %s' % env.hosts[0])
|
|
||||||
uncomment('~%s/.bashrc' % username, '#force_color_prompt=yes')
|
uncomment('~%s/.bashrc' % username, '#force_color_prompt=yes')
|
||||||
|
|
||||||
def install_web2py():
|
def install_web2py():
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ if PY2:
|
|||||||
import cgi
|
import cgi
|
||||||
import cookielib
|
import cookielib
|
||||||
from xmlrpclib import ProtocolError
|
from xmlrpclib import ProtocolError
|
||||||
|
from gluon.contrib import ipaddress
|
||||||
BytesIO = StringIO
|
BytesIO = StringIO
|
||||||
reduce = reduce
|
reduce = reduce
|
||||||
hashlib_md5 = hashlib.md5
|
hashlib_md5 = hashlib.md5
|
||||||
@@ -97,6 +98,7 @@ else:
|
|||||||
from http import cookiejar as cookielib
|
from http import cookiejar as cookielib
|
||||||
from xmlrpc.client import ProtocolError
|
from xmlrpc.client import ProtocolError
|
||||||
import html # warning, this is the python3 module and not the web2py html module
|
import html # warning, this is the python3 module and not the web2py html module
|
||||||
|
import ipaddress
|
||||||
hashlib_md5 = lambda s: hashlib.md5(bytes(s, 'utf8'))
|
hashlib_md5 = lambda s: hashlib.md5(bytes(s, 'utf8'))
|
||||||
iterkeys = lambda d: iter(d.keys())
|
iterkeys = lambda d: iter(d.keys())
|
||||||
itervalues = lambda d: iter(d.values())
|
itervalues = lambda d: iter(d.values())
|
||||||
|
|||||||
+5
-1
@@ -438,7 +438,11 @@ def add_path_first(path):
|
|||||||
def try_mkdir(path):
|
def try_mkdir(path):
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
try:
|
try:
|
||||||
os.mkdir(path)
|
if os.path.islink(path):
|
||||||
|
# path is a broken link, try to mkdir the target of the link instead of the link itself.
|
||||||
|
os.mkdir(os.path.realpath(path))
|
||||||
|
else:
|
||||||
|
os.mkdir(path)
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
if e.strerror == 'File exists': # In case of race condition.
|
if e.strerror == 'File exists': # In case of race condition.
|
||||||
pass
|
pass
|
||||||
|
|||||||
+1
-1
@@ -640,7 +640,7 @@ def run_controller_in(controller, function, environment):
|
|||||||
ccode = getcfs(layer, filename, lambda: compile2(code, layer))
|
ccode = getcfs(layer, filename, lambda: compile2(code, layer))
|
||||||
|
|
||||||
restricted(ccode, environment, layer=filename)
|
restricted(ccode, environment, layer=filename)
|
||||||
response = current.response
|
response = environment["response"]
|
||||||
vars = response._vars
|
vars = response._vars
|
||||||
if response.postprocessing:
|
if response.postprocessing:
|
||||||
vars = reduce(lambda vars, p: p(vars), response.postprocessing, vars)
|
vars = reduce(lambda vars, p: p(vars), response.postprocessing, vars)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+18
-10
@@ -951,32 +951,40 @@ def findT(path, language=DEFAULT_LANGUAGE):
|
|||||||
Note:
|
Note:
|
||||||
Must be run by the admin app
|
Must be run by the admin app
|
||||||
"""
|
"""
|
||||||
|
from gluon.tools import Auth, Crud
|
||||||
lang_file = pjoin(path, 'languages', language + '.py')
|
lang_file = pjoin(path, 'languages', language + '.py')
|
||||||
sentences = read_dict(lang_file)
|
sentences = read_dict(lang_file)
|
||||||
mp = pjoin(path, 'models')
|
mp = pjoin(path, 'models')
|
||||||
cp = pjoin(path, 'controllers')
|
cp = pjoin(path, 'controllers')
|
||||||
vp = pjoin(path, 'views')
|
vp = pjoin(path, 'views')
|
||||||
mop = pjoin(path, 'modules')
|
mop = pjoin(path, 'modules')
|
||||||
|
def add_message(message):
|
||||||
|
if not message.startswith('#') and not '\n' in message:
|
||||||
|
tokens = message.rsplit('##', 1)
|
||||||
|
else:
|
||||||
|
# this allows markmin syntax in translations
|
||||||
|
tokens = [message]
|
||||||
|
if len(tokens) == 2:
|
||||||
|
message = tokens[0].strip() + '##' + tokens[1].strip()
|
||||||
|
if message and not message in sentences:
|
||||||
|
sentences[message] = message.replace("@markmin\x01", "")
|
||||||
for filename in \
|
for filename in \
|
||||||
listdir(mp, '^.+\.py$', 0) + listdir(cp, '^.+\.py$', 0)\
|
listdir(mp, '^.+\.py$', 0) + listdir(cp, '^.+\.py$', 0)\
|
||||||
+ listdir(vp, '^.+\.html$', 0) + listdir(mop, '^.+\.py$', 0):
|
+ listdir(vp, '^.+\.html$', 0) + listdir(mop, '^.+\.py$', 0):
|
||||||
data = to_native(read_locked(filename))
|
data = to_native(read_locked(filename))
|
||||||
items = regex_translate.findall(data)
|
items = regex_translate.findall(data)
|
||||||
items += ["@markmin\x01%s" %x for x in regex_translate_m.findall(data)]
|
for x in regex_translate_m.findall(data):
|
||||||
|
if x[0:3] in ["'''", '"""']: items.append("%s@markmin\x01%s" %(x[0:3], x[3:]))
|
||||||
|
else: items.append("%s@markmin\x01%s" %(x[0], x[1:]))
|
||||||
for item in items:
|
for item in items:
|
||||||
try:
|
try:
|
||||||
message = safe_eval(item)
|
message = safe_eval(item)
|
||||||
except:
|
except:
|
||||||
continue # silently ignore inproperly formatted strings
|
continue # silently ignore inproperly formatted strings
|
||||||
if not message.startswith('#') and not '\n' in message:
|
add_message(message)
|
||||||
tokens = message.rsplit('##', 1)
|
gluon_msg = [Auth.default_messages, Crud.default_messages]
|
||||||
else:
|
for item in [x for m in gluon_msg for x in m.values() if x is not None]:
|
||||||
# this allows markmin syntax in translations
|
add_message(item)
|
||||||
tokens = [message]
|
|
||||||
if len(tokens) == 2:
|
|
||||||
message = tokens[0].strip() + '##' + tokens[1].strip()
|
|
||||||
if message and not message in sentences:
|
|
||||||
sentences[message] = message.replace("@markmin\x01", "")
|
|
||||||
if not '!langcode!' in sentences:
|
if not '!langcode!' in sentences:
|
||||||
sentences['!langcode!'] = (
|
sentences['!langcode!'] = (
|
||||||
DEFAULT_LANGUAGE if language in ('default', DEFAULT_LANGUAGE) else language)
|
DEFAULT_LANGUAGE if language in ('default', DEFAULT_LANGUAGE) else language)
|
||||||
|
|||||||
+1
-1
Submodule gluon/packages/dal updated: 12bc6d9740...4d22bb4f84
+1
-1
@@ -1040,7 +1040,7 @@ class MapUrlIn(object):
|
|||||||
else:
|
else:
|
||||||
default_function = self.router.default_function # str or None
|
default_function = self.router.default_function # str or None
|
||||||
default_function = self.domain_function or default_function
|
default_function = self.domain_function or default_function
|
||||||
if not arg0 or functions and arg0 not in functions:
|
if not arg0 or functions and arg0.split('.')[0] not in functions:
|
||||||
self.function = default_function or ""
|
self.function = default_function or ""
|
||||||
self.pop_arg_if(arg0 and self.function == arg0)
|
self.pop_arg_if(arg0 and self.function == arg0)
|
||||||
else:
|
else:
|
||||||
|
|||||||
+6
-6
@@ -2153,7 +2153,8 @@ class SQLFORM(FORM):
|
|||||||
ignore_common_filters=None,
|
ignore_common_filters=None,
|
||||||
auto_pagination=True,
|
auto_pagination=True,
|
||||||
use_cursor=False,
|
use_cursor=False,
|
||||||
represent_none=None):
|
represent_none=None,
|
||||||
|
showblobs=False):
|
||||||
|
|
||||||
formstyle = formstyle or current.response.formstyle
|
formstyle = formstyle or current.response.formstyle
|
||||||
if isinstance(query, Set):
|
if isinstance(query, Set):
|
||||||
@@ -2194,7 +2195,7 @@ class SQLFORM(FORM):
|
|||||||
buttondelete='icon trash icon-trash glyphicon glyphicon-trash',
|
buttondelete='icon trash icon-trash glyphicon glyphicon-trash',
|
||||||
buttonedit='icon pen icon-pencil glyphicon glyphicon-pencil',
|
buttonedit='icon pen icon-pencil glyphicon glyphicon-pencil',
|
||||||
buttontable='icon rightarrow icon-arrow-right glyphicon glyphicon-arrow-right',
|
buttontable='icon rightarrow icon-arrow-right glyphicon glyphicon-arrow-right',
|
||||||
buttonview='icon magnifier icon-zoom-in glyphicon glyphicon-zoom-in',
|
buttonview='icon magnifier icon-zoom-in glyphicon glyphicon-zoom-in'
|
||||||
)
|
)
|
||||||
elif not isinstance(ui, dict):
|
elif not isinstance(ui, dict):
|
||||||
raise RuntimeError('SQLFORM.grid ui argument must be a dictionary')
|
raise RuntimeError('SQLFORM.grid ui argument must be a dictionary')
|
||||||
@@ -2340,11 +2341,10 @@ class SQLFORM(FORM):
|
|||||||
else:
|
else:
|
||||||
fields = []
|
fields = []
|
||||||
columns = []
|
columns = []
|
||||||
filter1 = lambda f: isinstance(f, Field) and f.type != 'blob'
|
filter1 = lambda f: isinstance(f, Field) and f.readable and (f.type!='blob' or showblobs)
|
||||||
filter2 = lambda f: isinstance(f, Field) and f.readable
|
|
||||||
for table in tables:
|
for table in tables:
|
||||||
fields += filter(filter1, table)
|
fields += filter(filter1, table)
|
||||||
columns += filter(filter2, table)
|
columns += filter(filter1, table)
|
||||||
for k, f in iteritems(table):
|
for k, f in iteritems(table):
|
||||||
if not k.startswith('_'):
|
if not k.startswith('_'):
|
||||||
if isinstance(f, Field.Virtual) and f.readable:
|
if isinstance(f, Field.Virtual) and f.readable:
|
||||||
@@ -2862,7 +2862,7 @@ class SQLFORM(FORM):
|
|||||||
for field in columns:
|
for field in columns:
|
||||||
if not field.readable:
|
if not field.readable:
|
||||||
continue
|
continue
|
||||||
if field.type == 'blob':
|
elif field.type == 'blob' and not showblobs:
|
||||||
continue
|
continue
|
||||||
if isinstance(field, Field.Virtual) and field.tablename in row:
|
if isinstance(field, Field.Virtual) and field.tablename in row:
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -91,7 +91,8 @@ class TestAppAdmin(unittest.TestCase):
|
|||||||
self.run_view()
|
self.run_view()
|
||||||
self.run_view_file_stream()
|
self.run_view_file_stream()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e.message)
|
import traceback
|
||||||
|
print(traceback.format_exc())
|
||||||
self.fail('Could not make the view')
|
self.fail('Could not make the view')
|
||||||
|
|
||||||
def test_index(self):
|
def test_index(self):
|
||||||
@@ -115,7 +116,8 @@ class TestAppAdmin(unittest.TestCase):
|
|||||||
try:
|
try:
|
||||||
self.run_view()
|
self.run_view()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e.message)
|
import traceback
|
||||||
|
print(traceback.format_exc())
|
||||||
self.fail('Could not make the view')
|
self.fail('Could not make the view')
|
||||||
|
|
||||||
def test_insert(self):
|
def test_insert(self):
|
||||||
@@ -129,7 +131,8 @@ class TestAppAdmin(unittest.TestCase):
|
|||||||
try:
|
try:
|
||||||
self.run_view()
|
self.run_view()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e.message)
|
import traceback
|
||||||
|
print(traceback.format_exc())
|
||||||
self.fail('Could not make the view')
|
self.fail('Could not make the view')
|
||||||
|
|
||||||
def test_insert_submit(self):
|
def test_insert_submit(self):
|
||||||
@@ -151,7 +154,8 @@ class TestAppAdmin(unittest.TestCase):
|
|||||||
try:
|
try:
|
||||||
self.run_view()
|
self.run_view()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e.message)
|
import traceback
|
||||||
|
print(traceback.format_exc())
|
||||||
self.fail('Could not make the view')
|
self.fail('Could not make the view')
|
||||||
db = self.env['db']
|
db = self.env['db']
|
||||||
lisa_record = db(db.auth_user.username == 'lisasimpson').select().first()
|
lisa_record = db(db.auth_user.username == 'lisasimpson').select().first()
|
||||||
|
|||||||
@@ -873,6 +873,27 @@ class TestRouter(unittest.TestCase):
|
|||||||
self.assertEqual(str(URL(a='app2', c='default', f='index',
|
self.assertEqual(str(URL(a='app2', c='default', f='index',
|
||||||
args=['ctr'])), "/app2/index/ctr")
|
args=['ctr'])), "/app2/index/ctr")
|
||||||
|
|
||||||
|
# outbound - with extensions
|
||||||
|
self.assertEqual(
|
||||||
|
str(URL(a='app', c='default', f='index.json')), "/index.json")
|
||||||
|
self.assertEqual(
|
||||||
|
str(URL(a='app', c='default', f='index.json', args=['arg1'])), "/index.json/arg1")
|
||||||
|
self.assertEqual(str(
|
||||||
|
URL(a='app', c='default', f='user.json')), "/user.json")
|
||||||
|
self.assertEqual(str(
|
||||||
|
URL(a='app', c='default', f='user.json', args=['arg1'])), "/user.json/arg1")
|
||||||
|
self.assertEqual(str(URL(
|
||||||
|
a='app', c='default', f='user.json', args=['index'])), "/user.json/index")
|
||||||
|
self.assertEqual(str(
|
||||||
|
URL(a='app', c='default', f='index.json', args=['ctr'])), "/index.json/ctr")
|
||||||
|
self.assertEqual(
|
||||||
|
str(URL(a='app', c='ctr', f='ctrf1.json', args=['arg'])), "/ctr/ctrf1.json/arg")
|
||||||
|
|
||||||
|
self.assertEqual(str(URL(
|
||||||
|
a='app2', c='default', f='index.json', args=['arg1'])), "/app2/index.json/arg1")
|
||||||
|
self.assertEqual(str(URL(
|
||||||
|
a='app2', c='ctr', f='index.json', args=['arg1'])), "/app2/ctr/index.json/arg1")
|
||||||
|
|
||||||
# inbound
|
# inbound
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
filter_url('http://d.com/arg'), "/app/default/index ['arg']")
|
filter_url('http://d.com/arg'), "/app/default/index ['arg']")
|
||||||
@@ -896,6 +917,30 @@ class TestRouter(unittest.TestCase):
|
|||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
filter_url('http://d.com/app2/ctr/arg'), "/app2/ctr/arg")
|
filter_url('http://d.com/app2/ctr/arg'), "/app2/ctr/arg")
|
||||||
|
|
||||||
|
# inbound - with extensions
|
||||||
|
self.assertEqual(
|
||||||
|
filter_url('http://d.com/index.json'), "/app/default/index.json")
|
||||||
|
self.assertEqual(filter_url('http://d.com/user.json'), "/app/default/user.json")
|
||||||
|
self.assertEqual(
|
||||||
|
filter_url('http://d.com/user.json/arg'), "/app/default/user.json ['arg']")
|
||||||
|
self.assertEqual(
|
||||||
|
filter_url('http://d.com/user.json/index'), "/app/default/user.json ['index']")
|
||||||
|
self.assertEqual(
|
||||||
|
filter_url('http://d.com/index.json/ctr'), "/app/default/index.json ['ctr']")
|
||||||
|
self.assertEqual(
|
||||||
|
filter_url('http://d.com/ctr/ctrf1.json/arg'), "/app/ctr/ctrf1.json ['arg']")
|
||||||
|
|
||||||
|
self.assertEqual(filter_url(
|
||||||
|
'http://d.com/app2/index.json/arg'), "/app2/default/index.json ['arg']")
|
||||||
|
self.assertEqual(
|
||||||
|
filter_url('http://d.com/app2/user.json'), "/app2/default/user.json")
|
||||||
|
self.assertEqual(filter_url(
|
||||||
|
'http://d.com/app2/user.json/arg'), "/app2/default/user.json ['arg']")
|
||||||
|
self.assertEqual(filter_url(
|
||||||
|
'http://d.com/app2/ctr/index.json/arg'), "/app2/ctr/index.json ['arg']")
|
||||||
|
self.assertEqual(
|
||||||
|
filter_url('http://d.com/app2/ctr/arg'), "/app2/ctr/arg")
|
||||||
|
|
||||||
def test_router_functions2(self):
|
def test_router_functions2(self):
|
||||||
'''
|
'''
|
||||||
Test more functions=[something]
|
Test more functions=[something]
|
||||||
|
|||||||
@@ -843,7 +843,7 @@ class TestValidators(unittest.TestCase):
|
|||||||
'|'.join(['Minimum length is 8',
|
'|'.join(['Minimum length is 8',
|
||||||
'Maximum length is 4',
|
'Maximum length is 4',
|
||||||
'Must include at least 1 of the following: ~!@#$%^&*()_+-=?<>,.:;{}[]|',
|
'Must include at least 1 of the following: ~!@#$%^&*()_+-=?<>,.:;{}[]|',
|
||||||
'Must include at least 1 upper case',
|
'Must include at least 1 uppercase',
|
||||||
'Must include at least 1 number']))
|
'Must include at least 1 number']))
|
||||||
)
|
)
|
||||||
rtn = IS_STRONG(es=True)('abcde')
|
rtn = IS_STRONG(es=True)('abcde')
|
||||||
@@ -851,7 +851,7 @@ class TestValidators(unittest.TestCase):
|
|||||||
('abcde',
|
('abcde',
|
||||||
'|'.join(['Minimum length is 8',
|
'|'.join(['Minimum length is 8',
|
||||||
'Must include at least 1 of the following: ~!@#$%^&*()_+-=?<>,.:;{}[]|',
|
'Must include at least 1 of the following: ~!@#$%^&*()_+-=?<>,.:;{}[]|',
|
||||||
'Must include at least 1 upper case',
|
'Must include at least 1 uppercase',
|
||||||
'Must include at least 1 number']))
|
'Must include at least 1 number']))
|
||||||
)
|
)
|
||||||
rtn = IS_STRONG(upper=0, lower=0, number=0, es=True)('Abcde1')
|
rtn = IS_STRONG(upper=0, lower=0, number=0, es=True)('Abcde1')
|
||||||
@@ -859,8 +859,8 @@ class TestValidators(unittest.TestCase):
|
|||||||
('Abcde1',
|
('Abcde1',
|
||||||
'|'.join(['Minimum length is 8',
|
'|'.join(['Minimum length is 8',
|
||||||
'Must include at least 1 of the following: ~!@#$%^&*()_+-=?<>,.:;{}[]|',
|
'Must include at least 1 of the following: ~!@#$%^&*()_+-=?<>,.:;{}[]|',
|
||||||
'May not include any upper case letters',
|
'May not include any uppercase letters',
|
||||||
'May not include any lower case letters',
|
'May not include any lowercase letters',
|
||||||
'May not include any numbers']))
|
'May not include any numbers']))
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -1029,12 +1029,11 @@ this is the content of the fake file
|
|||||||
self.assertEqual(rtn, ('2001::126c:8ffa:fe22:b3af', 'Enter valid IPv6 address'))
|
self.assertEqual(rtn, ('2001::126c:8ffa:fe22:b3af', 'Enter valid IPv6 address'))
|
||||||
rtn = IS_IPV6(is_multicast=True)('ff00::126c:8ffa:fe22:b3af')
|
rtn = IS_IPV6(is_multicast=True)('ff00::126c:8ffa:fe22:b3af')
|
||||||
self.assertEqual(rtn, ('ff00::126c:8ffa:fe22:b3af', None))
|
self.assertEqual(rtn, ('ff00::126c:8ffa:fe22:b3af', None))
|
||||||
# TODO:
|
|
||||||
# with py3.ipaddress '2001::126c:8ffa:fe22:b3af' is considered private
|
# with py3.ipaddress '2001::126c:8ffa:fe22:b3af' is considered private
|
||||||
# with py2.ipaddress '2001::126c:8ffa:fe22:b3af' is considered private
|
# with py2.ipaddress '2001::126c:8ffa:fe22:b3af' is considered private
|
||||||
# with gluon.contrib.ipaddr(both current and trunk) is not considered private
|
# with gluon.contrib.ipaddr(both current and trunk) is not considered private
|
||||||
# rtn = IS_IPV6(is_routeable=True)('2001::126c:8ffa:fe22:b3af')
|
rtn = IS_IPV6(is_routeable=False)('2001::126c:8ffa:fe22:b3af')
|
||||||
# self.assertEqual(rtn, ('2001::126c:8ffa:fe22:b3af', None))
|
self.assertEqual(rtn, ('2001::126c:8ffa:fe22:b3af', None))
|
||||||
rtn = IS_IPV6(is_routeable=True)('ff00::126c:8ffa:fe22:b3af')
|
rtn = IS_IPV6(is_routeable=True)('ff00::126c:8ffa:fe22:b3af')
|
||||||
self.assertEqual(rtn, ('ff00::126c:8ffa:fe22:b3af', 'Enter valid IPv6 address'))
|
self.assertEqual(rtn, ('ff00::126c:8ffa:fe22:b3af', 'Enter valid IPv6 address'))
|
||||||
rtn = IS_IPV6(subnets='2001::/32')('2001::8ffa:fe22:b3af')
|
rtn = IS_IPV6(subnets='2001::/32')('2001::8ffa:fe22:b3af')
|
||||||
|
|||||||
+37
-13
@@ -2005,6 +2005,12 @@ class Auth(object):
|
|||||||
return self.cas_validate(version=2, proxy=False)
|
return self.cas_validate(version=2, proxy=False)
|
||||||
elif args(1) == self.settings.cas_actions['proxyvalidate']:
|
elif args(1) == self.settings.cas_actions['proxyvalidate']:
|
||||||
return self.cas_validate(version=2, proxy=True)
|
return self.cas_validate(version=2, proxy=True)
|
||||||
|
elif (args(1) == 'p3'
|
||||||
|
and args(2) == self.settings.cas_actions['servicevalidate']):
|
||||||
|
return self.cas_validate(version=3, proxy=False)
|
||||||
|
elif (args(1) == 'p3'
|
||||||
|
and args(2) == self.settings.cas_actions['proxyvalidate']):
|
||||||
|
return self.cas_validate(version=3, proxy=True)
|
||||||
elif args(1) == self.settings.cas_actions['logout']:
|
elif args(1) == self.settings.cas_actions['logout']:
|
||||||
return self.logout(next=request.vars.service or DEFAULT)
|
return self.logout(next=request.vars.service or DEFAULT)
|
||||||
else:
|
else:
|
||||||
@@ -2830,6 +2836,15 @@ class Auth(object):
|
|||||||
if success:
|
if success:
|
||||||
if version == 1:
|
if version == 1:
|
||||||
message = 'yes\n%s' % user[userfield]
|
message = 'yes\n%s' % user[userfield]
|
||||||
|
elif version == 3:
|
||||||
|
username = user.get('username', user[userfield])
|
||||||
|
message = build_response(
|
||||||
|
TAG['cas:authenticationSuccess'](
|
||||||
|
TAG['cas:user'](username),
|
||||||
|
TAG['cas:attributes'](
|
||||||
|
*[TAG['cas:' + field.name](user[field.name])
|
||||||
|
for field in self.table_user()
|
||||||
|
if field.readable])))
|
||||||
else: # assume version 2
|
else: # assume version 2
|
||||||
username = user.get('username', user[userfield])
|
username = user.get('username', user[userfield])
|
||||||
message = build_response(
|
message = build_response(
|
||||||
@@ -3417,7 +3432,9 @@ class Auth(object):
|
|||||||
link = self.url(
|
link = self.url(
|
||||||
self.settings.function, args=('verify_email', key), scheme=True)
|
self.settings.function, args=('verify_email', key), scheme=True)
|
||||||
d = dict(form.vars)
|
d = dict(form.vars)
|
||||||
d.update(dict(key=key, link=link, username=form.vars[username]))
|
d.update(dict(key=key, link=link, username=form.vars[username],
|
||||||
|
firstname=form.vars['firstname'],
|
||||||
|
lastname=form.vars['lastname']))
|
||||||
if not (self.settings.mailer and self.settings.mailer.send(
|
if not (self.settings.mailer and self.settings.mailer.send(
|
||||||
to=form.vars.email,
|
to=form.vars.email,
|
||||||
subject=self.messages.verify_email_subject,
|
subject=self.messages.verify_email_subject,
|
||||||
@@ -3670,7 +3687,12 @@ class Auth(object):
|
|||||||
key = request.args[-1]
|
key = request.args[-1]
|
||||||
if key:
|
if key:
|
||||||
session._reset_password_key = key
|
session._reset_password_key = key
|
||||||
redirect(self.url(args='confirm_registration'))
|
if next:
|
||||||
|
redirect_vars = {'_next': next}
|
||||||
|
else:
|
||||||
|
redirect_vars = {}
|
||||||
|
redirect(self.url(args='confirm_registration',
|
||||||
|
vars=redirect_vars))
|
||||||
else:
|
else:
|
||||||
key = session._reset_password_key
|
key = session._reset_password_key
|
||||||
else:
|
else:
|
||||||
@@ -4776,6 +4798,18 @@ class Auth(object):
|
|||||||
|
|
||||||
class Crud(object): # pragma: no cover
|
class Crud(object): # pragma: no cover
|
||||||
|
|
||||||
|
default_messages = dict(
|
||||||
|
submit_button = 'Submit',
|
||||||
|
delete_label = 'Check to delete',
|
||||||
|
record_created = 'Record Created',
|
||||||
|
record_updated = 'Record Updated',
|
||||||
|
record_deleted = 'Record Deleted',
|
||||||
|
update_log = 'Record %(id)s updated',
|
||||||
|
create_log = 'Record %(id)s created',
|
||||||
|
read_log = 'Record %(id)s read',
|
||||||
|
delete_log = 'Record %(id)s deleted',
|
||||||
|
)
|
||||||
|
|
||||||
def url(self, f=None, args=None, vars=None):
|
def url(self, f=None, args=None, vars=None):
|
||||||
"""
|
"""
|
||||||
This should point to the controller that exposes
|
This should point to the controller that exposes
|
||||||
@@ -4824,17 +4858,7 @@ class Crud(object): # pragma: no cover
|
|||||||
settings.lock_keys = True
|
settings.lock_keys = True
|
||||||
|
|
||||||
messages = self.messages = Messages(current.T)
|
messages = self.messages = Messages(current.T)
|
||||||
messages.submit_button = 'Submit'
|
messages.update(Crud.default_messages)
|
||||||
messages.delete_label = 'Check to delete'
|
|
||||||
messages.record_created = 'Record Created'
|
|
||||||
messages.record_updated = 'Record Updated'
|
|
||||||
messages.record_deleted = 'Record Deleted'
|
|
||||||
|
|
||||||
messages.update_log = 'Record %(id)s updated'
|
|
||||||
messages.create_log = 'Record %(id)s created'
|
|
||||||
messages.read_log = 'Record %(id)s read'
|
|
||||||
messages.delete_log = 'Record %(id)s deleted'
|
|
||||||
|
|
||||||
messages.lock_keys = True
|
messages.lock_keys = True
|
||||||
|
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
|
|||||||
+14
-12
@@ -17,6 +17,7 @@ import random
|
|||||||
import inspect
|
import inspect
|
||||||
import time
|
import time
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
import re
|
import re
|
||||||
import logging
|
import logging
|
||||||
import socket
|
import socket
|
||||||
@@ -299,19 +300,20 @@ def initialize_urandom():
|
|||||||
try:
|
try:
|
||||||
os.urandom(1)
|
os.urandom(1)
|
||||||
have_urandom = True
|
have_urandom = True
|
||||||
try:
|
if sys.platform != 'win32':
|
||||||
# try to add process-specific entropy
|
|
||||||
frandom = open('/dev/urandom', 'wb')
|
|
||||||
try:
|
try:
|
||||||
if PY2:
|
# try to add process-specific entropy
|
||||||
frandom.write(''.join(chr(t) for t in ctokens))
|
frandom = open('/dev/urandom', 'wb')
|
||||||
else:
|
try:
|
||||||
frandom.write(bytes([]).join(bytes([t]) for t in ctokens))
|
if PY2:
|
||||||
finally:
|
frandom.write(''.join(chr(t) for t in ctokens))
|
||||||
frandom.close()
|
else:
|
||||||
except IOError:
|
frandom.write(bytes([]).join(bytes([t]) for t in ctokens))
|
||||||
# works anyway
|
finally:
|
||||||
pass
|
frandom.close()
|
||||||
|
except IOError:
|
||||||
|
# works anyway
|
||||||
|
pass
|
||||||
except NotImplementedError:
|
except NotImplementedError:
|
||||||
have_urandom = False
|
have_urandom = False
|
||||||
logger.warning(
|
logger.warning(
|
||||||
|
|||||||
+11
-16
@@ -2470,7 +2470,7 @@ class IS_LIST_OF(Validator):
|
|||||||
|
|
||||||
class IS_LOWER(Validator):
|
class IS_LOWER(Validator):
|
||||||
"""
|
"""
|
||||||
Converts to lower case::
|
Converts to lowercase::
|
||||||
|
|
||||||
>>> IS_LOWER()('ABC')
|
>>> IS_LOWER()('ABC')
|
||||||
('abc', None)
|
('abc', None)
|
||||||
@@ -2485,7 +2485,7 @@ class IS_LOWER(Validator):
|
|||||||
|
|
||||||
class IS_UPPER(Validator):
|
class IS_UPPER(Validator):
|
||||||
"""
|
"""
|
||||||
Converts to upper case::
|
Converts to uppercase::
|
||||||
|
|
||||||
>>> IS_UPPER()('abc')
|
>>> IS_UPPER()('abc')
|
||||||
('ABC', None)
|
('ABC', None)
|
||||||
@@ -3025,22 +3025,22 @@ class IS_STRONG(object):
|
|||||||
all_upper = re.findall("[A-Z]", value)
|
all_upper = re.findall("[A-Z]", value)
|
||||||
if self.upper > 0:
|
if self.upper > 0:
|
||||||
if not len(all_upper) >= self.upper:
|
if not len(all_upper) >= self.upper:
|
||||||
failures.append(translate("Must include at least %s upper case")
|
failures.append(translate("Must include at least %s uppercase")
|
||||||
% str(self.upper))
|
% str(self.upper))
|
||||||
else:
|
else:
|
||||||
if len(all_upper) > 0:
|
if len(all_upper) > 0:
|
||||||
failures.append(
|
failures.append(
|
||||||
translate("May not include any upper case letters"))
|
translate("May not include any uppercase letters"))
|
||||||
if isinstance(self.lower, int):
|
if isinstance(self.lower, int):
|
||||||
all_lower = re.findall("[a-z]", value)
|
all_lower = re.findall("[a-z]", value)
|
||||||
if self.lower > 0:
|
if self.lower > 0:
|
||||||
if not len(all_lower) >= self.lower:
|
if not len(all_lower) >= self.lower:
|
||||||
failures.append(translate("Must include at least %s lower case")
|
failures.append(translate("Must include at least %s lowercase")
|
||||||
% str(self.lower))
|
% str(self.lower))
|
||||||
else:
|
else:
|
||||||
if len(all_lower) > 0:
|
if len(all_lower) > 0:
|
||||||
failures.append(
|
failures.append(
|
||||||
translate("May not include any lower case letters"))
|
translate("May not include any lowercase letters"))
|
||||||
if isinstance(self.number, int):
|
if isinstance(self.number, int):
|
||||||
all_number = re.findall("[0-9]", value)
|
all_number = re.findall("[0-9]", value)
|
||||||
if self.number > 0:
|
if self.number > 0:
|
||||||
@@ -3505,10 +3505,7 @@ class IS_IPV6(Validator):
|
|||||||
self.error_message = error_message
|
self.error_message = error_message
|
||||||
|
|
||||||
def __call__(self, value):
|
def __call__(self, value):
|
||||||
try:
|
from gluon._compat import ipaddress
|
||||||
import ipaddress
|
|
||||||
except ImportError:
|
|
||||||
from gluon.contrib import ipaddr as ipaddress
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
ip = ipaddress.IPv6Address(to_unicode(value))
|
ip = ipaddress.IPv6Address(to_unicode(value))
|
||||||
@@ -3732,12 +3729,10 @@ class IS_IPADDRESS(Validator):
|
|||||||
self.error_message = error_message
|
self.error_message = error_message
|
||||||
|
|
||||||
def __call__(self, value):
|
def __call__(self, value):
|
||||||
try:
|
from gluon._compat import ipaddress
|
||||||
from ipaddress import ip_address as IPAddress
|
IPAddress = ipaddress.ip_address
|
||||||
from ipaddress import IPv6Address, IPv4Address
|
IPv6Address = ipaddress.IPv6Address
|
||||||
except ImportError:
|
IPv4Address = ipaddress.IPv4Address
|
||||||
from gluon.contrib.ipaddr import (IPAddress, IPv4Address,
|
|
||||||
IPv6Address)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
ip = IPAddress(to_unicode(value))
|
ip = IPAddress(to_unicode(value))
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ legacy_db(legacy_db.mytable.id>0).select()
|
|||||||
If the script crashes this is might be due to that fact that the data_type_map dictionary below is incomplete.
|
If the script crashes this is might be due to that fact that the data_type_map dictionary below is incomplete.
|
||||||
Please complete it, improve it and continue.
|
Please complete it, improve it and continue.
|
||||||
|
|
||||||
Created by Falko Krause, minor modifications by Massimo Di Pierro and Ron McOuat
|
Created by Falko Krause, minor modifications by Massimo Di Pierro, Ron McOuat and Marvi Benedet
|
||||||
'''
|
'''
|
||||||
import subprocess
|
import subprocess
|
||||||
import re
|
import re
|
||||||
@@ -52,10 +52,11 @@ data_type_map = dict(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def mysql(database_name, username, password):
|
def mysql(database_name, username, password, host):
|
||||||
p = subprocess.Popen(['mysql',
|
p = subprocess.Popen(['mysql',
|
||||||
'--user=%s' % username,
|
'--user=%s' % username,
|
||||||
'--password=%s' % password,
|
'--password=%s' % password,
|
||||||
|
'--host=%s' % host,
|
||||||
'--execute=show tables;',
|
'--execute=show tables;',
|
||||||
database_name],
|
database_name],
|
||||||
stdin=subprocess.PIPE,
|
stdin=subprocess.PIPE,
|
||||||
@@ -64,14 +65,15 @@ def mysql(database_name, username, password):
|
|||||||
sql_showtables, stderr = p.communicate()
|
sql_showtables, stderr = p.communicate()
|
||||||
tables = [re.sub(
|
tables = [re.sub(
|
||||||
'\|\s+([^\|*])\s+.*', '\1', x) for x in sql_showtables.split()[1:]]
|
'\|\s+([^\|*])\s+.*', '\1', x) for x in sql_showtables.split()[1:]]
|
||||||
connection_string = "legacy_db = DAL('mysql://%s:%s@localhost/%s')" % (
|
connection_string = "legacy_db = DAL('mysql://%s:%s@%s/%s')" % (
|
||||||
username, password, database_name)
|
username, password, host, database_name)
|
||||||
legacy_db_table_web2py_code = []
|
legacy_db_table_web2py_code = []
|
||||||
for table_name in tables:
|
for table_name in tables:
|
||||||
#get the sql create statement
|
#get the sql create statement
|
||||||
p = subprocess.Popen(['mysqldump',
|
p = subprocess.Popen(['mysqldump',
|
||||||
'--user=%s' % username,
|
'--user=%s' % username,
|
||||||
'--password=%s' % password,
|
'--password=%s' % password,
|
||||||
|
'--host=%s' % host,
|
||||||
'--skip-add-drop-table',
|
'--skip-add-drop-table',
|
||||||
'--no-data', database_name,
|
'--no-data', database_name,
|
||||||
table_name], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
table_name], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
@@ -106,9 +108,13 @@ def mysql(database_name, username, password):
|
|||||||
legacy_db_table_web2py_code)
|
legacy_db_table_web2py_code)
|
||||||
return legacy_db_web2py_code
|
return legacy_db_web2py_code
|
||||||
|
|
||||||
regex = re.compile('(.*?):(.*?)@(.*)')
|
regex = re.compile('(.*):(.*)@((.*)/)?(.*)')
|
||||||
if len(sys.argv) < 2 or not regex.match(sys.argv[1]):
|
if len(sys.argv) < 2 or not regex.match(sys.argv[1]):
|
||||||
print 'USAGE:\n\n extract_mysql_models.py username:password@data_basename\n\n'
|
print 'USAGE:\n\n extract_mysql_models.py username:password@[host/]data_basename\n\n'
|
||||||
else:
|
else:
|
||||||
m = regex.match(sys.argv[1])
|
m = regex.match(sys.argv[1])
|
||||||
print mysql(m.group(3), m.group(1), m.group(2))
|
username = m.group(1)
|
||||||
|
password = m.group(2)
|
||||||
|
host = m.group(4) or 'localhost'
|
||||||
|
db_name = m.group(5)
|
||||||
|
print mysql(database_name = db_name, username = username, password = password, host = host)
|
||||||
|
|||||||
@@ -216,6 +216,7 @@ fi
|
|||||||
|
|
||||||
/etc/init.d/nginx start
|
/etc/init.d/nginx start
|
||||||
systemctl start emperor.uwsgi.service
|
systemctl start emperor.uwsgi.service
|
||||||
|
systemctl enable emperor.uwsgi.service
|
||||||
|
|
||||||
echo <<EOF
|
echo <<EOF
|
||||||
you can stop uwsgi and nginx with
|
you can stop uwsgi and nginx with
|
||||||
|
|||||||
Reference in New Issue
Block a user