something went wrong with VCS, trying fix it
This commit is contained in:
2
VERSION
2
VERSION
@@ -1 +1 @@
|
||||
Version 2.4.6-stable+timestamp.2013.04.28.23.09.04
|
||||
Version 2.4.6-stable+timestamp.2013.05.02.20.31.34
|
||||
|
||||
35
applications/admin/static/js/web2py_bootstrap.j
Normal file
35
applications/admin/static/js/web2py_bootstrap.j
Normal file
@@ -0,0 +1,35 @@
|
||||
// this code improves bootstrap menus and adds dropdown support
|
||||
jQuery(function(){
|
||||
jQuery('.nav>li>a').each(function(){
|
||||
if(jQuery(this).parent().find('ul').length)
|
||||
jQuery(this).attr({'class':'dropdown-toggle','data-toggle':'dropdown'}).append('<b class="caret"></b>');
|
||||
});
|
||||
jQuery('.nav li li').each(function(){
|
||||
if(jQuery(this).find('ul').length)
|
||||
jQuery(this).addClass('dropdown-submenu');
|
||||
});
|
||||
function adjust_height_of_collapsed_nav() {
|
||||
var cn = jQuery('div.collapse');
|
||||
if (cn.get(0)) {
|
||||
var cnh = cn.get(0).style.height;
|
||||
if (cnh>'0px'){
|
||||
cn.css('height','auto');
|
||||
}
|
||||
}
|
||||
}
|
||||
function hoverMenu(){
|
||||
jQuery('ul.nav a.dropdown-toggle').parent().hover(function(){
|
||||
adjust_height_of_collapsed_nav();
|
||||
mi = jQuery(this).addClass('open');
|
||||
mi.children('.dropdown-menu').stop(true, true).delay(200).fadeIn(400);
|
||||
}, function(){
|
||||
mi = jQuery(this);
|
||||
mi.children('.dropdown-menu').stop(true, true).delay(200).fadeOut(function(){mi.removeClass('open')});
|
||||
});
|
||||
}
|
||||
hoverMenu(); // first page load
|
||||
jQuery(window).resize(hoverMenu); // on resize event
|
||||
jQuery('ul.nav li.dropdown a').click(function(){window.location=jQuery(this).attr('href');});
|
||||
// make all buttons bootstrap buttons
|
||||
jQuery('button, form input[type="submit"], form input[type="button"]').addClass('btn');
|
||||
});
|
||||
35
applications/examples/static/js/web2py_bootstrap.j
Normal file
35
applications/examples/static/js/web2py_bootstrap.j
Normal file
@@ -0,0 +1,35 @@
|
||||
// this code improves bootstrap menus and adds dropdown support
|
||||
jQuery(function(){
|
||||
jQuery('.nav>li>a').each(function(){
|
||||
if(jQuery(this).parent().find('ul').length)
|
||||
jQuery(this).attr({'class':'dropdown-toggle','data-toggle':'dropdown'}).append('<b class="caret"></b>');
|
||||
});
|
||||
jQuery('.nav li li').each(function(){
|
||||
if(jQuery(this).find('ul').length)
|
||||
jQuery(this).addClass('dropdown-submenu');
|
||||
});
|
||||
function adjust_height_of_collapsed_nav() {
|
||||
var cn = jQuery('div.collapse');
|
||||
if (cn.get(0)) {
|
||||
var cnh = cn.get(0).style.height;
|
||||
if (cnh>'0px'){
|
||||
cn.css('height','auto');
|
||||
}
|
||||
}
|
||||
}
|
||||
function hoverMenu(){
|
||||
jQuery('ul.nav a.dropdown-toggle').parent().hover(function(){
|
||||
adjust_height_of_collapsed_nav();
|
||||
mi = jQuery(this).addClass('open');
|
||||
mi.children('.dropdown-menu').stop(true, true).delay(200).fadeIn(400);
|
||||
}, function(){
|
||||
mi = jQuery(this);
|
||||
mi.children('.dropdown-menu').stop(true, true).delay(200).fadeOut(function(){mi.removeClass('open')});
|
||||
});
|
||||
}
|
||||
hoverMenu(); // first page load
|
||||
jQuery(window).resize(hoverMenu); // on resize event
|
||||
jQuery('ul.nav li.dropdown a').click(function(){window.location=jQuery(this).attr('href');});
|
||||
// make all buttons bootstrap buttons
|
||||
jQuery('button, form input[type="submit"], form input[type="button"]').addClass('btn');
|
||||
});
|
||||
14
gluon/dal.py
14
gluon/dal.py
@@ -4719,12 +4719,17 @@ class GoogleDatastoreAdapter(NoSQLAdapter):
|
||||
"text and blob field types not allowed in projection queries")
|
||||
else:
|
||||
projection.append(f.name)
|
||||
elif args_get('filterfields') == True:
|
||||
projection = []
|
||||
for f in fields:
|
||||
projection.append(f.name)
|
||||
|
||||
# projection's can't include 'id'.
|
||||
# real projection's can't include 'id'.
|
||||
# it will be added to the result later
|
||||
query_projection = [
|
||||
p for p in projection if \
|
||||
p != db[tablename]._id.name] if projection \
|
||||
p != db[tablename]._id.name] if projection and \
|
||||
args_get('projection') == True\
|
||||
else None
|
||||
|
||||
cursor = None
|
||||
@@ -4802,6 +4807,11 @@ class GoogleDatastoreAdapter(NoSQLAdapter):
|
||||
what is accepted imposed by GAE: each field must be indexed,
|
||||
projection queries cannot contain blob or text fields, and you
|
||||
cannot use == and also select that same field. see https://developers.google.com/appengine/docs/python/datastore/queries#Query_Projection
|
||||
- optional attribute 'filterfields' when set to True web2py will only
|
||||
parse the explicitly listed fields into the Rows object, even though
|
||||
all fields are returned in the query. This can be used to reduce
|
||||
memory usage in cases where true projection queries are not
|
||||
usable.
|
||||
- optional attribute 'reusecursor' allows use of cursor with queries
|
||||
that have the limitby attribute. Set the attribute to True for the
|
||||
first query, set it to the value of db['_lastcursor'] to continue
|
||||
|
||||
@@ -706,17 +706,20 @@ class IS_INT_IN_RANGE(Validator):
|
||||
self.minimum = self.maximum = None
|
||||
if minimum is None:
|
||||
if maximum is None:
|
||||
self.error_message = error_message or 'enter an integer'
|
||||
self.error_message = translate(
|
||||
error_message or 'enter an integer')
|
||||
else:
|
||||
self.maximum = int(maximum)
|
||||
if error_message is None:
|
||||
error_message = 'enter an integer less than or equal to %(max)g'
|
||||
error_message = \
|
||||
'enter an integer less than or equal to %(max)g'
|
||||
self.error_message = translate(
|
||||
error_message) % dict(max=self.maximum - 1)
|
||||
elif maximum is None:
|
||||
self.minimum = int(minimum)
|
||||
if error_message is None:
|
||||
error_message = 'enter an integer greater than or equal to %(min)g'
|
||||
error_message = \
|
||||
'enter an integer greater than or equal to %(min)g'
|
||||
self.error_message = translate(
|
||||
error_message) % dict(min=self.minimum)
|
||||
else:
|
||||
|
||||
226
scripts/setup-web2py-nginx-uwsgi-opensuse.sh
Normal file
226
scripts/setup-web2py-nginx-uwsgi-opensuse.sh
Normal file
@@ -0,0 +1,226 @@
|
||||
#!/bin/bash
|
||||
echo 'setup-web2py-nginx-uwsgi-opensuse.sh'
|
||||
echo 'Requires OpenSUSE 12.3 32Bits and installs Nginx + uWSGI + Web2py'
|
||||
|
||||
|
||||
# Get Web2py Admin Password
|
||||
echo -e "Web2py Admin Password: \c "
|
||||
read PW
|
||||
|
||||
zypper clean && zypper refresh && zypper up
|
||||
zypper in -y nginx python-xml python-pip unzip sudo
|
||||
zypper in -y gcc python-devel libxml2-devel python-pip unzip
|
||||
pip install --upgrade pip
|
||||
PIPPATH=`which pip`
|
||||
$PIPPATH install --upgrade uwsgi
|
||||
|
||||
|
||||
# Prepare folders for uwsgi
|
||||
mkdir /etc/uwsgi
|
||||
mkdir /var/log/uwsgi
|
||||
|
||||
usermod -G www nginx
|
||||
|
||||
mkdir -p /etc/nginx/vhosts.d/
|
||||
mkdir -p /etc/nginx/ssl/
|
||||
|
||||
|
||||
cd /etc/nginx/ssl
|
||||
openssl genrsa 1024 > web2py.key
|
||||
chmod 400 web2py.key
|
||||
openssl req -new -x509 -nodes -sha1 -days 1780 -key web2py.key > web2py.crt
|
||||
openssl x509 -noout -fingerprint -text < web2py.crt > web2py.info
|
||||
|
||||
|
||||
echo 'server {
|
||||
listen 80;
|
||||
server_name $hostname;
|
||||
#to enable correct use of response.static_version
|
||||
#location ~* /(\w+)/static(?:/_[\d]+\.[\d]+\.[\d]+)?/(.*)$ {
|
||||
# alias /srv/www/web2py/applications/$1/static/$2;
|
||||
# expires max;
|
||||
#}
|
||||
location ~* /(\w+)/static/ {
|
||||
root /srv/www/web2py/applications/;
|
||||
#remove next comment on production
|
||||
#expires max;
|
||||
}
|
||||
location / {
|
||||
#uwsgi_pass 127.0.0.1:9001;
|
||||
uwsgi_pass unix:///tmp/web2py.socket;
|
||||
include /etc/nginx/uwsgi_params;
|
||||
uwsgi_param UWSGI_SCHEME $scheme;
|
||||
uwsgi_param SERVER_SOFTWARE nginx/$nginx_version;
|
||||
}
|
||||
}
|
||||
server {
|
||||
listen 443 default_server ssl;
|
||||
server_name $hostname;
|
||||
ssl_certificate /etc/nginx/ssl/web2py.crt;
|
||||
ssl_certificate_key /etc/nginx/ssl/web2py.key;
|
||||
ssl_prefer_server_ciphers on;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_timeout 10m;
|
||||
ssl_ciphers ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA;
|
||||
ssl_protocols SSLv3 TLSv1;
|
||||
keepalive_timeout 70;
|
||||
location / {
|
||||
#uwsgi_pass 127.0.0.1:9001;
|
||||
uwsgi_pass unix:///tmp/web2py.socket;
|
||||
include /etc/nginx/uwsgi_params;
|
||||
uwsgi_param UWSGI_SCHEME $scheme;
|
||||
uwsgi_param SERVER_SOFTWARE nginx/$nginx_version;
|
||||
}
|
||||
|
||||
}' >/etc/nginx/vhosts.d/web2py.conf
|
||||
|
||||
|
||||
|
||||
# Create configuration file /etc/uwsgi/web2py.xml
|
||||
echo '<uwsgi>
|
||||
<socket>/tmp/web2py.socket</socket>
|
||||
<pythonpath>/srv/www/web2py/</pythonpath>
|
||||
<mount>/=wsgihandler:application</mount>
|
||||
<master/>
|
||||
<processes>4</processes>
|
||||
<harakiri>60</harakiri>
|
||||
<reload-mercy>8</reload-mercy>
|
||||
<cpu-affinity>1</cpu-affinity>
|
||||
<stats>/tmp/stats.socket</stats>
|
||||
<max-requests>2000</max-requests>
|
||||
<limit-as>512</limit-as>
|
||||
<reload-on-as>256</reload-on-as>
|
||||
<reload-on-rss>192</reload-on-rss>
|
||||
<uid>nginx</uid>
|
||||
<gid>www</gid>
|
||||
<cron>0 0 -1 -1 -1 python /srv/www/web2py/web2py.py -Q -S welcome -M -R scripts/sessions2trash.py -A -o</cron>
|
||||
<no-orphans/>
|
||||
</uwsgi>' >/etc/uwsgi/web2py.xml
|
||||
|
||||
|
||||
cd /srv/www/
|
||||
wget http://web2py.com/examples/static/web2py_src.zip
|
||||
unzip web2py_src.zip
|
||||
rm web2py_src.zip
|
||||
# Download latest version of sessions2trash.py
|
||||
wget http://web2py.googlecode.com/hg/scripts/sessions2trash.py -O /srv/www/web2py/scripts/sessions2trash.py
|
||||
chown -R nginx:www web2py
|
||||
cd /srv/www/web2py
|
||||
sudo -u nginx python -c "from gluon.main import save_password; save_password('$PW',443)"
|
||||
|
||||
|
||||
|
||||
## Daemons /start/stop
|
||||
|
||||
echo '#!/bin/sh
|
||||
# Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany.
|
||||
#
|
||||
# Author: James Oakley
|
||||
#
|
||||
# /etc/init.d/uwsgi
|
||||
# and its symbolic link
|
||||
# /(usr/)sbin/rcuwsgi
|
||||
#
|
||||
# LSB compatible service control script; see http://www.linuxbase.org/spec/
|
||||
#
|
||||
### BEGIN INIT INFO
|
||||
# Provides: uwsgi
|
||||
# Required-Start: $syslog $remote_fs
|
||||
# Should-Start: $time ypbind smtp
|
||||
# Required-Stop: $syslog $remote_fs
|
||||
# Should-Stop: ypbind smtp
|
||||
# Default-Start: 3 5
|
||||
# Default-Stop: 0 1 2 6
|
||||
# Short-Description: Application Container Server for Networked/Clustered Web Applications
|
||||
# Description: Application Container Server for Networked/Clustered Web Applications
|
||||
### END INIT INFO
|
||||
|
||||
# Check for missing binaries (stale symlinks should not happen)
|
||||
UWSGI_BIN=/usr/bin/uwsgi
|
||||
test -x $UWSGI_BIN || { echo "$UWSGI_BIN not installed";
|
||||
if [ "$1" = "stop" ]; then exit 0;
|
||||
else exit 5; fi; }
|
||||
|
||||
UWSGI_EMPEROR_MODE=true
|
||||
UWSGI_VASSALS="/etc/uwsgi/"
|
||||
UWSGI_OPTIONS="--logto /var/log/uwsgi/uwsgi.log"
|
||||
|
||||
|
||||
UWSGI_OPTIONS="$UWSGI_OPTIONS --autoload"
|
||||
|
||||
if [ "$UWSGI_EMPEROR_MODE" = "true" ] ; then
|
||||
UWSGI_OPTIONS="$UWSGI_OPTIONS --emperor $UWSGI_VASSALS"
|
||||
fi
|
||||
|
||||
. /etc/rc.status
|
||||
|
||||
rc_reset
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
echo -n "Starting uWSGI "
|
||||
/sbin/startproc $UWSGI_BIN $UWSGI_OPTIONS
|
||||
rc_status -v
|
||||
;;
|
||||
stop)
|
||||
echo -n "Shutting down uWSGI "
|
||||
/sbin/killproc $UWSGI_BIN
|
||||
rc_status -v
|
||||
;;
|
||||
try-restart|condrestart)
|
||||
if test "$1" = "condrestart"; then
|
||||
echo "${attn} Use try-restart ${done}(LSB)${attn} rather than condrestart ${warn}(RH)${norm}"
|
||||
fi
|
||||
$0 status
|
||||
if test $? = 0; then
|
||||
$0 restart
|
||||
else
|
||||
rc_reset
|
||||
fi
|
||||
rc_status
|
||||
;;
|
||||
restart)
|
||||
$0 stop
|
||||
$0 start
|
||||
rc_status
|
||||
;;
|
||||
force-reload)
|
||||
echo -n "Reload service uWSGI "
|
||||
/sbin/killproc -HUP $UWSGI_BIN
|
||||
rc_status -v
|
||||
;;
|
||||
reload)
|
||||
echo -n "Reload service uWSGI "
|
||||
/sbin/killproc -HUP $UWSGI_BIN
|
||||
rc_status -v
|
||||
;;
|
||||
status)
|
||||
echo -n "Checking for service uWSGI "
|
||||
/sbin/checkproc $UWSGI_BIN
|
||||
rc_status -v
|
||||
;;
|
||||
probe)
|
||||
echo -n "uWSGI does not support probe "
|
||||
rc_failed 3
|
||||
rc_status -v
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload|probe}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
rc_exit '> /etc/init.d/uwsgi
|
||||
|
||||
|
||||
chmod +x /etc/init.d/uwsgi
|
||||
/etc/init.d/uwsgi start
|
||||
/etc/init.d/nginx restart
|
||||
|
||||
|
||||
chkconfig --add uwsgi
|
||||
chkconfig --add nginx
|
||||
|
||||
## you can reload uwsgi with
|
||||
#/etc/init.d/uwsgi restart
|
||||
## to reload web2py only (without restarting uwsgi)
|
||||
# touch /etc/uwsgi/web2py.xml
|
||||
Reference in New Issue
Block a user