Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
58533954dc | ||
|
|
236dc4b943 | ||
|
|
6612fd1cfe | ||
|
|
520950ba74 | ||
|
|
e943aa9c25 | ||
|
|
756aec7206 | ||
|
|
970e2ed35c | ||
|
|
1388c39636 | ||
|
|
6e84737924 | ||
|
|
0ad50630f2 | ||
|
|
f42ee15f5f | ||
|
|
2b0bfba649 | ||
|
|
9f1edf267d | ||
|
|
f3bda9ad02 | ||
|
|
f8afc76263 | ||
|
|
65b4aaf842 | ||
|
|
1b729cfbfc | ||
|
|
1aa5f30091 | ||
|
|
b17174c04c | ||
|
|
ac80adc9b4 | ||
|
|
888fa3dfc8 | ||
|
|
f3d815e84b | ||
|
|
9915fdf093 | ||
|
|
ef8f802df9 | ||
|
|
f7bf1020df | ||
|
|
75b8ceb022 | ||
|
|
b4f3784136 | ||
|
|
f1297bb827 | ||
|
|
435ebeaae4 | ||
|
|
537045082c | ||
|
|
4bea52a7b5 | ||
|
|
33295e516f | ||
|
|
f33ccf3366 | ||
|
|
0784680c90 | ||
|
|
e940228eaf | ||
|
|
50769a627a | ||
|
|
e68ecaa131 | ||
|
|
95e6e8577b | ||
|
|
19c83d4ad6 | ||
|
|
9c92bd1050 | ||
|
|
b3b95ccf5f | ||
|
|
cefa30841b | ||
|
|
15ff8669cb | ||
|
|
a921751e8e | ||
|
|
b02e8a6d5f | ||
|
|
a2b17967cf | ||
|
|
343ebf1714 | ||
|
|
e330791fe3 | ||
|
|
5e1e97ffc4 | ||
|
|
60f8816a10 | ||
|
|
6187c89ba6 | ||
|
|
e441e15907 | ||
|
|
e6c3410639 | ||
|
|
6b6cb5839c | ||
|
|
2a7e9c0c59 | ||
|
|
5b637c0a82 | ||
|
|
5cdd7c1215 | ||
|
|
0aade6b378 | ||
|
|
5b75130187 |
No files matched your search
@@ -1,4 +1,4 @@
|
||||
## 2.10.1
|
||||
## 2.10.1-2.10.2
|
||||
|
||||
- welcome app defaults to Bootstrap 3
|
||||
- DAL -> pyDAL (thanks Giovanni, Niphlod, Paolo)
|
||||
|
||||
@@ -32,7 +32,7 @@ update:
|
||||
echo "remember that pymysql was tweaked"
|
||||
src:
|
||||
### Use semantic versioning
|
||||
echo 'Version 2.10.1-stable+timestamp.'`date +%Y.%m.%d.%H.%M.%S` > VERSION
|
||||
echo 'Version 2.10.4-beta+timestamp.'`date +%Y.%m.%d.%H.%M.%S` > VERSION
|
||||
### rm -f all junk files
|
||||
make clean
|
||||
### clean up baisc apps
|
||||
|
||||
@@ -1 +1 @@
|
||||
Version 2.10.1-stable+timestamp.2015.03.31.15.15.31
|
||||
Version 2.10.4-stable+timestamp.2015.04.26.09.05.21
|
||||
@@ -180,6 +180,11 @@ class Servers:
|
||||
s = wsgi.WSGIServer(callable=app, bind="%s:%d" % address)
|
||||
s.start()
|
||||
|
||||
@staticmethod
|
||||
def waitress(app, address, **options):
|
||||
from waitress import serve
|
||||
serve(app, host=address[0], port=address[1], _quiet=True)
|
||||
|
||||
|
||||
def mongrel2_handler(application, conn, debug=False):
|
||||
"""
|
||||
|
||||
+4
-4
@@ -1,4 +1,4 @@
|
||||
/*! jQuery v1.11.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */
|
||||
!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.1",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b=a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C="undefined",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",N="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=N.replace("w","w#"),P="\\["+M+"*("+N+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"Line truncated
|
||||
if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?m.queue(this[0],a):void 0===b?this:this.each(function(){var c=m.queue(this,a,b);m._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&m.dequeue(this,a)})},dequeue:function(a){return this.each(function(){m.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=m.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=m._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=["Top","Right","Bottom","Left"],U=function(a,b){return a=b||a,"none"===m.css(a,"display")||!m.contains(a.ownerDocument,a)},V=m.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===m.type(c)){e=!0;for(h in c)m.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,m.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(m(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav></:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function ab(){return!0}function bb(){return!1}function cb(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=rLine truncated
|
||||
},cur:function(){var a=Zb.propHooks[this.prop];return a&&a.get?a.get(this):Zb.propHooks._default.get(this)},run:function(a){var b,c=Zb.propHooks[this.prop];return this.pos=b=this.options.duration?m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Zb.propHooks._default.set(this),this}},Zb.prototype.init.prototype=Zb.prototype,Zb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Zb.propHooks.scrollTop=Zb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Zb.prototype.init,m.fx.step={};var $b,_b,ac=/^(?:toggle|show|hide)$/,bc=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cc=/queueHooks$/,dc=[ic],ec={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bc.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bc.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fc(){return setTimeout(function(){$b=void 0}),$b=m.now()}function gc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hc(a,b,c){for(var d,e=(ec[b]||[]).concat(ec["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ic(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fb(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fb(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ac.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fb(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hc(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jc(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kc(a,b,c){var d,e,f=0,g=dc.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$b||fc(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$b||fc(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jc(k,j.opts.specialEasing);g>f;f++)if(d=dc[f].call(j,a,k,j.opts))return d;return m.map(k,hc,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kc,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],ec[c]=ec[c]||[],ec[c].unshift(b)},prefilter:function(a,b){b?dc.unshift(a):dc.push(a)}}),m.speed=function(a,b,c){var d=a&&"object"==typeof a?m.extend({},a):{complete:c||!c&&b||m.isFunction(a)&&a,duration:a,easing:c&&b||b&&!m.isFunction(b)&&b};return d.duration=m.fLine truncated
|
||||
/*! jQuery v1.11.2 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */
|
||||
!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.2",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b=a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=hb(),z=hb(),A=hb(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(Line truncated
|
||||
return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?m.queue(this[0],a):void 0===b?this:this.each(function(){var c=m.queue(this,a,b);m._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&m.dequeue(this,a)})},dequeue:function(a){return this.each(function(){m.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=m.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=m._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=["Top","Right","Bottom","Left"],U=function(a,b){return a=b||a,"none"===m.css(a,"display")||!m.contains(a.ownerDocument,a)},V=m.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===m.type(c)){e=!0;for(h in c)m.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,m.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(m(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav></:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function ab(){return!0}function bb(){return!1}function cb(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var
Line truncated
|
||||
}m.Tween=Zb,Zb.prototype={constructor:Zb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")},cur:function(){var a=Zb.propHooks[this.prop];return a&&a.get?a.get(this):Zb.propHooks._default.get(this)},run:function(a){var b,c=Zb.propHooks[this.prop];return this.pos=b=this.options.duration?m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Zb.propHooks._default.set(this),this}},Zb.prototype.init.prototype=Zb.prototype,Zb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Zb.propHooks.scrollTop=Zb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Zb.prototype.init,m.fx.step={};var $b,_b,ac=/^(?:toggle|show|hide)$/,bc=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cc=/queueHooks$/,dc=[ic],ec={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bc.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bc.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fc(){return setTimeout(function(){$b=void 0}),$b=m.now()}function gc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hc(a,b,c){for(var d,e=(ec[b]||[]).concat(ec["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ic(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fb(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fb(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ac.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fb(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hc(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jc(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kc(a,b,c){var d,e,f=0,g=dc.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$b||fc(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$b||fc(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jc(k,j.opts.specialEasing);g>f;f++)if(d=dc[f].call(j,a,k,j.opts))return d;return m.map(k,hc,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kc,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],ec[c]=ec[c]||[],ec[c].unshift(b)},prefilter:function(aLine truncated
|
||||
@@ -18,7 +18,7 @@
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" id="alltables">
|
||||
<table>
|
||||
<table class="table">
|
||||
{{for db in sorted(databases):}}
|
||||
{{for table in databases[db].tables:}}
|
||||
{{qry='%s.%s.id>0'%(db,table)}}
|
||||
@@ -40,7 +40,7 @@
|
||||
{{=A("%s.%s" % (db,table),_href=URL('select',args=[db],vars=dict(query=qry)))}}
|
||||
</th>
|
||||
<td>
|
||||
{{=A(str(T('New Record')),_href=URL('insert',args=[db,table]),_class="btn")}}
|
||||
{{=A(str(T('New Record')),_href=URL('insert',args=[db,table]),_class="btn btn-default")}}
|
||||
</td>
|
||||
</tr>
|
||||
{{pass}}
|
||||
@@ -61,7 +61,7 @@
|
||||
</pre>
|
||||
{{pass}}
|
||||
{{if table:}}
|
||||
{{=A(str(T('New Record')),_href=URL('insert',args=[request.args[0],table]),_class="btn")}}<br/><br/>
|
||||
{{=A(str(T('New Record')),_href=URL('insert',args=[request.args[0],table]),_class="btn btn-default")}}<br/><br/>
|
||||
<h3>{{=T("Rows in Table")}}</h3><br/>
|
||||
{{else:}}
|
||||
<h3>{{=T("Rows selected")}}</h3><br/>
|
||||
@@ -72,8 +72,8 @@
|
||||
{{=T('"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN')}}</p>
|
||||
<br/><br/>
|
||||
<h4>{{=T("%s selected", nrows)}}</h4>
|
||||
{{if start>0:}}{{=A(T('previous %s rows') % step,_href=URL('select',args=request.args[0],vars=dict(start=start-step)),_class="btn")}}{{pass}}
|
||||
{{if stop<nrows:}}{{=A(T('next %s rows') % step,_href=URL('select',args=request.args[0],vars=dict(start=start+step)),_class="btn")}}{{pass}}
|
||||
{{if start>0:}}{{=A(T('previous %s rows') % step,_href=URL('select',args=request.args[0],vars=dict(start=start-step)),_class="btn btn-default")}}{{pass}}
|
||||
{{if stop<nrows:}}{{=A(T('next %s rows') % step,_href=URL('select',args=request.args[0],vars=dict(start=start+step)),_class="btn btn-default")}}{{pass}}
|
||||
{{if rows:}}
|
||||
<div style="overflow:auto; width:80%;">
|
||||
{{linkto = lambda f, t, r: URL('update', args=[request.args[0], r, f]) if f else "#"}}
|
||||
@@ -82,7 +82,7 @@
|
||||
</div>
|
||||
{{pass}}
|
||||
<br/><br/><h3>{{=T("Import/Export")}}</h3><br/>
|
||||
<a href="{{=URL('csv',args=request.args[0],vars=dict(query=query))}}" class="btn">{{=T("export as csv file")}}</a>
|
||||
<a href="{{=URL('csv',args=request.args[0],vars=dict(query=query))}}" class="btn btn-default">{{=T("export as csv file")}}</a>
|
||||
{{=formcsv or ''}}
|
||||
|
||||
{{elif request.function=='insert':}}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" id="alltables">
|
||||
<table>
|
||||
<table class="table">
|
||||
{{for db in sorted(databases):}}
|
||||
{{for table in databases[db].tables:}}
|
||||
{{qry='%s.%s.id>0'%(db,table)}}
|
||||
@@ -40,7 +40,7 @@
|
||||
{{=A("%s.%s" % (db,table),_href=URL('select',args=[db],vars=dict(query=qry)))}}
|
||||
</th>
|
||||
<td>
|
||||
{{=A(str(T('New Record')),_href=URL('insert',args=[db,table]),_class="btn")}}
|
||||
{{=A(str(T('New Record')),_href=URL('insert',args=[db,table]),_class="btn btn-default")}}
|
||||
</td>
|
||||
</tr>
|
||||
{{pass}}
|
||||
@@ -61,7 +61,7 @@
|
||||
</pre>
|
||||
{{pass}}
|
||||
{{if table:}}
|
||||
{{=A(str(T('New Record')),_href=URL('insert',args=[request.args[0],table]),_class="btn")}}<br/><br/>
|
||||
{{=A(str(T('New Record')),_href=URL('insert',args=[request.args[0],table]),_class="btn btn-default")}}<br/><br/>
|
||||
<h3>{{=T("Rows in Table")}}</h3><br/>
|
||||
{{else:}}
|
||||
<h3>{{=T("Rows selected")}}</h3><br/>
|
||||
@@ -72,8 +72,8 @@
|
||||
{{=T('"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN')}}</p>
|
||||
<br/><br/>
|
||||
<h4>{{=T("%s selected", nrows)}}</h4>
|
||||
{{if start>0:}}{{=A(T('previous %s rows') % step,_href=URL('select',args=request.args[0],vars=dict(start=start-step)),_class="btn")}}{{pass}}
|
||||
{{if stop<nrows:}}{{=A(T('next %s rows') % step,_href=URL('select',args=request.args[0],vars=dict(start=start+step)),_class="btn")}}{{pass}}
|
||||
{{if start>0:}}{{=A(T('previous %s rows') % step,_href=URL('select',args=request.args[0],vars=dict(start=start-step)),_class="btn btn-default")}}{{pass}}
|
||||
{{if stop<nrows:}}{{=A(T('next %s rows') % step,_href=URL('select',args=request.args[0],vars=dict(start=start+step)),_class="btn btn-default")}}{{pass}}
|
||||
{{if rows:}}
|
||||
<div style="overflow:auto; width:80%;">
|
||||
{{linkto = lambda f, t, r: URL('update', args=[request.args[0], r, f]) if f else "#"}}
|
||||
@@ -82,7 +82,7 @@
|
||||
</div>
|
||||
{{pass}}
|
||||
<br/><br/><h3>{{=T("Import/Export")}}</h3><br/>
|
||||
<a href="{{=URL('csv',args=request.args[0],vars=dict(query=query))}}" class="btn">{{=T("export as csv file")}}</a>
|
||||
<a href="{{=URL('csv',args=request.args[0],vars=dict(query=query))}}" class="btn btn-default">{{=T("export as csv file")}}</a>
|
||||
{{=formcsv or ''}}
|
||||
|
||||
{{elif request.function=='insert':}}
|
||||
|
||||
@@ -33,6 +33,9 @@
|
||||
<li><a target="_blank" href="https://loadinfo-net.appspot.com">LoadInfo</a> (Bulgaria)</li>
|
||||
<li><a target="_blank" href="http://www.appliedobjects.com">Applied Objects</a> (New Zealand)</li>
|
||||
<li><a target="_blank" href="http://www.sistemasagiles.com.ar/">Sistemas Ágiles</a> ("Agile Systems") (Argentina)</li>
|
||||
<li><a target="_blank" href="http://www.definescope.com/en/services/consulting/">DefineScope</a> (Portugal)</li>
|
||||
<li><a target="_blank" href="http://10Biosystems.com">10BioSystems</a></li>
|
||||
<li><a target="_blank" href="http://www.dutveul.nl">Dutveul</a> (Netherlands)</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -62,7 +62,7 @@ auth.define_tables(username=False, signature=False)
|
||||
|
||||
## configure email
|
||||
mail = auth.settings.mailer
|
||||
mail.settings.server = 'logging' if request.is_local else myconf.take('smtp.sender')
|
||||
mail.settings.server = 'logging' if request.is_local else myconf.take('smtp.server')
|
||||
mail.settings.sender = myconf.take('smtp.sender')
|
||||
mail.settings.login = myconf.take('smtp.login')
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!-- app configuration for web2py on IIS -->
|
||||
<configuration>
|
||||
<appSettings>
|
||||
<add key="WSGI_HANDLER" value="gluon.main.wsgibase" />
|
||||
<add key="WSGI_RESTART_FILE_REGEX" value=".*((routes\.py)|(\.config))$" />
|
||||
</appSettings>
|
||||
<system.webServer>
|
||||
<rewrite>
|
||||
<rules>
|
||||
<clear />
|
||||
<rule name="static" enabled="true" stopProcessing="true">
|
||||
<match url="^(\w+)/static(?:/_[\d]+\.[\d]+\.[\d]+)?/(.*)$" />
|
||||
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
|
||||
<action type="Rewrite" url="applications/{R:1}/static/{R:2}" logRewrittenUrl="false" />
|
||||
</rule>
|
||||
<rule name="web2py_app" enabled="true" stopProcessing="true">
|
||||
<match url="(.*)" ignoreCase="false" />
|
||||
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
|
||||
<action type="Rewrite" url="handler.web2py/{R:1}" appendQueryString="true" />
|
||||
</rule>
|
||||
</rules>
|
||||
<outboundRules>
|
||||
<rule name="static_version_cache_control" preCondition="static_version">
|
||||
<match serverVariable="RESPONSE_Cache-Control" pattern=".*" />
|
||||
<action type="Rewrite" value="max-age=315360000" />
|
||||
<conditions>
|
||||
</conditions>
|
||||
</rule>
|
||||
<rule name="static_version_Expires" preCondition="static_version">
|
||||
<match serverVariable="RESPONSE_Expires" pattern=".*" />
|
||||
<action type="Rewrite" value="Thu, 31 Dec 2037 23:59:59 GMT" />
|
||||
</rule>
|
||||
<preConditions>
|
||||
<preCondition name="static_version">
|
||||
<add input="{REQUEST_URI}" pattern="(\w+)/static(?:/_[\d]+\.[\d]+\.[\d]+)?/(.*)$" />
|
||||
</preCondition>
|
||||
</preConditions>
|
||||
</outboundRules>
|
||||
</rewrite>
|
||||
<handlers>
|
||||
<!-- replace SCRIPT_PROCESSOR with the configured handler for python -->
|
||||
<add name="Python_via_FastCGI" path="handler.web2py" verb="*" modules="FastCgiModule" scriptProcessor="SCRIPT_PROCESSOR" resourceType="Unspecified" requireAccess="Script" />
|
||||
</handlers>
|
||||
</system.webServer>
|
||||
</configuration>
|
||||
+5
-2
@@ -21,6 +21,7 @@ from gluon.fileutils import up, fix_newlines, abspath, recursive_unlink
|
||||
from gluon.fileutils import read_file, write_file, parse_version
|
||||
from gluon.restricted import RestrictedError
|
||||
from gluon.settings import global_settings
|
||||
from gluon.cache import CacheOnDisk
|
||||
|
||||
|
||||
if not global_settings.web2py_runtime_gae:
|
||||
@@ -113,16 +114,18 @@ def app_cleanup(app, request):
|
||||
for f in os.listdir(path):
|
||||
try:
|
||||
if f[:1] != '.': recursive_unlink(os.path.join(path, f))
|
||||
except IOError:
|
||||
except (OSError, IOError):
|
||||
r = False
|
||||
|
||||
# Remove cache files
|
||||
path = apath('%s/cache/' % app, request)
|
||||
CacheOnDisk(folder=path).clear()
|
||||
|
||||
if os.path.exists(path):
|
||||
for f in os.listdir(path):
|
||||
try:
|
||||
if f[:1] != '.': recursive_unlink(os.path.join(path, f))
|
||||
except IOError:
|
||||
except (OSError, IOError):
|
||||
r = False
|
||||
return r
|
||||
|
||||
|
||||
+2
-2
@@ -99,7 +99,7 @@ class CacheAbstract(object):
|
||||
"""
|
||||
|
||||
cache_stats_name = 'web2py_cache_statistics'
|
||||
max_ram_utilization = 90 # percent
|
||||
max_ram_utilization = None # percent
|
||||
|
||||
def __init__(self, request=None):
|
||||
"""Initializes the object
|
||||
@@ -353,7 +353,7 @@ class CacheOnDisk(CacheAbstract):
|
||||
raise KeyError
|
||||
|
||||
self.wait_portalock(val_file)
|
||||
value = pickle.load(recfile.open(key, 'rb', path=self.folder))
|
||||
value = pickle.load(val_file)
|
||||
val_file.close()
|
||||
return value
|
||||
|
||||
|
||||
Executable → Regular
+48
-22
@@ -9,7 +9,7 @@ Required: Python 2.4 or later
|
||||
Recommended: iconv_codec <http://cjkpython.i18n.org/>
|
||||
"""
|
||||
|
||||
__version__ = "5.1.2"
|
||||
__version__ = "5.1.3"
|
||||
__license__ = """
|
||||
Copyright (c) 2010-2012 Kurt McKee <contactme@kurtmckee.org>
|
||||
Copyright (c) 2002-2008 Mark Pilgrim
|
||||
@@ -44,7 +44,8 @@ __contributors__ = ["Jason Diamond <http://injektilo.org/>",
|
||||
"Sam Ruby <http://intertwingly.net/>",
|
||||
"Ade Oshineye <http://blog.oshineye.com/>",
|
||||
"Martin Pool <http://sourcefrog.net/>",
|
||||
"Kurt McKee <http://kurtmckee.org/>"]
|
||||
"Kurt McKee <http://kurtmckee.org/>",
|
||||
"Bernd Schlapsi <https://github.com/brot>",]
|
||||
|
||||
# HTTP "User-Agent" header to send to servers when downloading feeds.
|
||||
# If you are embedding feedparser in a larger application, you should
|
||||
@@ -1971,6 +1972,7 @@ class _BaseHTMLProcessor(sgmllib.SGMLParser):
|
||||
def handle_charref(self, ref):
|
||||
# called for each character reference, e.g. for ' ', ref will be '160'
|
||||
# Reconstruct the original character reference.
|
||||
ref = ref.lower()
|
||||
if ref.startswith('x'):
|
||||
value = int(ref[1:], 16)
|
||||
else:
|
||||
@@ -2455,7 +2457,10 @@ class _MicroformatsParser:
|
||||
linktype.startswith('video/') or \
|
||||
(linktype.startswith('application/') and not linktype.endswith('xml')):
|
||||
return 1
|
||||
path = urlparse.urlparse(attrsD['href'])[2]
|
||||
try:
|
||||
path = urlparse.urlparse(attrsD['href'])[2]
|
||||
except ValueError:
|
||||
return 0
|
||||
if path.find('.') == -1:
|
||||
return 0
|
||||
fileext = path.split('.').pop().lower()
|
||||
@@ -2541,7 +2546,8 @@ class _RelativeURIResolver(_BaseHTMLProcessor):
|
||||
('object', 'data'),
|
||||
('object', 'usemap'),
|
||||
('q', 'cite'),
|
||||
('script', 'src')])
|
||||
('script', 'src'),
|
||||
('video', 'poster')])
|
||||
|
||||
def __init__(self, baseuri, encoding, _type):
|
||||
_BaseHTMLProcessor.__init__(self, encoding, _type)
|
||||
@@ -2618,13 +2624,13 @@ class _HTMLSanitizer(_BaseHTMLProcessor):
|
||||
'loop', 'loopcount', 'loopend', 'loopstart', 'low', 'lowsrc', 'max',
|
||||
'maxlength', 'media', 'method', 'min', 'multiple', 'name', 'nohref',
|
||||
'noshade', 'nowrap', 'open', 'optimum', 'pattern', 'ping', 'point-size',
|
||||
'prompt', 'pqg', 'radiogroup', 'readonly', 'rel', 'repeat-max',
|
||||
'repeat-min', 'replace', 'required', 'rev', 'rightspacing', 'rows',
|
||||
'rowspan', 'rules', 'scope', 'selected', 'shape', 'size', 'span', 'src',
|
||||
'start', 'step', 'summary', 'suppress', 'tabindex', 'target', 'template',
|
||||
'title', 'toppadding', 'type', 'unselectable', 'usemap', 'urn', 'valign',
|
||||
'value', 'variable', 'volume', 'vspace', 'vrml', 'width', 'wrap',
|
||||
'xml:lang'])
|
||||
'poster', 'pqg', 'preload', 'prompt', 'radiogroup', 'readonly', 'rel',
|
||||
'repeat-max', 'repeat-min', 'replace', 'required', 'rev', 'rightspacing',
|
||||
'rows', 'rowspan', 'rules', 'scope', 'selected', 'shape', 'size', 'span',
|
||||
'src', 'start', 'step', 'summary', 'suppress', 'tabindex', 'target',
|
||||
'template', 'title', 'toppadding', 'type', 'unselectable', 'usemap',
|
||||
'urn', 'valign', 'value', 'variable', 'volume', 'vspace', 'vrml',
|
||||
'width', 'wrap', 'xml:lang'])
|
||||
|
||||
unacceptable_elements_with_end_tag = set(['script', 'applet', 'style'])
|
||||
|
||||
@@ -2976,9 +2982,9 @@ def _open_resource(url_file_stream_or_string, etag, modified, agent, referrer, h
|
||||
url_file_stream_or_string = 'http:' + url_file_stream_or_string[5:]
|
||||
if not agent:
|
||||
agent = USER_AGENT
|
||||
# test for inline user:password for basic auth
|
||||
# Test for inline user:password credentials for HTTP basic auth
|
||||
auth = None
|
||||
if base64:
|
||||
if base64 and not url_file_stream_or_string.startswith('ftp:'):
|
||||
urltype, rest = urllib.splittype(url_file_stream_or_string)
|
||||
realhost, rest = urllib.splithost(rest)
|
||||
if realhost:
|
||||
@@ -3471,15 +3477,7 @@ _rfc822_match = re.compile(
|
||||
"(?:%s, )?%s(?: %s)?" % (_rfc822_dayname, _rfc822_date, _rfc822_time)
|
||||
).match
|
||||
|
||||
def _parse_date_rfc822(dt):
|
||||
"""Parse RFC 822 dates and times, with one minor
|
||||
difference: years may be 4DIGIT or 2DIGIT.
|
||||
http://tools.ietf.org/html/rfc822#section-5"""
|
||||
try:
|
||||
m = _rfc822_match(dt.lower()).groupdict(0)
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
def _parse_date_group_rfc822(m):
|
||||
# Calculate a date and timestamp
|
||||
for k in ('year', 'day', 'hour', 'minute', 'second'):
|
||||
m[k] = int(m[k])
|
||||
@@ -3512,8 +3510,36 @@ def _parse_date_rfc822(dt):
|
||||
|
||||
# Return the date and timestamp in UTC
|
||||
return (stamp - delta).utctimetuple()
|
||||
|
||||
def _parse_date_rfc822(dt):
|
||||
"""Parse RFC 822 dates and times, with one minor
|
||||
difference: years may be 4DIGIT or 2DIGIT.
|
||||
http://tools.ietf.org/html/rfc822#section-5"""
|
||||
try:
|
||||
m = _rfc822_match(dt.lower()).groupdict(0)
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
return _parse_date_group_rfc822(m)
|
||||
registerDateHandler(_parse_date_rfc822)
|
||||
|
||||
def _parse_date_rfc822_grubby(dt):
|
||||
"""Parse date format similar to RFC 822, but
|
||||
the comma after the dayname is optional and
|
||||
month/day are inverted"""
|
||||
_rfc822_date_grubby = "%s %s %s" % (_rfc822_month, _rfc822_day, _rfc822_year)
|
||||
_rfc822_match_grubby = re.compile(
|
||||
"(?:%s[,]? )?%s(?: %s)?" % (_rfc822_dayname, _rfc822_date_grubby, _rfc822_time)
|
||||
).match
|
||||
|
||||
try:
|
||||
m = _rfc822_match_grubby(dt.lower()).groupdict(0)
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
return _parse_date_group_rfc822(m)
|
||||
registerDateHandler(_parse_date_rfc822_grubby)
|
||||
|
||||
def _parse_date_asctime(dt):
|
||||
"""Parse asctime-style dates"""
|
||||
dayname, month, day, remainder = dt.split(None, 3)
|
||||
|
||||
@@ -521,9 +521,19 @@ def ldap_auth(server='ldap', port=None,
|
||||
logging.error(
|
||||
'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))
|
||||
# if old pydal version, assume this is a relational database which can do joins
|
||||
db_can_join = db.can_join() if hasattr(db, 'can_join') else True
|
||||
if db_can_join:
|
||||
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))
|
||||
else:
|
||||
# no joins on NoSQL databases, perform two queries
|
||||
db_group_search = db(db.auth_membership.user_id == db_user_id)
|
||||
group_ids = [x.group_id for x in db_group_search.select(
|
||||
db.auth_membership.group_id, distinct=True)]
|
||||
db_group_search = db(db.auth_group.id.belongs(group_ids))
|
||||
db_groups_of_the_user = list()
|
||||
db_group_id = dict()
|
||||
|
||||
|
||||
@@ -1,254 +0,0 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
from imaplib import ParseFlags
|
||||
|
||||
# mockimaplib: A very simple mock server module for imap client APIs
|
||||
# Copyright (C) 2014 Alan Etkin <spametki@gmail.com>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or(at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this program. If not, see
|
||||
# <http://www.gnu.org/licenses/lgpl.html>
|
||||
|
||||
"""
|
||||
mockimaplib allows you to test applications connecting to a dummy imap
|
||||
service. For more details on the api subset implemented,
|
||||
refer to the imaplib docs.
|
||||
|
||||
The client should configure a dictionary to map imap string queries to sets
|
||||
of entries stored in a message dummy storage dictionary. The module includes
|
||||
a small set of default message records (SPAM and MESSAGES), two mailboxes
|
||||
(Draft and INBOX) and a list of query/resultset entries (RESULTS).
|
||||
|
||||
Usage:
|
||||
|
||||
>>> import mockimaplib
|
||||
>>> connection = mockimaplib.IMAP4_SSL(<host>)
|
||||
>>> connection.login(<user>, <password>)
|
||||
None
|
||||
>>> connection.select("INBOX")
|
||||
("OK", ... <mailbox length>)
|
||||
# fetch commands specifying single uid or message id
|
||||
# will try to get messages recorded in SPAM
|
||||
>>> connection.uid(...)
|
||||
<search query or fetch result>
|
||||
# returns a string list of matching message ids
|
||||
>>> connection.search(<query>)
|
||||
("OK", ... "1 2 ... n")
|
||||
"""
|
||||
|
||||
MESSAGES = (
|
||||
'MIME-Version: 1.0\r\nReceived: by 10.140.91.199 with HTTP; Mon, 27 Jan 2014 13:52:30 -0800 (PST)\r\nDate: Mon, 27 Jan 2014 19:52:30 -0200\r\nDelivered-To: nurse@example.com\r\nMessage-ID: <10101010101010010000010101010001010101001010010000001@mail.example.com>\r\nSubject: spam1\r\nFrom: Mr. Gumby <gumby@example.com>\r\nTo: The nurse <nurse@example.com>\r\nContent-Type: text/plain; charset=ISO-8859-1\r\n\r\nNurse!\r\n\r\n\r\n',
|
||||
'MIME-Version: 1.0\r\nReceived: by 10.140.91.199 with HTTP; Mon, 27 Jan 2014 13:52:47 -0800 (PST)\r\nDate: Mon, 27 Jan 2014 19:52:47 -0200\r\nDelivered-To: nurse@example.com\r\nMessage-ID: <101010101010100100000101010100010101010010100100000010@mail.example.com>\r\nSubject: spam2\r\nFrom: Mr. Gumby <gumby@example.com>\r\nTo: The nurse <nurse@example.com>\r\nContent-Type: text/plain; charset=ISO-8859-1\r\n\r\nNurse, nurse!',
|
||||
'MIME-Version: 1.0\r\nReceived: by 10.140.91.199 with HTTP; Mon, 27 Jan 2014 13:54:54 -0800 (PST)\r\nDate: Mon, 27 Jan 2014 19:54:54 -0200\r\nDelivered-To: nurse@example.com\r\nMessage-ID: <1010101010101001000001010101000101010100101001000000101@mail.example.com>\r\nSubject: spamalot1\r\nFrom: Mr. Gumby <gumby@example.com>\r\nTo: The nurse <nurse@example.com>\r\nContent-Type: text/plain; charset=ISO-8859-1\r\n\r\nNurse!\r\n\r\n\r\n',
|
||||
'MIME-Version: 1.0\r\n\r\nReceived: by 10.140.91.199 with HTTP; Mon, 27 Jan 2014 13:54:54 -0800 (PST)\r\nDate: Mon, 27 Jan 2014 19:54:54 -0200\r\nDelivered-To: nurse@example.com\r\nMessage-ID: <101010101010100100000101010100010101010010100100000010101@mail.example.com>\r\nSubject: spamalot2\r\nFrom: Mr. Gumby <gumby@example.com>\r\nTo: The nurse <nurse@example.com>\r\nContent-Type: text/plain; charset=ISO-8859-1\r\n\r\nNurse! ... Nurse! ... Nurse!\r\n\r\n\r\n')
|
||||
|
||||
SPAM = {
|
||||
"INBOX": [
|
||||
{"uid": "483209",
|
||||
"headers": MESSAGES[0],
|
||||
"complete": MESSAGES[0],
|
||||
"flags": ""},
|
||||
{"uid": "483211",
|
||||
"headers": MESSAGES[1],
|
||||
"complete": MESSAGES[1],
|
||||
"flags": ""},
|
||||
{"uid": "483225",
|
||||
"headers": MESSAGES[2],
|
||||
"complete": MESSAGES[2],
|
||||
"flags": ""}],
|
||||
"Draft":[
|
||||
{"uid": "483432",
|
||||
"headers": MESSAGES[3],
|
||||
"complete": MESSAGES[3],
|
||||
"flags": ""},]
|
||||
}
|
||||
|
||||
RESULTS = {
|
||||
# <query string>: [<str uid> | <long id>, ...]
|
||||
"INBOX": {
|
||||
"(ALL)": (1, 2, 3),
|
||||
"(1:3)": (1, 2, 3)},
|
||||
"Draft": {
|
||||
"(1:1)": (1,)},
|
||||
}
|
||||
|
||||
class Connection(object):
|
||||
"""Dummy connection object for the imap client.
|
||||
By default, uses the module SPAM and RESULT
|
||||
sets (use Connection.setup for custom values)"""
|
||||
def login(self, user, password):
|
||||
pass
|
||||
|
||||
def __init__(self):
|
||||
self._readonly = False
|
||||
self._mailbox = None
|
||||
self.setup()
|
||||
|
||||
def list(self):
|
||||
return ('OK', ['(\\HasNoChildren) "/" "%s"' % key for key in self.spam])
|
||||
|
||||
def select(self, tablename, readonly=False):
|
||||
self._readonly = readonly
|
||||
"""args: mailbox, boolean
|
||||
result[1][0] -> int last message id / mailbox lenght
|
||||
result[0] = 'OK'
|
||||
"""
|
||||
self._mailbox = tablename
|
||||
return ('OK', (len(SPAM[self._mailbox]), None))
|
||||
|
||||
def uid(self, command, uid, arg):
|
||||
""" args:
|
||||
command: "search" | "fetch"
|
||||
uid: None | uid
|
||||
parts: "(ALL)" | "(RFC822 FLAGS)" | "(RFC822.HEADER FLAGS)"
|
||||
|
||||
"search", None, "(ALL)" -> ("OK", ("uid_1 uid_2 ... uid_<mailbox length>", None))
|
||||
"search", None, "<query>" -> ("OK", ("uid_1 uid_2 ... uid_n", None))
|
||||
"fetch", uid, parts -> ("OK", (("<id> ...", "<raw message as specified in parts>"), "<flags>")
|
||||
[0] [1][0][0] [1][0][1] [1][1]
|
||||
"""
|
||||
if command == "search":
|
||||
return self._search(arg)
|
||||
elif command == "fetch":
|
||||
return self._fetch(uid, arg)
|
||||
|
||||
def _search(self, query):
|
||||
return ("OK", (" ".join([str(item["uid"]) for item in self._get_messages(query)]), None))
|
||||
|
||||
def _fetch(self, value, arg):
|
||||
try:
|
||||
message = self.spam[self._mailbox][value - 1]
|
||||
message_id = value
|
||||
except TypeError:
|
||||
for x, item in enumerate(self.spam[self._mailbox]):
|
||||
if item["uid"] == value:
|
||||
message = item
|
||||
message_id = x + 1
|
||||
break
|
||||
|
||||
parts = "headers"
|
||||
if arg in ("(ALL)", "(RFC822 FLAGS)"):
|
||||
parts = "complete"
|
||||
|
||||
return ("OK", (("%s " % message_id, message[parts]), message["flags"]))
|
||||
|
||||
def _get_messages(self, query):
|
||||
if query.strip().isdigit():
|
||||
return [self.spam[self._mailbox][int(query.strip()) - 1],]
|
||||
elif query[1:-1].strip().isdigit():
|
||||
return [self.spam[self._mailbox][int(query[1:-1].strip()) -1],]
|
||||
elif query[1:-1].replace("UID", "").strip().isdigit():
|
||||
for item in self.spam[self._mailbox]:
|
||||
if item["uid"] == query[1:-1].replace("UID", "").strip():
|
||||
return [item,]
|
||||
messages = []
|
||||
try:
|
||||
for m in self.results[self._mailbox][query]:
|
||||
try:
|
||||
self.spam[self._mailbox][m - 1]["id"] = m
|
||||
messages.append(self.spam[self._mailbox][m - 1])
|
||||
except TypeError:
|
||||
for x, item in enumerate(self.spam[self._mailbox]):
|
||||
if item["uid"] == m:
|
||||
item["id"] = x + 1
|
||||
messages.append(item)
|
||||
break
|
||||
except IndexError:
|
||||
# message removed
|
||||
pass
|
||||
return messages
|
||||
except KeyError:
|
||||
raise ValueError("The client issued an unexpected query: %s" % query)
|
||||
|
||||
def setup(self, spam={}, results={}):
|
||||
"""adds custom message and query databases or sets
|
||||
the values to the module defaults.
|
||||
"""
|
||||
|
||||
self.spam = spam
|
||||
self.results = results
|
||||
if not spam:
|
||||
for key in SPAM:
|
||||
self.spam[key] = []
|
||||
for d in SPAM[key]:
|
||||
self.spam[key].append(d.copy())
|
||||
if not results:
|
||||
for key in RESULTS:
|
||||
self.results[key] = RESULTS[key].copy()
|
||||
|
||||
|
||||
def search(self, first, query):
|
||||
""" args:
|
||||
first: None
|
||||
query: string with mailbox query (flags, date, uid, id, ...)
|
||||
example: '2:15723 BEFORE 27-Jan-2014 FROM "gumby"'
|
||||
result[1][0] -> "id_1 id_2 ... id_n"
|
||||
"""
|
||||
messages = self._get_messages(query)
|
||||
ids = " ".join([str(item["id"]) for item in messages])
|
||||
return ("OK", (ids, None))
|
||||
|
||||
def append(self, mailbox, flags, struct_time, message):
|
||||
"""
|
||||
result, data = self.connection.append(mailbox, flags, struct_time, message)
|
||||
if result == "OK":
|
||||
uid = int(re.findall("\d+", str(data))[-1])
|
||||
"""
|
||||
last = self.spam[mailbox][-1]
|
||||
try:
|
||||
uid = int(last["uid"]) +1
|
||||
except ValueError:
|
||||
alluids = []
|
||||
for _mailbox in self.spam.keys():
|
||||
for item in self.spam[_mailbox]:
|
||||
try:
|
||||
alluids.append(int(item["uid"]))
|
||||
except:
|
||||
pass
|
||||
if len(alluids) > 0:
|
||||
uid = max(alluids) + 1
|
||||
else:
|
||||
uid = 1
|
||||
flags = "FLAGS " + flags
|
||||
item = {"uid": str(uid), "headers": message, "complete": message, "flags": flags}
|
||||
self.spam[mailbox].append(item)
|
||||
return ("OK", "spam spam %s spam" % uid)
|
||||
|
||||
|
||||
def store(self, *args):
|
||||
"""
|
||||
implements some flag commands
|
||||
args: ("<id>", "<+|->FLAGS", "(\\Flag1 \\Flag2 ... \\Flagn)")
|
||||
"""
|
||||
message = self.spam[self._mailbox][int(args[0] - 1)]
|
||||
old_flags = ParseFlags(message["flags"])
|
||||
flags = ParseFlags("FLAGS" + args[2])
|
||||
if args[1].strip().startswith("+"):
|
||||
message["flags"] = "FLAGS (%s)" % " ".join(set(flags + old_flags))
|
||||
elif args[1].strip().startswith("-"):
|
||||
message["flags"] = "FLAGS (%s)" % " ".join([flag for flag in old_flags if not flag in flags])
|
||||
|
||||
def expunge(self):
|
||||
"""implements removal of deleted flag messages"""
|
||||
for x, item in enumerate(self.spam[self._mailbox]):
|
||||
if "\\Deleted" in item["flags"]:
|
||||
self.spam[self._mailbox].pop(x)
|
||||
|
||||
|
||||
class IMAP4(object):
|
||||
""">>> connection = IMAP4() # creates the dummy imap4 client object"""
|
||||
def __new__(self, *args, **kwargs):
|
||||
# args: (server, port)
|
||||
return Connection()
|
||||
|
||||
IMAP4_SSL = IMAP4
|
||||
+35
-17
@@ -25,7 +25,7 @@ pooling = True
|
||||
apilevel = '2.0'
|
||||
paramstyle = 'qmark'
|
||||
threadsafety = 1
|
||||
version = '1.3.0'
|
||||
version = '1.3.3'
|
||||
lowercase=True
|
||||
|
||||
DEBUG = 0
|
||||
@@ -89,7 +89,7 @@ SQL_ATTR_AUTOCOMMIT = SQL_AUTOCOMMIT = 102
|
||||
SQL_MODE_DEFAULT = SQL_MODE_READ_WRITE = 0; SQL_MODE_READ_ONLY = 1
|
||||
SQL_AUTOCOMMIT_OFF, SQL_AUTOCOMMIT_ON = 0, 1
|
||||
SQL_IS_UINTEGER = -5
|
||||
SQL_ATTR_LOGIN_TIMEOUT = 103; SQL_ATTR_CONNECTION_TIMEOUT = 113
|
||||
SQL_ATTR_LOGIN_TIMEOUT = 103; SQL_ATTR_CONNECTION_TIMEOUT = 113;SQL_ATTR_QUERY_TIMEOUT = 0
|
||||
SQL_COMMIT, SQL_ROLLBACK = 0, 1
|
||||
|
||||
SQL_INDEX_UNIQUE,SQL_INDEX_ALL = 0,1
|
||||
@@ -565,19 +565,21 @@ def dttm_cvt(x):
|
||||
if py_v3:
|
||||
x = x.decode('ascii')
|
||||
if x == '': return None
|
||||
else: return datetime.datetime(int(x[0:4]),int(x[5:7]),int(x[8:10]),int(x[10:13]),int(x[14:16]),int(x[17:19]),int(x[20:].ljust(6,'0')))
|
||||
x = x.ljust(26,'0')
|
||||
return datetime.datetime(int(x[0:4]),int(x[5:7]),int(x[8:10]),int(x[10:13]),int(x[14:16]),int(x[17:19]),int(x[20:26]))
|
||||
|
||||
def tm_cvt(x):
|
||||
if py_v3:
|
||||
x = x.decode('ascii')
|
||||
if x == '': return None
|
||||
else: return datetime.time(int(x[0:2]),int(x[3:5]),int(x[6:8]),int(x[9:].ljust(6,'0')))
|
||||
x = x.ljust(15,'0')
|
||||
return datetime.time(int(x[0:2]),int(x[3:5]),int(x[6:8]),int(x[9:15]))
|
||||
|
||||
def dt_cvt(x):
|
||||
if py_v3:
|
||||
x = x.decode('ascii')
|
||||
if x == '': return None
|
||||
else: return datetime.date(int(x[0:4]),int(x[5:7]),int(x[8:10]))
|
||||
else:return datetime.date(int(x[0:4]),int(x[5:7]),int(x[8:10]))
|
||||
|
||||
def Decimal_cvt(x):
|
||||
if py_v3:
|
||||
@@ -696,6 +698,7 @@ funcs_with_ret = [
|
||||
"SQLStatisticsW",
|
||||
"SQLTables",
|
||||
"SQLTablesW",
|
||||
"SQLSetStmtAttr"
|
||||
]
|
||||
|
||||
for func_name in funcs_with_ret:
|
||||
@@ -1168,9 +1171,18 @@ class Cursor:
|
||||
self.arraysize = 1
|
||||
ret = ODBC_API.SQLAllocHandle(SQL_HANDLE_STMT, self.connection.dbc_h, ADDR(self.stmt_h))
|
||||
check_success(self, ret)
|
||||
|
||||
self.timeout = conx.timeout
|
||||
if self.timeout != 0:
|
||||
self.set_timeout(self.timeout)
|
||||
|
||||
self._PARAM_SQL_TYPE_LIST = []
|
||||
self.closed = False
|
||||
|
||||
def set_timeout(self, timeout):
|
||||
self.timeout = timeout
|
||||
ret = ODBC_API.SQLSetStmtAttr(self.stmt_h, SQL_ATTR_QUERY_TIMEOUT, self.timeout, 0)
|
||||
check_success(self, ret)
|
||||
|
||||
def prepare(self, query_string):
|
||||
"""prepare a query"""
|
||||
@@ -2369,10 +2381,14 @@ class Cursor:
|
||||
return self
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# This class implement a odbc connection.
|
||||
#
|
||||
#
|
||||
|
||||
connection_timeout = 0
|
||||
|
||||
class Connection:
|
||||
def __init__(self, connectString = '', autocommit = False, ansi = False, timeout = 0, unicode_results = use_unicode, readonly = False, **kargs):
|
||||
@@ -2384,6 +2400,7 @@ class Connection:
|
||||
self.dbc_h = ctypes.c_void_p()
|
||||
self.autocommit = autocommit
|
||||
self.readonly = False
|
||||
# the query timeout value
|
||||
self.timeout = 0
|
||||
# self._cursors = []
|
||||
for key, value in list(kargs.items()):
|
||||
@@ -2409,9 +2426,17 @@ class Connection:
|
||||
ret = ODBC_API.SQLAllocHandle(SQL_HANDLE_DBC, shared_env_h, ADDR(self.dbc_h))
|
||||
check_success(self, ret)
|
||||
|
||||
self.connection_timeout = connection_timeout
|
||||
if self.connection_timeout != 0:
|
||||
self.set_connection_timeout(connection_timeout)
|
||||
|
||||
|
||||
self.connect(connectString, autocommit, ansi, timeout, unicode_results, readonly)
|
||||
|
||||
|
||||
def set_connection_timeout(self,connection_timeout):
|
||||
self.connection_timeout = connection_timeout
|
||||
ret = ODBC_API.SQLSetConnectAttr(self.dbc_h, SQL_ATTR_CONNECTION_TIMEOUT, connection_timeout, SQL_IS_UINTEGER);
|
||||
check_success(self, ret)
|
||||
|
||||
def connect(self, connectString = '', autocommit = False, ansi = False, timeout = 0, unicode_results = use_unicode, readonly = False):
|
||||
"""Connect to odbc, using connect strings and set the connection's attributes like autocommit and timeout
|
||||
@@ -2421,11 +2446,8 @@ class Connection:
|
||||
# Before we establish the connection by the connection string
|
||||
# Set the connection's attribute of "timeout" (Actully LOGIN_TIMEOUT)
|
||||
if timeout != 0:
|
||||
self.settimeout(timeout)
|
||||
ret = ODBC_API.SQLSetConnectAttr(self.dbc_h, SQL_ATTR_LOGIN_TIMEOUT, timeout, SQL_IS_UINTEGER);
|
||||
check_success(self, ret)
|
||||
|
||||
|
||||
# Create one connection with a connect string by calling SQLDriverConnect
|
||||
# and make self.dbc_h the handle of this connection
|
||||
|
||||
@@ -2474,9 +2496,9 @@ class Connection:
|
||||
# Set the connection's attribute of "readonly"
|
||||
#
|
||||
self.readonly = readonly
|
||||
|
||||
ret = ODBC_API.SQLSetConnectAttr(self.dbc_h, SQL_ATTR_ACCESS_MODE, self.readonly and SQL_MODE_READ_ONLY or SQL_MODE_READ_WRITE, SQL_IS_UINTEGER)
|
||||
check_success(self, ret)
|
||||
if self.readonly == True:
|
||||
ret = ODBC_API.SQLSetConnectAttr(self.dbc_h, SQL_ATTR_ACCESS_MODE, SQL_MODE_READ_ONLY, SQL_IS_UINTEGER)
|
||||
check_success(self, ret)
|
||||
|
||||
self.unicode_results = unicode_results
|
||||
self.connected = 1
|
||||
@@ -2491,10 +2513,6 @@ class Connection:
|
||||
def add_output_converter(self, sqltype, func):
|
||||
self.output_converter[sqltype] = func
|
||||
|
||||
def settimeout(self, timeout):
|
||||
ret = ODBC_API.SQLSetConnectAttr(self.dbc_h, SQL_ATTR_CONNECTION_TIMEOUT, timeout, SQL_IS_UINTEGER);
|
||||
check_success(self, ret)
|
||||
self.timeout = timeout
|
||||
|
||||
|
||||
def ConnectByDSN(self, dsn, user, passwd = ''):
|
||||
|
||||
+35
-35
@@ -4,7 +4,24 @@ from hashlib import sha1
|
||||
|
||||
class Stripe:
|
||||
"""
|
||||
Usage:
|
||||
Use in WEB2PY (guaranteed PCI compliant)
|
||||
|
||||
def pay():
|
||||
from gluon.contrib.stripe import StripeForm
|
||||
form = StripeForm(
|
||||
pk=STRIPE_PUBLISHABLE_KEY,
|
||||
sk=STRIPE_SECRET_KEY,
|
||||
amount=150, # $1.5 (amount is in cents)
|
||||
description="Nothing").process()
|
||||
if form.accepted:
|
||||
payment_id = form.response['id']
|
||||
redirect(URL('thank_you'))
|
||||
elif form.errors:
|
||||
redirect(URL('pay_error'))
|
||||
return dict(form=form)
|
||||
|
||||
Low level API:
|
||||
|
||||
key='<api key>'
|
||||
d = Stripe(key).charge(
|
||||
amount=100, # 1 dollar!!!!
|
||||
@@ -22,22 +39,6 @@ class Stripe:
|
||||
{u'fee': 0, u'description': u'test charge', u'created': 1321242072, u'refunded': False, u'livemode': False, u'object': u'charge', u'currency': u'usd', u'amount': 100, u'paid': True, u'id': u'ch_sdjasgfga83asf', u'card': {u'exp_month': 5, u'country': u'US', u'object': u'card', u'last4': u'4242', u'exp_year': 2012, u'type': u'Visa'}}
|
||||
if paid is True than transaction was processed
|
||||
|
||||
Use in WEB2PY (guaranteed PCI compliant)
|
||||
|
||||
def pay():
|
||||
from gluon.contrib.stripe import StripeForm
|
||||
form = StripeForm(
|
||||
pk=STRIPE_PUBLISHABLE_KEY,
|
||||
sk=STRIPE_SECRET_KEY,
|
||||
amount=150, # $1.5 (amount is in cents)
|
||||
description="Nothing").process()
|
||||
if form.accepted:
|
||||
payment_id = form.response['id']
|
||||
redirect(URL('thank_you'))
|
||||
elif form.errors:
|
||||
redirect(URL('pay_error'))
|
||||
return dict(form=form)
|
||||
|
||||
"""
|
||||
|
||||
URL_CHARGE = 'https://%s:@api.stripe.com/v1/charges'
|
||||
@@ -188,37 +189,36 @@ jQuery(function(){
|
||||
<h3>Payment Amount: {{=currency_symbol}} {{="%.2f" % (0.01*amount)}}</h3>
|
||||
<form action="" method="POST" id="payment-form" class="form-horizontal">
|
||||
|
||||
<div class="form-row control-group">
|
||||
<label class="control-label">Card Number</label>
|
||||
<div class="controls">
|
||||
<div class="form-row form-group">
|
||||
<label class="col-sm-2 control-label">Card Number</label>
|
||||
<div class="controls col-sm-10">
|
||||
<input type="text" size="20" data-stripe="number"
|
||||
placeholder="4242424242424242"/>
|
||||
placeholder="4242424242424242" class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row control-group">
|
||||
<label class="control-label">CVC</label>
|
||||
<div class="controls">
|
||||
<div class="form-row form-group">
|
||||
<label class="col-sm-2 control-label">CVC</label>
|
||||
<div class="controls col-sm-10">
|
||||
<input type="text" size="4" style="width:80px" data-stripe="cvc"
|
||||
placeholder="XXX"/>
|
||||
placeholder="XXX" class="form-control"/>
|
||||
<a href="http://en.wikipedia.org/wiki/Card_Verification_Code" target="_blank">What is this?</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row control-group">
|
||||
<label class="control-label">Expiration</label>
|
||||
<div class="controls">
|
||||
<input type="text" size="2" style="width:40px" data-stripe="exp-month"
|
||||
placeholder="MM"/>
|
||||
<div class="form-row form-group">
|
||||
<label class="col-sm-2 control-label">Expiration</label>
|
||||
<div class="controls col-sm-10">
|
||||
<input type="text" size="2" style="width:40px; display:inline-block"
|
||||
data-stripe="exp-month" placeholder="MM" class="form-control"/>
|
||||
/
|
||||
<input type="text" size="4" style="width:80px" data-stripe="exp-year"
|
||||
placeholder="YYYY"/>
|
||||
<input type="text" size="4" style="width:80px; display:inline-block"
|
||||
data-stripe="exp-year" placeholder="YYYY" class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<div class="form-row form-group">
|
||||
<div class="controls col-sm-offset-2 col-sm-10">
|
||||
<button type="submit" class="btn btn-primary">Submit Payment</button>
|
||||
<div class="payment-errors error hidden"></div>
|
||||
</div>
|
||||
|
||||
@@ -47,6 +47,9 @@ def custom_importer(name, globals=None, locals=None, fromlist=None, level=-1):
|
||||
If the import fails, it falls back on naive_importer
|
||||
"""
|
||||
|
||||
if isinstance(name, unicode):
|
||||
name = name.encode('utf8')
|
||||
|
||||
globals = globals or {}
|
||||
locals = locals or {}
|
||||
fromlist = fromlist or []
|
||||
|
||||
+4
-4
@@ -7,14 +7,14 @@
|
||||
| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
|
||||
|
||||
Takes care of adapting pyDAL to web2py's needs
|
||||
--------------------------------------------
|
||||
-----------------------------------------------
|
||||
"""
|
||||
|
||||
from pydal import DAL as DAL
|
||||
from pydal import Field
|
||||
from pydal.objects import Row, Rows, Table, Query, Expression
|
||||
from pydal import SQLCustomType, geoPoint, geoLine, geoPolygon
|
||||
import copy_reg as copyreg
|
||||
|
||||
|
||||
def _default_validators(db, field):
|
||||
"""
|
||||
@@ -81,12 +81,12 @@ def _default_validators(db, field):
|
||||
requires[0] = validators.IS_EMPTY_OR(requires[0])
|
||||
return requires
|
||||
|
||||
from gluon import serializers as w2p_serializers
|
||||
from gluon.serializers import custom_json, xml
|
||||
from gluon.utils import web2py_uuid
|
||||
from gluon import sqlhtml
|
||||
|
||||
|
||||
DAL.serializers = w2p_serializers
|
||||
DAL.serializers = {'json': custom_json, 'xml': xml}
|
||||
DAL.validators_method = _default_validators
|
||||
DAL.uuid = lambda x: web2py_uuid()
|
||||
DAL.representers = {
|
||||
|
||||
+1
-7
@@ -23,6 +23,7 @@ base_modules = ['aifc', 'anydbm', 'array', 'asynchat', 'asyncore', 'atexit',
|
||||
'collections', 'colorsys', 'compileall', 'compiler',
|
||||
'compiler.ast', 'compiler.visitor', 'ConfigParser',
|
||||
'contextlib', 'Cookie', 'cookielib', 'copy', 'copy_reg',
|
||||
'collections',
|
||||
'cPickle', 'cProfile', 'cStringIO', 'csv', 'ctypes',
|
||||
'datetime', 'decimal', 'difflib', 'dircache', 'dis',
|
||||
'doctest', 'DocXMLRPCServer', 'dumbdbm', 'dummy_thread',
|
||||
@@ -67,13 +68,6 @@ base_modules = ['aifc', 'anydbm', 'array', 'asynchat', 'asyncore', 'atexit',
|
||||
'MimeWriter', 'mimify', 'multifile', 'sets']
|
||||
|
||||
contributed_modules = []
|
||||
for root, dirs, files in os.walk('gluon'):
|
||||
for candidate in ['.'.join(
|
||||
os.path.join(root, os.path.splitext(name)[0]).split(os.sep))
|
||||
for name in files if name.endswith('.py')
|
||||
and root.split(os.sep) != ['gluon', 'tests']
|
||||
]:
|
||||
contributed_modules.append(candidate)
|
||||
|
||||
# Python base version
|
||||
python_version = sys.version[:3]
|
||||
|
||||
+1
-1
Submodule gluon/packages/dal updated: b08cb1f779...62eb7767db.
+16
-4
@@ -58,9 +58,12 @@ def represent(field, value, record):
|
||||
f = field.represent
|
||||
if not callable(f):
|
||||
return str(value)
|
||||
n = f.func_code.co_argcount - len(f.func_defaults or [])
|
||||
if getattr(f, 'im_self', None):
|
||||
n -= 1
|
||||
if hasattr(f,'func_code'):
|
||||
n = f.func_code.co_argcount - len(f.func_defaults or [])
|
||||
if getattr(f, 'im_self', None):
|
||||
n -= 1
|
||||
else:
|
||||
n = 1
|
||||
if n == 1:
|
||||
return f(value)
|
||||
elif n == 2:
|
||||
@@ -1205,6 +1208,9 @@ class SQLFORM(FORM):
|
||||
elif field.type == 'boolean':
|
||||
inp = self.widgets.boolean.widget(
|
||||
field, default, _disabled=True)
|
||||
elif isinstance(field.type, SQLCustomType) and callable(field.type.represent):
|
||||
# SQLCustomType has a represent, use it
|
||||
inp = field.type.represent(default, record)
|
||||
else:
|
||||
inp = field.formatter(default)
|
||||
if getattr(field, 'show_if', None):
|
||||
@@ -1246,6 +1252,9 @@ class SQLFORM(FORM):
|
||||
dspval = ''
|
||||
elif field.type == 'blob':
|
||||
continue
|
||||
elif isinstance(field.type, SQLCustomType) and callable(field.type.widget):
|
||||
# SQLCustomType has a widget, use it
|
||||
inp = field.type.widget(field, default)
|
||||
else:
|
||||
field_type = widget_class.match(str(field.type)).group()
|
||||
field_type = field_type in self.widgets and field_type or 'string'
|
||||
@@ -2148,7 +2157,7 @@ class SQLFORM(FORM):
|
||||
else:
|
||||
fields = []
|
||||
columns = []
|
||||
filter1 = lambda f: isinstance(f, Field)
|
||||
filter1 = lambda f: isinstance(f, Field) and f.type != 'blob'
|
||||
filter2 = lambda f: isinstance(f, Field) and f.readable
|
||||
for table in tables:
|
||||
fields += filter(filter1, table)
|
||||
@@ -2708,6 +2717,9 @@ class SQLFORM(FORM):
|
||||
_href='%s/%s' % (upload, value))
|
||||
else:
|
||||
value = ''
|
||||
elif isinstance(field.type, SQLCustomType) and callable(field.type.represent):
|
||||
# SQLCustomType has a represent, use it
|
||||
value = field.type.represent(value, row)
|
||||
if isinstance(value, str):
|
||||
value = truncate_string(value, maxlength)
|
||||
elif not isinstance(value, XmlComponent):
|
||||
|
||||
@@ -15,10 +15,11 @@ from gluon.dal import DAL, Field
|
||||
|
||||
class TestDALSubclass(unittest.TestCase):
|
||||
def testRun(self):
|
||||
import gluon.serializers as mserializers
|
||||
from gluon.serializers import custom_json, xml
|
||||
from gluon import sqlhtml
|
||||
db = DAL(check_reserved=['all'])
|
||||
self.assertEqual(db.serializers, mserializers)
|
||||
self.assertEqual(db.serializers['json'], custom_json)
|
||||
self.assertEqual(db.serializers['xml'], xml)
|
||||
self.assertEqual(db.representers['rows_render'], sqlhtml.represent)
|
||||
self.assertEqual(db.representers['rows_xml'], sqlhtml.SQLTABLE)
|
||||
|
||||
|
||||
+5
-2
@@ -42,10 +42,13 @@ from gluon import *
|
||||
from gluon.contrib.autolinks import expand_one
|
||||
from gluon.contrib.markmin.markmin2html import \
|
||||
replace_at_urls, replace_autolinks, replace_components
|
||||
from pydal.objects import Table, Row, Set, Query
|
||||
from pydal.objects import Row, Set, Query
|
||||
|
||||
import gluon.serializers as serializers
|
||||
|
||||
Table = DAL.Table
|
||||
Field = DAL.Field
|
||||
|
||||
try:
|
||||
# try stdlib (Python 2.6)
|
||||
import json as json_parser
|
||||
@@ -5359,7 +5362,7 @@ class Expose(object):
|
||||
if current.request.raw_args:
|
||||
self.args = [arg for arg in current.request.raw_args.split('/') if arg]
|
||||
else:
|
||||
self.args = [arg for arg in current.request.args if args]
|
||||
self.args = [arg for arg in current.request.args if arg]
|
||||
filename = os.path.join(base, *self.args)
|
||||
if not os.path.exists(filename):
|
||||
raise HTTP(404, "FILE NOT FOUND")
|
||||
|
||||
+1
-1
@@ -611,7 +611,7 @@ class IS_IN_DB(Validator):
|
||||
|
||||
def count(values, s=self.dbset, f=field):
|
||||
return s(f.belongs(map(int, values))).count()
|
||||
if isinstance(self.dbset.db._adapter, GoogleDatastoreAdapter):
|
||||
if GoogleDatastoreAdapter is not None and isinstance(self.dbset.db._adapter, GoogleDatastoreAdapter):
|
||||
range_ids = range(0, len(values), 30)
|
||||
total = sum(count(values[i:i + 30]) for i in range_ids)
|
||||
if total == len(values):
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
"This script will work fine for a few cases 'by default':"
|
||||
" - completely CLEAN WS2012R2 host"
|
||||
" - python 2.7 installed in the default path"
|
||||
" - wfasctgi installed on the default path"
|
||||
"It'll install web2py under the default website "
|
||||
" You can use it as a boilerplate to automate your deployments"
|
||||
" but it still is released AS IT IS. "
|
||||
"BIG FAT WARNING: It will install a bunch of dependecies
|
||||
Inspect the source before executing it"
|
||||
""
|
||||
""
|
||||
$ErrorActionPreference = 'stop'
|
||||
|
||||
$REALLY_SURE = Read-Host "Do you want to start with web2py deployment? [y/N]"
|
||||
if (!@('y', 'Y') -contains $REALLY_SURE) {
|
||||
"Ok, Exiting without doing anything"
|
||||
exit 1
|
||||
}
|
||||
#setting root folder
|
||||
$rootfolder = $pwd
|
||||
|
||||
### utilities - start
|
||||
function ask_a_question($question) {
|
||||
$response = Read-Host "$question [Y/n]"
|
||||
if (@('Y', 'y', '', $null) -contains $response) {
|
||||
return $true
|
||||
} else {
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
function unzip_me {
|
||||
#Load the assembly
|
||||
[System.Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem") | Out-Null
|
||||
#Unzip the file
|
||||
[System.IO.Compression.ZipFile]::ExtractToDirectory($pathToZip, $targetDir)
|
||||
}
|
||||
|
||||
|
||||
### utilities - end
|
||||
|
||||
#install 4.5 that is needed for a bunch of things anyway
|
||||
Install-WindowsFeature Net-Framework-45-Core
|
||||
|
||||
#fetch web2py
|
||||
$web2py_url = 'http://www.web2py.com/examples/static/web2py_src.zip'
|
||||
$web2py_file = "$pwd\web2py_src.zip"
|
||||
if (!(Test-Path $web2py_file)) {
|
||||
(new-object net.webclient).DownloadFile($web2py_url, $web2py_file)
|
||||
}
|
||||
#Load the assembly
|
||||
[System.Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem") | Out-Null
|
||||
#Unzip the file
|
||||
[System.IO.Compression.ZipFile]::ExtractToDirectory($web2py_file, $pwd)
|
||||
|
||||
#features installation (IIS, needed modules, python, chocolatey, etc)
|
||||
$installfeatures = ask_a_question('Do you want to install needed features?')
|
||||
|
||||
if ($installfeatures) {
|
||||
Install-WindowsFeature Web-Server,Web-Default-Doc,Web-Static-Content,Web-Http-Redirect,Web-Http-Logging,Web-Request-Monitor,`
|
||||
Web-Http-Tracing,Web-Stat-Compression,Web-Dyn-Compression,Web-Filtering,Web-Basic-Auth,Web-Windows-Auth,Web-AppInit,`
|
||||
Web-CGI,Web-WebSockets,Web-Mgmt-Console,Web-Net-Ext45
|
||||
}
|
||||
|
||||
$copy_web2py = ask_a_question("Copy web2py to the default website root?")
|
||||
if ($copy_web2py) {
|
||||
Import-Module WebAdministration
|
||||
$available_websites = Get-Website
|
||||
if ($available_websites[0] -eq $null) {
|
||||
$default_one = $available_websites
|
||||
} else {
|
||||
$default_one = $available_websites[0]
|
||||
}
|
||||
$iis_root = [System.Environment]::ExpandEnvironmentVariables($default_one.PhysicalPath)
|
||||
Copy-Item "$rootfolder\web2py\*" $iis_root -Recurse
|
||||
$rootfolder = $iis_root
|
||||
$acl = (Get-Item $rootfolder).GetAccessControl('Access')
|
||||
$identity = "BUILTIN\IIS_IUSRS"
|
||||
$fileSystemRights = "Modify"
|
||||
$inheritanceFlags = "ContainerInherit, ObjectInherit"
|
||||
$propagationFlags = "None"
|
||||
$accessControlType = "Allow"
|
||||
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule($identity, $fileSystemRights, $inheritanceFlags, $propagationFlags, $accessControlType)
|
||||
$acl.SetAccessRule($rule)
|
||||
Set-Acl $rootfolder $acl
|
||||
}
|
||||
|
||||
$create_cert = ask_a_question("Do you want to create a self-signed SSL cert?")
|
||||
if ($create_cert) {
|
||||
$cert = New-SelfSignedCertificate -DnsName ("localtest.me","*.localtest.me") -CertStoreLocation cert:\LocalMachine\My
|
||||
$rootStore = Get-Item cert:\LocalMachine\Root
|
||||
$rootStore.Open("ReadWrite")
|
||||
$rootStore.Add($cert)
|
||||
$rootStore.Close();
|
||||
Import-Module WebAdministration
|
||||
Set-Location IIS:\SslBindings
|
||||
New-WebBinding -Name "Default Web Site" -IP "*" -Port 443 -Protocol https
|
||||
$cert | New-Item 0.0.0.0!443
|
||||
Set-Location $pwd
|
||||
}
|
||||
|
||||
"checking for chocolatey"
|
||||
if (Get-Command "choco.exe" -ErrorAction SilentlyContinue)
|
||||
{
|
||||
"chocolatey found"
|
||||
} else {
|
||||
"installing chocolatey"
|
||||
(new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1') | iex
|
||||
}
|
||||
"installing url-rewrite"
|
||||
choco install UrlRewrite
|
||||
$pythonexe = Read-Host 'Python.exe path [C:\Python27\python.exe]'
|
||||
if (($pythonexe -eq '') -or ($pythonexe -eq $null)) {
|
||||
$pythonexe = 'C:\Python27\python.exe'
|
||||
}
|
||||
if (!(Test-Path $pythonexe)) {
|
||||
"ERROR: python executable not found"
|
||||
$pythonwanted = ask_a_question("do you want to install it automatically?")
|
||||
|
||||
if ($pythonwanted) {
|
||||
choco install webpicmd
|
||||
WebpiCmd.exe /Install /Products:WFastCgi_21_279
|
||||
$pythonexe = 'C:\Python27\python.exe'
|
||||
}
|
||||
else {
|
||||
exit 1
|
||||
}
|
||||
|
||||
}
|
||||
$wfastcgipath = Read-Host 'wfastcgi.py path [C:\Python27\Scripts\wfastcgi.py]'
|
||||
if (($wfastcgipath -eq '') -or ($wfastcgipath -eq $null)) {
|
||||
$wfastcgipath = 'C:\Python27\Scripts\wfastcgi.py'
|
||||
}
|
||||
|
||||
if (-not (Test-Path $wfastcgipath)) {
|
||||
"ERROR: wfastcgi.py not found"
|
||||
|
||||
$wfastcgiwanted = ask_a_question("do you want to install it automatically?")
|
||||
if ($wfastcgiwanted) {
|
||||
choco install webpicmd
|
||||
WebpiCmd.exe /Install /Products:WFastCgi_21_279
|
||||
} else {
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
$pythondir = Split-Path c:\python27\python.exe
|
||||
#installing dependencies
|
||||
$env:Path = $env:Path + ";$pythondir;$pythondir\Scripts"
|
||||
|
||||
pip install pypiwin32
|
||||
|
||||
$PW = Read-Host 'Web2py Admin Password'
|
||||
|
||||
$appcmdpath = "$env:windir\system32\inetsrv\appcmd.exe"
|
||||
|
||||
& $appcmdpath set config /section:system.webServer/fastCGI "/+[fullPath='$pythonexe', arguments='$wfastcgipath']"
|
||||
& $appcmdpath unlock config -section:system.webServer/handlers
|
||||
|
||||
& cd $rootfolder
|
||||
& $pythonexe -c "from gluon.main import save_password; save_password('$PW',443)"
|
||||
|
||||
$webconfig_template = Join-Path $rootfolder "examples\web.config"
|
||||
$destination = Join-Path $rootfolder "web.config"
|
||||
$scriptprocessor = 'scriptProcessor="{0}|{1}"' -f $pythonexe, $wfastcgipath
|
||||
|
||||
(Get-Content $webconfig_template) | Foreach-Object {$_ -replace 'scriptProcessor="SCRIPT_PROCESSOR"', $scriptprocessor} | where {$_ -ne ""} | Set-Content $destination
|
||||
""
|
||||
"Installation finished. Web2py is available either on http://localhost/ or at https://localtest.me/"
|
||||
""
|
||||
Executable
+78
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Post error tickets to slack on a 5 minute schedule.
|
||||
#
|
||||
# Proper use depends on having created a web-hook through Slack, and having set
|
||||
# that value in your app's model as the value of global_settings.slack_hook.
|
||||
# Details on creating web-hooks can be found at https://slack.com/integrations
|
||||
#
|
||||
# requires the Requests module for posting to slack, other requirements are
|
||||
# standard or provided by web2py
|
||||
#
|
||||
# Usage (on Unices), replace myapp with the name of your application and run:
|
||||
# nohup python web2py.py -S myapp -M -R scripts/tickets2slack.py &
|
||||
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
import pickle
|
||||
import json
|
||||
|
||||
try:
|
||||
import requests
|
||||
except ImportError as e:
|
||||
print "missing module 'Requests', aborting."
|
||||
sys.exit(1)
|
||||
|
||||
from gluon import URL
|
||||
from gluon.utils import md5_hash
|
||||
from gluon.restricted import RestrictedError
|
||||
from gluon.settings import global_settings
|
||||
|
||||
|
||||
path = os.path.join(request.folder, 'errors')
|
||||
sent_errors_file = os.path.join(path, 'slack_errors.pickle')
|
||||
hashes = {}
|
||||
if os.path.exists(sent_errors_file):
|
||||
try:
|
||||
with open(sent_errors_file, 'rb') as f:
|
||||
hashes = pickle.load(f)
|
||||
except Exception as _:
|
||||
pass
|
||||
|
||||
# ## CONFIGURE HERE
|
||||
SLEEP_MINUTES = 5
|
||||
ALLOW_DUPLICATES = False
|
||||
global_settings.slack_hook = global_settings.slack_hook or \
|
||||
'https://hooks.slack.com/services/your_service'
|
||||
# ## END CONFIGURATION
|
||||
|
||||
while 1:
|
||||
for file_name in os.listdir(path):
|
||||
if file_name == 'slack_errors.pickle':
|
||||
continue
|
||||
|
||||
if not ALLOW_DUPLICATES:
|
||||
key = md5_hash(file_name)
|
||||
if key in hashes:
|
||||
continue
|
||||
hashes[key] = 1
|
||||
|
||||
error = RestrictedError()
|
||||
|
||||
try:
|
||||
error.load(request, request.application, file_name)
|
||||
except Exception as _:
|
||||
continue # not an exception file?
|
||||
|
||||
url = URL(a='admin', f='ticket', args=[request.application, file],
|
||||
scheme=True)
|
||||
payload = json.dumps(dict(text="Error in %(app)s.\n%(url)s" %
|
||||
dict(app=request.application, url=url)))
|
||||
|
||||
requests.post(global_settings.slack_hook, data=dict(payload=payload))
|
||||
|
||||
with open(sent_errors_file, 'wb') as f:
|
||||
pickle.dump(hashes, f)
|
||||
time.sleep(SLEEP_MINUTES * 60)
|
||||
Reference in new issue
Block a user