diff --git a/Makefile b/Makefile
index d764297d..3193225d 100644
--- a/Makefile
+++ b/Makefile
@@ -29,7 +29,7 @@ update:
wget -O gluon/contrib/simplejsonrpc.py http://rad2py.googlecode.com/hg/ide2py/simplejsonrpc.py
echo "remember that pymysql was tweaked"
src:
- echo 'Version 2.0.9 ('`date +%Y-%m-%d\ %H:%M:%S`') stable' > VERSION
+ echo 'Version 2.0.9 ('`date +%Y-%m-%d\ %H:%M:%S`') dev' > VERSION
### rm -f all junk files
make clean
### clean up baisc apps
@@ -107,10 +107,6 @@ win:
cp applications/__init__.py ../web2py_win/web2py/applications
cd ../web2py_win; zip -r web2py_win.zip web2py
mv ../web2py_win/web2py_win.zip .
-pip:
- # create Web2py distribution for upload to Pypi
- # after upload clean Web2py sources with rm -R ./dist
- python setup.py sdist
run:
python2.5 web2py.py -a hello
commit:
@@ -129,3 +125,10 @@ tag:
hg tag -l '$(S)'
make commit S='$(S)'
make push
+pip:
+ # create Web2py distribution for upload to Pypi
+ # after upload clean Web2py sources with rm -R ./dist
+ # http://guide.python-distribute.org/creation.html
+ python setup.py sdist
+ python setup.py register
+ python setup.py sdist upload
diff --git a/VERSION b/VERSION
index 44f1be1a..e657a8d6 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-Version 2.0.9 (2012-09-21 09:37:29) stable
+Version 2.0.9 (2012-09-30 14:45:39) dev
diff --git a/applications/admin/static/js/web2py.js b/applications/admin/static/js/web2py.js
index 9a2e208c..61f45e30 100644
--- a/applications/admin/static/js/web2py.js
+++ b/applications/admin/static/js/web2py.js
@@ -39,7 +39,7 @@ function web2py_ajax_init(target) {
function web2py_event_handlers() {
var doc = jQuery(document)
- doc.on('click', '.flash', function(e){jQuery(this).fadeOut('slow'); e.preventDefault();});
+ doc.on('click', '.flash', function(e){var t=jQuery(this); if(t.css('top')=='0px') t.slideUp('slow'); else t.fadeOut(); e.preventDefault();});
doc.on('keyup', 'input.integer', function(){this.value=this.value.reverse().replace(/[^0-9\-]|\-(?=.)/g,'').reverse();});
doc.on('keyup', 'input.double, input.decimal', function(){this.value=this.value.reverse().replace(/[^0-9\-\.,]|[\-](?=.)|[\.,](?=[0-9]*[\.,])/g,'').reverse();});
var confirm_message = (typeof w2p_ajax_confirm_message != 'undefined') ? w2p_ajax_confirm_message : "Are you sure you want to delete this object?";
@@ -55,7 +55,7 @@ function web2py_event_handlers() {
jQuery(function() {
var flash = jQuery('.flash');
flash.hide();
- if(flash.html()) flash.slideDown();
+ if(flash.html()) flash.append('×').slideDown();
web2py_ajax_init(document);
web2py_event_handlers();
});
@@ -67,20 +67,20 @@ function web2py_trap_form(action,target) {
form.submit(function(e){
jQuery('.flash').hide().html('');
web2py_ajax_page('post',action,form.serialize(),target);
- e.preventDefault();
+ e.preventDefault();
});
});
}
function web2py_trap_link(target) {
jQuery('#'+target+' a.w2p_trap').each(function(i){
- var link=jQuery(this);
- link.click(function(e) {
- jQuery('.flash').hide().html('');
- web2py_ajax_page('get',link.attr('href'),[],target);
- e.preventDefault();
- });
- });
+ var link=jQuery(this);
+ link.click(function(e) {
+ jQuery('.flash').hide().html('');
+ web2py_ajax_page('get',link.attr('href'),[],target);
+ e.preventDefault();
+ });
+ });
}
function web2py_ajax_page(method, action, data, target) {
@@ -101,9 +101,9 @@ function web2py_ajax_page(method, action, data, target) {
web2py_trap_link(target);
web2py_ajax_init('#'+target);
if(command)
- eval(decodeURIComponent(command));
+ eval(decodeURIComponent(command));
if(flash)
- jQuery('.flash').html(decodeURIComponent(flash)).slideDown();
+ jQuery('.flash').html(decodeURIComponent(flash)).slideDown();
}
});
}
@@ -151,11 +151,11 @@ function web2py_component(action, target, timeout, times){
}
} else {
// run once (no timeout specified)
- element.reload_counter = Infinity;
+ element.reload_counter = Infinity;
web2py_ajax_page('get', action, null, target);
} }); }
-function web2py_comet(url,onmessage,onopen,onclose) {
+function web2py_websocket(url,onmessage,onopen,onclose) {
if ("WebSocket" in window) {
var ws = new WebSocket(url);
ws.onopen = onopen?onopen:(function(){});
@@ -165,3 +165,38 @@ function web2py_comet(url,onmessage,onopen,onclose) {
} else return false; // not supported
}
+
+function web2py_calc_entropy(mystring) {
+ //calculate a simple entropy for a given string
+ var csets = new Array(
+ 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
+ '0123456789', '!@#$\%^&*()', '~`-_=+[]{}\|;:\'",.<>?/',
+ '0123456789abcdefghijklmnopqrstuvwxyz');
+ var score = 0, other = {}, seen = {}, lastset = null, mystringlist = mystring.split('');
+ for (var i=0;i×').slideDown();
web2py_ajax_init(document);
web2py_event_handlers();
});
@@ -67,20 +67,20 @@ function web2py_trap_form(action,target) {
form.submit(function(e){
jQuery('.flash').hide().html('');
web2py_ajax_page('post',action,form.serialize(),target);
- e.preventDefault();
+ e.preventDefault();
});
});
}
function web2py_trap_link(target) {
jQuery('#'+target+' a.w2p_trap').each(function(i){
- var link=jQuery(this);
- link.click(function(e) {
- jQuery('.flash').hide().html('');
- web2py_ajax_page('get',link.attr('href'),[],target);
- e.preventDefault();
- });
- });
+ var link=jQuery(this);
+ link.click(function(e) {
+ jQuery('.flash').hide().html('');
+ web2py_ajax_page('get',link.attr('href'),[],target);
+ e.preventDefault();
+ });
+ });
}
function web2py_ajax_page(method, action, data, target) {
@@ -101,9 +101,9 @@ function web2py_ajax_page(method, action, data, target) {
web2py_trap_link(target);
web2py_ajax_init('#'+target);
if(command)
- eval(decodeURIComponent(command));
+ eval(decodeURIComponent(command));
if(flash)
- jQuery('.flash').html(decodeURIComponent(flash)).slideDown();
+ jQuery('.flash').html(decodeURIComponent(flash)).slideDown();
}
});
}
@@ -151,11 +151,11 @@ function web2py_component(action, target, timeout, times){
}
} else {
// run once (no timeout specified)
- element.reload_counter = Infinity;
+ element.reload_counter = Infinity;
web2py_ajax_page('get', action, null, target);
} }); }
-function web2py_comet(url,onmessage,onopen,onclose) {
+function web2py_websocket(url,onmessage,onopen,onclose) {
if ("WebSocket" in window) {
var ws = new WebSocket(url);
ws.onopen = onopen?onopen:(function(){});
@@ -165,3 +165,38 @@ function web2py_comet(url,onmessage,onopen,onclose) {
} else return false; // not supported
}
+
+function web2py_calc_entropy(mystring) {
+ //calculate a simple entropy for a given string
+ var csets = new Array(
+ 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
+ '0123456789', '!@#$\%^&*()', '~`-_=+[]{}\|;:\'",.<>?/',
+ '0123456789abcdefghijklmnopqrstuvwxyz');
+ var score = 0, other = {}, seen = {}, lastset = null, mystringlist = mystring.split('');
+ for (var i=0;iIan Reinhart Geiser (html helpers)
Ionel Anton (Romanian translation)
Jan Beilicke (markmin)
+Jeremy Dillworth
Jonathan Benn (is_url validator and tests)
Jonathan Lundell (multiple contributions)
Josh Goldfoot (xaml/html sanitizer)
@@ -156,6 +157,7 @@
memcache developed by Evan Martin
jQuery developed by John Resig
A syntax highlighter inspired by the code of Peter Wilkinson
+pyUCA developed by James Tauber
diff --git a/applications/welcome/models/db.py b/applications/welcome/models/db.py
index 26d28122..54a0b231 100644
--- a/applications/welcome/models/db.py
+++ b/applications/welcome/models/db.py
@@ -11,7 +11,7 @@
if not request.env.web2py_runtime_gae:
## if NOT running on Google App Engine use SQLite or other DB
- db = DAL('sqlite://storage.sqlite')
+ db = DAL('sqlite://storage.sqlite')
else:
## connect to Google BigTable (optional 'google:datastore://namespace')
db = DAL('google:datastore')
diff --git a/applications/welcome/static/css/web2py.css b/applications/welcome/static/css/web2py.css
index ac04a0f0..1ad43fd0 100644
--- a/applications/welcome/static/css/web2py.css
+++ b/applications/welcome/static/css/web2py.css
@@ -61,7 +61,7 @@ input[type=text],input[type=password],select{width:300px; margin-right:5px}
border-top:1px #DEDEDE solid;
}
.header {
- // background:;
+ /* background:; */
}
@@ -182,7 +182,7 @@ div.error {
* will look better with the declarations below
* if needed to remove base.css consider keeping these following lines in some css file.
*/
-// .web2py_table {border:1px solid #ccc}
+/* .web2py_table {border:1px solid #ccc} */
.web2py_paginator {}
.web2py_grid {width:100%}
.web2py_grid table {width:100%}
diff --git a/applications/welcome/static/css/web2py_bootstrap.css b/applications/welcome/static/css/web2py_bootstrap.css
index 36e9bf0e..ad3e8385 100644
--- a/applications/welcome/static/css/web2py_bootstrap.css
+++ b/applications/welcome/static/css/web2py_bootstrap.css
@@ -1,8 +1,8 @@
-//=======================================================
-// CUSTOM RULES
-//=======================================================
+/*=============================================================
+ CUSTOM RULES
+==============================================================*/
-body{height:auto;} // to avoid vertical scroll bar
+body{height:auto;} /* to avoid vertical scroll bar */
div.flash.flash-center{left:25%;right:25%;}
div.flash.flash-top,div.flash.flash-top:hover{
position:relative;
@@ -36,18 +36,16 @@ div.flash.flash-top,div.flash.flash-top:hover{
font-size:20px;
font-weight:300;
}
-// auth navbar - primitive style
+/* auth navbar - primitive style */
.auth_navbar,.auth_navbar a{color:inherit;}
-.ie-lte7 .auth_navbar,.auth_navbar a{color:expression(this.parentNode.currentStyle['color']); // ie7 doesn't support inherit
-}
-.auth_navbar a{white-space:nowrap;} // to avoid the nav split on more lines
+.ie-lte7 .auth_navbar,.auth_navbar a{color:expression(this.parentNode.currentStyle['color']); /* ie7 doesn't support inherit */}
+.auth_navbar a{white-space:nowrap;} /* to avoid the nav split on more lines */
.auth_navbar a:hover{color:white;text-decoration:none;}
ul#navbar>.auth_navbar{
display:inline-block;
padding:5px;
}
-
-// form errors message box customization
+/* form errors message box customization */
div.error_wrapper{margin-bottom:9px;}
div.error{
border-radius: 4px;
@@ -55,9 +53,8 @@ div.error{
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
}
-
-// below rules are only for formstyle = bootstrap
-// trying to make errors look like bootstrap ones
+/* below rules are only for formstyle = bootstrap
+trying to make errors look like bootstrap ones */
div.controls .error_wrapper{
display:inline-block;
margin-bottom:0;
@@ -70,46 +67,44 @@ div.controls .error{
border:none;
padding:0;
margin:0;
- //display:inline; // uncommenting this, the animation effect is lost
+ //display:inline; /* uncommenting this, the animation effect is lost */
}
div.controls .inline-help{color:#3A87AD;}
div.controls .error_wrapper+.inline-help{margin-left:-99999px;}
-
-// beautify brand
+/* beautify brand */
.navbar-inverse .brand{color:#c6cecc;}
.navbar-inverse .brand b{display:inline-block;margin-top:-1px;}
.navbar-inverse .brand b>span{font-size:22px;color:white}
.navbar-inverse .brand:hover b>span{color:white}
-// beautify web2py link in navbar
+/* beautify web2py link in navbar */
span.highlighted{color:#d8d800;}
.open span.highlighted{color:#ffff00;}
-//===========================================================
-// OVERRIDING WEB2PY.CSS RULES
-//===========================================================
+/*=============================================================
+ OVERRIDING WEB2PY.CSS RULES
+==============================================================*/
-// reset to default
+/* reset to default */
a{white-space:normal;}
li{margin-bottom:0;}
textarea,button{display:block;}
-// reset ul padding
+/*reset ul padding */
ul#navbar{padding:0;}
-// label aligned to related input
+/* label aligned to related input */
td.w2p_fl,td.w2p_fc {padding:0;}
#web2py_user_form td{vertical-align:middle;}
-//==========================================================
-// OVERRIDING BOOTSTRAP.CSS RULES
-//==========================================================
+/*=============================================================
+ OVERRIDING BOOTSTRAP.CSS RULES
+==============================================================*/
-// because web2py handles this via js
+/* because web2py handles this via js */
.hidden{visibility:visible;}
-
-// right folder for bootstrap black images/icons
+/* right folder for bootstrap black images/icons */
[class^="icon-"],[class*=" icon-"]{
background-image:url("../images/glyphicons-halflings.png")
}
-// right folder for bootstrap white images/icons
+/* right folder for bootstrap white images/icons */
.icon-white,
.nav-tabs > .active > a > [class^="icon-"],
.nav-tabs > .active > a > [class*=" icon-"],
@@ -125,20 +120,20 @@ td.w2p_fl,td.w2p_fc {padding:0;}
.dropdown-menu > .active > a > [class*=" icon-"] {
background-image:url("../images/glyphicons-halflings-white.png");
}
-// bootstrap has a label as input's wrapper while web2py has a div
+/* bootstrap has a label as input's wrapper while web2py has a div */
div>input[type="radio"],div>input[type="checkbox"]{margin:0;}
-// bootstrap has button instead of input
+/* bootstrap has button instead of input */
input[type="button"], input[type="submit"]{margin-right:8px;}
-//===========================================================
-// SOLVING CONFLICTS BETWEEN WEB2PY.CSS AND BOOTSTRAP.CSS
-//===========================================================
+/*=============================================================
+RULES FOR SOLVING CONFLICTS BETWEEN WEB2PY.CSS AND BOOTSTRAP.CSS
+==============================================================*/
-// when formstyle=table3cols
+/*when formstyle=table3cols*/
tr#auth_user_remember__row>td.w2p_fw>div{padding-bottom:8px;}
td.w2p_fw div>label{vertical-align:middle;}
td.w2p_fc {padding-bottom:5px;}
-// when formstyle=divs
+/*when formstyle=divs*/
div#auth_user_remember__row{margin-top:4px;}
div#auth_user_remember__row>.w2p_fl{display:none;}
div#auth_user_remember__row>.w2p_fw{min-height:39px;}
@@ -151,8 +146,7 @@ div.w2p_fc{
padding-left:5px;
margin-top:-8px;
}
-
-// when formstyle=ul
+/*when formstyle=ul*/
form>ul{
list-style:none;
margin:0;
@@ -160,30 +154,28 @@ form>ul{
li#auth_user_remember__row{margin-top:4px;}
li#auth_user_remember__row>.w2p_fl{display:none;}
li#auth_user_remember__row>.w2p_fw{min-height:39px;}
-
-// when formstyle=bootstrap
+/*when formstyle=bootstrap*/
#auth_user_remember__row label.checkbox{display:block;}
span.inline-help{display:inline-block;}
input[type="text"].input-xlarge,input[type="password"].input-xlarge{width:270px;}
-
-// when recaptcha is used
+/*when recaptcha is used*/
#recaptcha{min-height:30px;display:inline-block;margin-bottom:0;line-height:30px;vertical-align:middle;}
td>#recaptcha{margin-bottom:6px;}
div>#recaptcha{margin-bottom:9px;}
-//==========================================================
-// OTHER RULES
-//==========================================================
+/*=============================================================
+ OTHER RULES
+==============================================================*/
.navbar-inner{
- position:relative; // unnecessary
+ position:relative; /*unnecessary ??*/
}
-
-// fixed alignment in forms with list:string
+/* Massimo Di Pierro fixed alignment in forms with list:string */
form table tr{margin-bottom:9px;}
td.w2p_fw ul{margin-left:0px;}
-// web2py_console in grid and smartgrid
+/* web2py_console in grid and smartgrid */
+.hidden{visibility:visible;}
.web2py_console input{
display: inline-block;
margin-bottom: 0;
@@ -203,12 +195,12 @@ td.w2p_fw ul{margin-left:0px;}
margin:3px 0 0 2px;
}
.web2py_grid form table{width:auto;}
-// auth_user_remember checkbox extrapadding in IE fix
+/* auth_user_remember checkbox extrapadding in IE fix */
.ie-lte9 input#auth_user_remember.checkbox {padding-left:0;}
-//===========================================================
-// MEDIA QUERIES
-//===========================================================
+/*=============================================================
+ MEDIA QUERIES
+==============================================================*/
@media only screen and (max-width:979px){
body{padding-top:0px;}
diff --git a/applications/welcome/static/images/google-buzz.png b/applications/welcome/static/images/google-buzz.png
deleted file mode 100644
index 844d5412..00000000
Binary files a/applications/welcome/static/images/google-buzz.png and /dev/null differ
diff --git a/applications/welcome/static/images/gplus-32.png b/applications/welcome/static/images/gplus-32.png
new file mode 100644
index 00000000..c42eab78
Binary files /dev/null and b/applications/welcome/static/images/gplus-32.png differ
diff --git a/applications/welcome/static/js/share.js b/applications/welcome/static/js/share.js
index ab0bcf1b..5e9d2c26 100644
--- a/applications/welcome/static/js/share.js
+++ b/applications/welcome/static/js/share.js
@@ -21,8 +21,8 @@ jQuery(function(){
var title = escape(jQuery('title').text());
var twit = 'http://twitter.com/home?status='+title+'%20'+url;
var facebook = 'http://www.facebook.com/sharer.php?u='+url;
- var buzz = 'https://plus.google.com/share?url='+url;
- var tbar = '';
+ var gplus = 'https://plus.google.com/share?url='+url;
+ var tbar = '';
// Add the share tool bar.
jQuery('body').append(tbar);
var st = jQuery('#socialdrawer');
diff --git a/applications/welcome/static/js/web2py.js b/applications/welcome/static/js/web2py.js
index 4bcb2063..61f45e30 100644
--- a/applications/welcome/static/js/web2py.js
+++ b/applications/welcome/static/js/web2py.js
@@ -67,20 +67,20 @@ function web2py_trap_form(action,target) {
form.submit(function(e){
jQuery('.flash').hide().html('');
web2py_ajax_page('post',action,form.serialize(),target);
- e.preventDefault();
+ e.preventDefault();
});
});
}
function web2py_trap_link(target) {
jQuery('#'+target+' a.w2p_trap').each(function(i){
- var link=jQuery(this);
- link.click(function(e) {
- jQuery('.flash').hide().html('');
- web2py_ajax_page('get',link.attr('href'),[],target);
- e.preventDefault();
- });
- });
+ var link=jQuery(this);
+ link.click(function(e) {
+ jQuery('.flash').hide().html('');
+ web2py_ajax_page('get',link.attr('href'),[],target);
+ e.preventDefault();
+ });
+ });
}
function web2py_ajax_page(method, action, data, target) {
@@ -101,9 +101,9 @@ function web2py_ajax_page(method, action, data, target) {
web2py_trap_link(target);
web2py_ajax_init('#'+target);
if(command)
- eval(decodeURIComponent(command));
+ eval(decodeURIComponent(command));
if(flash)
- jQuery('.flash').html(decodeURIComponent(flash)).slideDown();
+ jQuery('.flash').html(decodeURIComponent(flash)).slideDown();
}
});
}
@@ -151,11 +151,11 @@ function web2py_component(action, target, timeout, times){
}
} else {
// run once (no timeout specified)
- element.reload_counter = Infinity;
+ element.reload_counter = Infinity;
web2py_ajax_page('get', action, null, target);
} }); }
-function web2py_comet(url,onmessage,onopen,onclose) {
+function web2py_websocket(url,onmessage,onopen,onclose) {
if ("WebSocket" in window) {
var ws = new WebSocket(url);
ws.onopen = onopen?onopen:(function(){});
@@ -165,3 +165,38 @@ function web2py_comet(url,onmessage,onopen,onclose) {
} else return false; // not supported
}
+
+function web2py_calc_entropy(mystring) {
+ //calculate a simple entropy for a given string
+ var csets = new Array(
+ 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
+ '0123456789', '!@#$\%^&*()', '~`-_=+[]{}\|;:\'",.<>?/',
+ '0123456789abcdefghijklmnopqrstuvwxyz');
+ var score = 0, other = {}, seen = {}, lastset = null, mystringlist = mystring.split('');
+ for (var i=0;ili>a').each(function(){
+ if(jQuery(this).parent().find('ul').length)
+ jQuery(this).attr({'class':'dropdown-toggle','data-toggle':'dropdown'}).append('');
+ });
+ jQuery('.nav li li').each(function(){
+ if(jQuery(this).find('ul').length)
+ jQuery(this).addClass('dropdown-submenu');
+ });
+ function hoverMenu(){
+ var wid = document.documentElement.clientWidth; //faster than $(window).width() and cross browser
+ if (wid>=980){
+ jQuery('ul.nav a.dropdown-toggle').parent().hover(function(){
+ 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');
+});
diff --git a/applications/welcome/views/default/user.html b/applications/welcome/views/default/user.html
index ef00c0e6..475be5b3 100644
--- a/applications/welcome/views/default/user.html
+++ b/applications/welcome/views/default/user.html
@@ -15,92 +15,9 @@ pass
-
+{{if request.args(0)=='register':}}
+ web2py_validate_entropy(jQuery('#auth_user_password'),100);
+{{elif request.args(0)=='change_password':}}
+ web2py_validate_entropy(jQuery('#no_table_new_password'),100);
+{{pass}}
+//-->
diff --git a/applications/welcome/views/layout.html b/applications/welcome/views/layout.html
index 19225730..ad0d0d9e 100644
--- a/applications/welcome/views/layout.html
+++ b/applications/welcome/views/layout.html
@@ -39,7 +39,7 @@
- {{
+ {{
response.files.append(URL('static','css/web2py.css'))
response.files.append(URL('static','css/bootstrap.min.css'))
response.files.append(URL('static','css/bootstrap-responsive.min.css'))
@@ -71,11 +71,11 @@
-
+
+
web2py™
{{='auth' in globals() and auth.navbar(mode="dropdown") or ''}}
@@ -146,32 +146,8 @@
-
+