initial commit

This commit is contained in:
Massimo Di Pierro
2011-11-22 23:30:42 -06:00
commit d421c1321b
580 changed files with 115527 additions and 0 deletions
+233
View File
@@ -0,0 +1,233 @@
{{extend 'layout.html'}}
<script><!--
jQuery(document).ready(function(){
jQuery("table.sortable tbody tr").mouseover( function() {
jQuery(this).addClass("highlight"); }).mouseout( function() {
jQuery(this).removeClass("highlight"); });
jQuery('table.sortable tbody tr:odd').addClass('odd');
jQuery('table.sortable tbody tr:even').addClass('even');
});
//--></script>
{{if request.function=='index':}}
<h1>{{=T("Available databases and tables")}}</h1>
{{if not databases:}}{{=T("No databases in this application")}}{{pass}}
{{for db in sorted(databases):}}
{{for table in databases[db].tables:}}
{{qry='%s.%s.id>0'%(db,table)}}
{{tbl=databases[db][table]}}
{{if hasattr(tbl,'_primarykey'):}}
{{if tbl._primarykey:}}
{{firstkey=tbl[tbl._primarykey[0]]}}
{{if firstkey.type in ['string','text']:}}
{{qry='%s.%s.%s!=""'%(db,table,firstkey.name)}}
{{else:}}
{{qry='%s.%s.%s>0'%(db,table,firstkey.name)}}
{{pass}}
{{else:}}
{{qry=''}}
{{pass}}
{{pass}}
<h2>{{=A("%s.%s" % (db,table),_href=URL('select',args=[db],vars=dict(query=qry)))}}
</h2>
[ {{=A(str(T('insert new'))+' '+table,_href=URL('insert',args=[db,table]))}} ]
<br /><br />
{{pass}}
{{pass}}
{{elif request.function=='select':}}
<h1>{{=XML(str(T("database %s select"))%A(request.args[0],_href=URL('index'))) }}
</h1>
{{if table:}}
[ {{=A(str(T('insert new %s'))%table,_href=URL('insert',args=[request.args[0],table]))}} ]<br/><br/>
<h2>{{=T("Rows in table")}}</h2><br/>
{{else:}}
<h2>{{=T("Rows selected")}}</h2><br/>
{{pass}}
{{=form}}
<p>{{=T('The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1==db.table2.field2" results in a SQL JOIN.')}}<br/>
{{=T('Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.')}}<br/>
{{=T('"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN')}}</p>
<br/><br/>
<h3>{{=nrows}} {{=T("selected")}}</h3>
{{if start>0:}}[ {{=A(T('previous 100 rows'),_href=URL('select',args=request.args[0],vars=dict(start=start-100)))}} ]{{pass}}
{{if stop<nrows:}}[ {{=A(T('next 100 rows'),_href=URL('select',args=request.args[0],vars=dict(start=start+100)))}} ]{{pass}}
{{if rows:}}
<div style="overflow: auto;" width="80%">
{{linkto=URL('update',args=request.args[0])}}
{{upload=URL('download',args=request.args[0])}}
{{=SQLTABLE(rows,linkto,upload,orderby=True,_class='sortable')}}
</div>
{{pass}}
<br/><br/><h2>{{=T("Import/Export")}}</h2><br/>
[ <a href="{{=URL('csv',args=request.args[0],vars=dict(query=query))}}">{{=T("export as csv file")}}</a> ]
{{if table:}}
{{=FORM(str(T('or import from csv file'))+" ",INPUT(_type='file',_name='csvfile'),INPUT(_type='hidden',_value=table,_name='table'),INPUT(_type='submit',_value='import'))}}
{{pass}}
{{elif request.function=='insert':}}
<h1>{{=T("database")}} {{=A(request.args[0],_href=URL('index'))}}
{{if hasattr(table,'_primarykey'):}}
{{fieldname=table._primarykey[0]}}
{{dbname=request.args[0]}}
{{tablename=request.args[1]}}
{{cond = table[fieldname].type in ['string','text'] and '!=""' or '>0'}}
{{=T("table")}} {{=A(tablename,_href=URL('select',args=dbname,vars=dict(query='%s.%s.%s%s'%(dbname,tablename,fieldname,cond))))}}
{{else:}}
{{=T("table")}} {{=A(request.args[1],_href=URL('select',args=request.args[0],vars=dict(query='%s.%s.id>0'%tuple(request.args[:2]))))}}
{{pass}}
</h1>
<h2>{{=T("New Record")}}</h2><br/>
{{=form}}
{{elif request.function=='update':}}
<h1>{{=T("database")}} {{=A(request.args[0],_href=URL('index'))}}
{{if hasattr(table,'_primarykey'):}}
{{fieldname=request.vars.keys()[0]}}
{{dbname=request.args[0]}}
{{tablename=request.args[1]}}
{{cond = table[fieldname].type in ['string','text'] and '!=""' or '>0'}}
{{=T("table")}} {{=A(tablename,_href=URL('select',args=dbname,vars=dict(query='%s.%s.%s%s'%(dbname,tablename,fieldname,cond))))}}
{{=T("record")}} {{=A('%s=%s'%request.vars.items()[0],_href=URL('update',args=request.args[:2],vars=request.vars))}}
{{else:}}
{{=T("table")}} {{=A(request.args[1],_href=URL('select',args=request.args[0],vars=dict(query='%s.%s.id>0'%tuple(request.args[:2]))))}}
{{=T("record id")}} {{=A(request.args[2],_href=URL('update',args=request.args[:3]))}}
{{pass}}
</h1>
<h2>{{=T("Edit current record")}}</h2><br/><br/>{{=form}}
{{elif request.function=='state':}}
<h1>{{=T("Internal State")}}</h1>
<h2>{{=T("Current request")}}</h2>
{{=BEAUTIFY(request)}}
<br/><h2>{{=T("Current response")}}</h2>
{{=BEAUTIFY(response)}}
<br/><h2>{{=T("Current session")}}</h2>
{{=BEAUTIFY(session)}}
{{elif request.function == 'ccache':}}
<h1>Cache</h1>
<div class="wrapper">
<div class="list">
<div class="list-header">
<h2>Statistics</h2>
</div>
<div class="content">
<h3>Overview</h3>
<p>Number of entries: <strong>{{=total['entries']}}</strong>
{{if total['entries'] > 0:}}
<p>
Hit Ratio:
<strong>{{=total['ratio']}}%</strong>
(<strong>{{=total['hits']}}</strong> hits
and <strong>{{=total['misses']}}</strong> misses)
</p>
<p>
Size of cache:
{{if object_stats:}}
<strong>{{=total['objects']}}</strong> items,
<strong>{{=total['bytes']}}</strong> bytes
{{if total['bytes'] > 524287:}}
(<strong>{{="%.0d" % (total['bytes'] / 1048576)}} MB</strong>)
{{pass}}
{{else:}} <strong>not available</strong> (requires the Python <a href="http://pypi.python.org/pypi/guppy/" target="_blank">guppy</a> library)
{{pass}}
</p>
<p>
Cache contains items up to
<strong>{{="%02d" % total['oldest'][0]}}</strong> hours
<strong>{{="%02d" % total['oldest'][1]}}</strong> minutes
<strong>{{="%02d" % total['oldest'][2]}}</strong> seconds old.
</p>
{{=BUTTON(T('Cache Keys'), _onclick='jQuery("#all_keys").toggle();')}}
<div class="hidden" id="all_keys">
{{=total['keys']}}
</div>
<br />
{{pass}}
<h3>RAM</h3>
<p>Number of entries: <strong>{{=ram['entries']}}</strong>
{{if ram['entries'] > 0:}}
<p>
Hit Ratio:
<strong>{{=ram['ratio']}}%</strong>
(<strong>{{=ram['hits']}}</strong> hits
and <strong>{{=ram['misses']}}</strong> misses)
</p>
<p>
Size of cache:
{{if object_stats:}}
<strong>{{=ram['objects']}}</strong> items,
<strong>{{=ram['bytes']}}</strong> bytes
{{if ram['bytes'] > 524287:}}
(<strong>{{=ram['bytes'] / 1048576}} MB</strong>)
{{pass}}
{{else:}} <strong>not available</strong> (requires the Python <a href="http://pypi.python.org/pypi/guppy/" target="_blank">guppy</a> library)
{{pass}}
</p>
<p>
RAM contains items up to
<strong>{{="%02d" % ram['oldest'][0]}}</strong> hours
<strong>{{="%02d" % ram['oldest'][1]}}</strong> minutes
<strong>{{="%02d" % ram['oldest'][2]}}</strong> seconds old.
</p>
{{=BUTTON(T('RAM Cache Keys'), _onclick='jQuery("#ram_keys").toggle();')}}
<div class="hidden" id="ram_keys">
{{=ram['keys']}}
</div>
<br />
{{pass}}
<h3>DISK</h3>
<p>Number of entries: <strong>{{=disk['entries']}}</strong>
{{if disk['entries'] > 0:}}
<p>
Hit Ratio:
<strong>{{=disk['ratio']}}%</strong>
(<strong>{{=disk['hits']}}</strong> hits
and <strong>{{=disk['misses']}}</strong> misses)
</p>
<p>
Size of cache:
{{if object_stats:}}
<strong>{{=disk['objects']}}</strong> items,
<strong>{{=disk['bytes']}}</strong> bytes
{{if disk['bytes'] > 524287:}}
(<strong>{{=disk['bytes'] / 1048576}} MB</strong>)
{{pass}}
{{else:}} <strong>not available</strong> (requires the Python <a href="http://pypi.python.org/pypi/guppy/" target="_blank">guppy</a> library)
{{pass}}
</p>
<p>
DISK contains items up to
<strong>{{="%02d" % disk['oldest'][0]}}</strong> hours
<strong>{{="%02d" % disk['oldest'][1]}}</strong> minutes
<strong>{{="%02d" % disk['oldest'][2]}}</strong> seconds old.
</p>
{{=BUTTON(T('Disk Cache Keys'), _onclick='jQuery("#disk_keys").toggle();')}}
<div class="hidden" id="disk_keys">
{{=disk['keys']}}
</div>
<br />
{{pass}}
</div>
<div class="list-header">
<h2>Manage Cache</h2>
</div>
<div class="content">
<p>
{{=form}}
</p>
</div>
</div>
<div class="clear"></div>
</div>
{{pass}}
+159
View File
@@ -0,0 +1,159 @@
{{extend 'layout.html'}}
{{block sectionclass}}shell{{end}}
<!--style type="text/css">
.prompt, #output {
width: 45em;
border: 1px solid #CCCCCC;
font-size: 10pt;
margin: 0.5em;
padding: 0.5em;
padding-right: 0em;
overflow: auto;
wrap: hard;
}
#output {
height:250px;overflow:auto;
}
#toolbar {
margin-left: 0.5em;
padding-left: 0.5em;
}
#caret {
width: 2.5em;
margin-right: 0px;
padding-right: 0px;
border-right: 0px;
}
#statement {
width: 43em;
margin-left: -1em;
padding-left: 0px;
border-left: 0px;
background-position: top right;
background-repeat: no-repeat;
}
.processing {
background-image: url("{{=URL('static','images/spinner.gif')}}");
}
#ajax-status {
font-weight: bold;
}
.message {
color: #8AD;
font-weight: bold;
font-style: italic;
}
.error {
color: #F44;
}
.username {
font-weight: bold;
}
</style-->
<div id="wrapper">
<textarea id="output" readonly="readonly">web2py Debugger {{=request.env.web2py_version}}{{=data}}</textarea>
<form id="form" action="{{=URL(r=request,f='callback',args=app)}}" method="get">
<div id="shellwrapper">
<div id="caret">&gt;&gt;&gt;</div>
<div class="tooltip">
<textarea class="prompt" name="statement" id="statement"></textarea>
<span>Type PDB debugger command in here and hit Return (Enter) to execute it.</span>
</div>
</div>
</form>
</div>
<div class="help">
<ul>
<li>Using the shell may lock the database to other users of this app.</li>
</ul>
</div>
<script type="text/javascript">
var bShellScrolling=0
jQuery(document).ready(function(){
jQuery('#statement').focus();
jQuery('#statement').keyup(function(event){
var t=jQuery(this),
s=t.val(),
o=jQuery('#output'),
RETURN = 38;
if(s=='\n') t.val('');
if(s.length>1 && s.substr(s.length-1,1)=='\n' && s.substr(s.length-2,1)!=':' &&
(s.indexOf(':\n ')<0 || s.substr(s.length-2,1)=='\n')) {
t.val('');
jQuery.post("{{=URL(r=request,f='callback',args=app)}}",
{statement:s},function(data){o.html(o.html()+data).attr('scrollTop',o.attr('scrollHeight'));});
} else { };
if(event.keyCode==RETURN){
var i=s.length
if(i==0){
var s=o.find('table:last pre:first').text();
bShellScrolling=o.find('table').length;
}else if(bShellScrolling){
var i=bShellScrolling
if(i<1){
return
}else{
i--
var s=o.find('table:nth-child('+(i)+') pre:first').text();
bShellScrolling=i
}
}else if(s.indexOf('\n')<0){
var oo=o.find('tr:first-child pre:contains("'+s+'")')
if(oo.length==0){
return
}else if(oo.length==1){
s=oo.text();
}else{
sVar=oo.text();
o.html(o.html()+'<dd>'+s+' ?</dd><dt>'+sVar+'</dt>').attr('scrollTop',o.attr('scrollHeight'))
return
}
}else{
//multistring expr
return;
}
// if(s.slice(s.length-1)=='\n'){
s=s.slice(0,s.length-1)
// }
t.val(s);
}
if(bShellScrolling && event.keyCode==40){
var i=bShellScrolling
i++
var s=o.find('table:nth-child('+i+') tr:first-child pre').text();
if(s){
s=s.slice(0,s.length-1)
t.val(s);
bShellScrolling=i
}else{
bShellScrolling=0
t.val('')
}
};
if(bShellScrolling && (event.keyCode==37 || event.keyCode==39)){
bShellScrolling=0;
};
if(event.keyCode==27){
bShellScrolling=0;
t.val('');
};
});
});
</script>
@@ -0,0 +1,12 @@
{{extend 'layout.html'}}
{{block sectionclass}}about{{end}}
<h2>{{=T("About application")}} "{{=app}}"</h2>
<h3>{{=T("About")}} {{=app}}</h3>
<p class="controls">{{=button(URL('edit/%s/ABOUT' % (app)), T('Edit'))}}</p>
<div class="about_text legalese">{{=about}}</div>
<h3>{{=T('License for')}} {{=app}}</h3>
<p class="controls">{{=button(URL('edit/%s/LICENSE' % (app)), T('Edit'))}}</p>
<div class="license_text legalese">{{=license}}</div>
</ul>
@@ -0,0 +1,76 @@
<style>
.acw-chap pre, .acw-chap pre span, span.acw-char-check, .acw-chap .selection-area div
{
font:11px 'Courier', monospaced;
line-height:11px;
margin:0;
padding:0;
border:0;
}
.acw-chap .wrapped-row
{
background-image:url('{{=URL(r=request,c='static',f='eamy')}}/chap-wrapped-row.gif');
background-repeat:no-repeat;
background-position:25px 4px;
}
.acw-chap .sidebar
{
background-image:url('{{=URL(r=request,c='static',f='eamy')}}/chap-bg-sidebar.gif');
line-height:11px;
}
.acw-chap .sidebar .row-number
{
text-align:right;
font-size:9px;
font-family:'Lucida Grande', Verdana, Arial, Helvetica, sans-serif;
color:#999;
}
.acw-chap .folding-expand-inner
{
width:14px;
height:10px;
margin-left:2px;
display:inline;
background-image:url('{{=URL(r=request,c='static',f='eamy')}}/chap-folding-expand-inner.gif');
}
.acw-chap .folding-expand
{
background-image:url('{{=URL(r=request,c='static',f='eamy')}}/chap-folding-expand.gif');
}
.acw-chap .folding-start
{
background-image:url('{{=URL(r=request,c='static',f='eamy')}}/chap-folding-start.gif');
}
.acw-chap .folding-stop
{
background-image:url('{{=URL(r=request,c='static',f='eamy')}}/chap-folding-stop.gif');
}
.acw-chap .bookmark-default
{
background-image:url('{{=URL(r=request,c='static',f='eamy')}}/chap-bookmark-default.gif');
}
.acw-chap .void
{
background-image:url('{{=URL(r=request,c='static',f='eamy')}}/void.gif');
}
</style>
<script src="{{=URL(r=request,c='static',f='eamy/eamy.js')}}" type="text/javascript"></script>
<script src="{{=URL(r=request,c='static',f='js/jquery.hotkeys.js')}}" type="text/javascript" charset="utf-8"></script>
{{if request.args[1]=="views":}}
<script src="{{=URL(r=request,c='static',f='eamy/bundle_markup.js')}}" type="text/javascript"></script>
{{else:}}
<script src="{{=URL(r=request,c='static',f='eamy/bundle_python.js')}}" type="text/javascript"></script>
{{pass}}
<script language="Javascript" type="text/javascript" src="/{{=request.application}}/static/js/ajax_editor.js"></script>
<script language="Javascript" type="text/javascript">
jQuery(document).ready(function(){
setTimeout("keepalive('{{=URL('keepalive')}}')",10000);
});
jQuery(document).bind('keydown', 'alt+f1',function (evt){
doClickSave();
});
</script>
@@ -0,0 +1,9 @@
{{extend 'layout.html'}}
{{block sectionclass}}change_password{{end}}
<h2>Change Admin Password</h2>
<div class="pwform">
{{=form}}
</div>
@@ -0,0 +1,8 @@
{{extend 'layout.html'}}
{{block sectionclass}}delete{{end}}
<div class="center">
<h2>{{=T('Are you sure you want to delete file "%s"?', filename)}}</h2>
<p>{{=FORM(INPUT(_type='submit',_name='nodelete',_value=T('Abort')),INPUT(_type='hidden',_name='sender',_value=sender), _class="inline")}}{{=FORM(INPUT(_type='submit',_name='delete',_value=T('Delete')),INPUT(_type='hidden',_name='sender',_value=sender), _class="inline")}}</p>
</div>
@@ -0,0 +1,9 @@
{{extend 'layout.html'}}
{{block sectionclass}}delete_plugin{{end}}
<div class="center">
<h2>{{=T('Are you sure you want to delete plugin "%s"?', plugin)}}</h2>
<p>{{=FORM(INPUT(_type='submit',_name='nodelete',_value=T('NO')))}}</p>
<p>{{=FORM(INPUT(_type='submit',_name='delete',_value=T('YES')))}}</p>
</div>
@@ -0,0 +1,313 @@
{{extend 'layout.html'}}
{{
def all(items):
return reduce(lambda a,b:a and b,items,True)
def peekfile(path,file):
return A(file.replace('\\\\','/'),_href=URL('peek', args=(app, path, file)))
def editfile(path,file):
return A(SPAN(T('Edit')),_class='button editbutton',_href=URL('edit', args=(app, path, file)))
def testfile(path,file):
return A(TAG[''](IMG(_src=URL('static', 'images/test_icon.png'), _alt=T('test')), SPAN(T("Run tests in this file (to run all files, you may also use the button labelled 'test')"))), _class='icon test tooltip',_href=URL('test', args=(app, file)))
def editlanguagefile(path,file):
return A(SPAN(T('Edit')),_class='button editbutton',_href=URL('edit_language', args=(app, path, file)))
def file_upload_form(location):
form=FORM(T("upload file:")," ",
INPUT(_type="file",_name="file")," ",T("and rename it:")," ",
INPUT(_type="text",_name="filename",requires=IS_NOT_EMPTY),
INPUT(_type="hidden",_name="location",_value=location),
INPUT(_type="hidden",_name="sender",_value=URL('design',args=app)),
INPUT(_type="submit",_value=T("upload")),_action=URL('upload_file'))
return form
def file_create_form(location):
form=FORM(T("create file with filename:")," ",
INPUT(_type="text",_name="filename",requires=IS_NOT_EMPTY),
INPUT(_type="hidden",_name="location",_value=location),
INPUT(_type="hidden",_name="sender",_value=URL('design',args=app)),
INPUT(_type="submit",_value=T("Create")),_action=URL('create_file'))
return form
def upload_plugin_form(app):
form=FORM(T("upload plugin file:")," ",
INPUT(_type="file",_name="pluginfile"),
INPUT(_type="submit",_value=T("upload")))
return form
def deletefile(arglist):
return A(TAG[''](IMG(_src=URL('static', 'images/delete_icon.png')), SPAN(T('Delete this file (you will be asked to confirm deletion)'))), _class='icon delete tooltip', _href=URL('delete',args=arglist,vars=dict(sender=request.function+'/'+app)))
}}
{{block sectionclass}}design{{end}}
<h2>{{=T("Edit application")}} "{{=A(app,_href=URL(app,'default','index'),_target="_blank")}}"</h2>
<!-- COLLAPSE/JUMP-TO BUTTONS -->
<div class="right-full controls">
<p>
{{=searchbox('search')}}
<a class="button special" href="#" onclick="jQuery('h3').click();return false"><span>{{=T("collapse/expand all")}}</span></a>
<span class="buttongroup">
{{=button('#models', T("models"))}}
{{=button('#controllers', T("controllers"))}}
{{=button('#views', T("views"))}}
{{=button('#languages', T("languages"))}}
{{=button('#static', T("static"))}}
{{=button('#modules', T("modules"))}}
{{=button('#plugins', T("plugins"))}}
</span>
</p>
</div>
<!-- MODELS -->
<h3 id="models" onclick="collapse('models_inner');" class="component">
{{=T("Models")}}
<span class="tooltip">{{=helpicon()}} <span>{{=T("The data representation, define database tables and sets")}}</span></span>
</h3>
<div id="models_inner" class="component_contents">
{{if not models:}}<p><strong>{{=T("There are no models")}}</strong></p>{{else:}}
<div class="controls comptools">
{{=button(URL(a=app,c='appadmin',f='index'), T('database administration'))}}
{{if os.access(os.path.join(request.folder,'..',app,'databases','sql.log'),os.R_OK):}}
{{=button(URL('peek/%s/databases/sql.log'%app), 'sql.log')}}
{{pass}}
</div>
{{pass}}
<ul>
{{for m in models:}}
<li id="models__{{=m.replace('.','__')}}">
<span class="filetools controls">
{{=editfile('models',m)}}
{{=deletefile([app, 'models', m])}}
</span>
<span class="file">
{{=peekfile('models',m)}}
</span>
<span class="extras">
{{if len(defines[m]):}}{{=T("defines tables")}} {{pass}}{{=XML(', '.join([B(table).xml() for table in defines[m]]))}}
</span>
</li>
{{pass}}
</ul>
<div class="controls formfield">{{=file_create_form('%s/models/' % app)}}</div>
</div>
<!-- FIND CONTROLLER FUNCTIONS -->
{{
controller_functions=[]
for c in controllers: controller_functions+=[c[:-3]+'/%s.html'%x for x in functions[c]]
}}
<!-- CONTROLLERS -->
<h3 id="controllers" onclick="collapse('controllers_inner');" class="component">
{{=T("Controllers")}}
<span class="tooltip">{{=helpicon()}} <span>{{=T("The application logic, each URL path is mapped in one exposed function in the controller")}}</span></span>
</h3>
<div id="controllers_inner" class="component_contents">
{{if not controllers:}}<p><strong>{{=T("There are no controllers")}}</strong></p>{{else:}}
<div class="controls comptools">
{{=button(URL(r=request,c='shell',f='index',args=app), T("shell"))}}
{{=button(URL('test',args=app), T("test"))}}
{{=button(URL('edit',args=[app,'cron','crontab']), T("crontab"))}}
</div>
{{pass}}
<ul>
{{for c in controllers:}}
<li id="controllers__{{=c.replace('.','__')}}">
<span class="filetools controls">
{{=editfile('controllers',c)}}
{{=deletefile([app, 'controllers', c])}}
{{=testfile('controllers',c)}}
</span>
<span class="file">
{{=peekfile('controllers',c)}}
</span>
<span class="extras">
{{if functions[c]:}}{{=T("exposes")}} {{pass}}{{=XML(', '.join([A(f,_href=URL(a=app,c=c[:-3],f=f)).xml() for f in functions[c]]))}}
</span>
</li>
{{pass}}
</ul>
<div class="controls formfield">{{=file_create_form('%s/controllers/' % app)}}</div>
</div>
<!-- VIEWS -->
<h3 id="views" onclick="collapse('views_inner');" class="component">
{{=T("Views")}}
<span class="tooltip">{{=helpicon()}} <span>{{=T("The presentations layer, views are also known as templates")}}</span></span>
</h3>
<div id="views_inner" class="component_contents">
<div class="controls comptools">
{{=button(LAYOUTS_APP, T("download layouts"))}}
</div>
{{if not views:}}<p><strong>{{=T("There are no views")}}</strong></p>{{pass}}
<ul>
{{for c in views:}}
<li id="views__{{=c.replace('/','__').replace('.','__')}}">
<span class="filetools controls">
{{=editfile('views',c)}}
{{=deletefile([app, 'views', c])}}
</span>
<span class="file">
{{=peekfile('views',c)}}
</span>
<span class="extras">
{{if extend.has_key(c):}}{{=T("extends")}} <b>{{=extend[c]}}</b> {{pass}}
{{if include[c]:}}{{=T("includes")}} {{pass}}{{=XML(', '.join([B(f).xml() for f in include[c]]))}}
</span>
</li>
{{pass}}
</ul>
<div class="controls formfield">{{=file_create_form('%s/views/' % app)}}</div>
</div>
<!-- LANGUAGES -->
<h3 id="languages" onclick="collapse('languages_inner');" class="component">
{{=T("Languages")}}
<span class="tooltip">{{=helpicon()}} <span>{{=T("Translation strings for the application")}}</span></span>
</h3>
<div id="languages_inner" class="component_contents">
<div class="controls comptools">
{{=button(URL('update_languages/'+app), T('update all languages'))}}
</div>
{{if not languages:}}<p><strong>{{=T("There are no translators, only default language is supported")}}</strong></p>{{pass}}
<ul>
{{for file in languages:}}
<li id="languages__{{=file.replace('.','__')}}">
<span class="filetools controls">
{{=editlanguagefile('languages',file)}}
{{=deletefile([app, 'languages', file])}}
</span>
<span class="file">
{{=peekfile('languages',file)}}
</span>
</li>
{{pass}}
</ul>
<div class="controls formfield">{{=file_create_form('%s/languages/' % app)}}{{=T('(something like "it-it")')}}</div>
</div>
<!-- STATIC -->
<h3 id="static" onclick="collapse('static_inner');" class="component">
{{=T("Static files")}}
<span class="tooltip">{{=helpicon()}} <span>{{=T("These files are served without processing, your images go here")}}</span></span>
</h3>
<div id="static_inner" class="component_contents">
<div class="controls comptools">
</div>
{{if not statics:}}<p><strong>{{=T("There are no static files")}}</strong></p>{{pass}}
<ul>
{{
path=[]
for file in statics+['']:
items=file.split('/')
file_path=items[:-1]
filename=items[-1]
while path!=file_path:
if len(file_path)>=len(path) and all([v==file_path[k] for k,v in enumerate(path)]):
path.append(file_path[len(path)])
thispath='static__'+'__'.join(path)
}}
<li class="folder">
<a href="javascript:collapse('{{=thispath}}');" class="file">{{=path[-1]}}/</a>
<ul id="{{=thispath}}" style="display: none;" class="sublist">{{
else:
path = path[:-1]
}}
</ul></li>
{{
pass
pass
if filename:
}}<li>
<span class="filetools controls">
{{=editfile('static',file)}} {{=deletefile([app,'static',file])}}
</span>
<span class="file">
<a href="{{=URL(a=app,c='static',f=file)}}">{{=filename}}</a>
</span>
</li>{{
pass
pass
}}
{{pass}}
</ul>
<div class="controls formfield">{{=file_create_form('%s/static/' % app)}}
{{=file_upload_form('%s/static/' % app)}}</div>
</div>
<!-- MODULES -->
<h3 id="modules" onclick="collapse('modules_inner');" class="component">
{{=T("Modules")}}
<span class="tooltip">{{=helpicon()}} <span>{{=T("Additional code for your application")}}</span></span>
</h3>
<div id="modules_inner" class="component_contents">
<div class="controls comptools">
</div>
{{if not modules:}}<p><strong>{{=T("There are no modules")}}</strong></p>{{pass}}
<ul>
{{for m in modules:}}
<li id="modules__{{=m.replace('/','__').replace('.','__')}}">
<span class="filetols controls">
{{=editfile('modules',m)}}
{{if m!='__init__.py':}}{{=deletefile([app, 'modules', m])}}{{pass}}
</span>
<span class="file">
{{=peekfile('modules',m)}}
</span>
</li>
{{pass}}
</ul>
<div class="controls formfield">{{=file_create_form('%s/modules/' % app)}}
{{=file_upload_form('%s/modules/' % app)}}</div>
</div>
<!-- PLUGINS -->
<h3 id="plugins" onclick="collapse('plugins_inner');" class="component">
{{=T("Plugins")}}
<span class="tooltip">{{=helpicon()}} <span>{{=T("To create a plugin, name a file/folder plugin_[name]")}}</span></span>
</h3>
<div id="plugins_inner" class="component_contents">
<div class="controls comptools">
{{=button(PLUGINS_APP, T('download plugins'))}}
</div>
<div class="controls">
</div>
{{if plugins:}}
<ul>
{{for plugin in plugins:}}
<li>
{{=A('plugin_%s' % plugin, _class='file', _href=URL('plugin', args=[app, plugin]))}}
</li>
{{pass}}
</ul>
{{else:}}
<p><strong>{{=T('There are no plugins')}}</strong></p>
{{pass}}
<div class="controls formfield">{{=upload_plugin_form(app)}}</div>
</div>
<script>
jQuery(document).ready(function(){
jQuery('#search').keyup(function(e){
var code = (e.keyCode ? e.keyCode : e.which);
if(code==13 && jQuery('#search').val()){
jQuery.getJSON('{{=URL('search',args=request.args)}}?keywords='+escape(jQuery('#search').val()),null,function(data, textStatus, xhr){
jQuery('.component_contents li, .formfield, .comptools').hide();
files=data['files'];
for(var i=0; i<files.length; i++)
jQuery('li#'+files[i].replace(/\//g,'__').replace('.','__')).slideDown();
jQuery('.flash').html('{{=T("Searching:")}} '+files.length+' {{=T("files")}}').slideDown();
});
} else if(code==13) {
jQuery('.component_contents li, .formfield, .comptools').slideDown();
jQuery('.flash').html('').hide();
}
});
});
</script>
@@ -0,0 +1,13 @@
{{extend 'layout.html'}}
{{block sectionclass}}upgrade{{end}}
<h2>{{=T('web2py downgrade')}}</h2>
<p class="center"><strong class="att">{{=T('ATTENTION:')}}</strong> {{=T('This is an experimental feature and it needs more testing. If you decide to downgrade you do it at your own risk')}}<br />
{{=T('If start the downgrade, be patient, it may take a while to rollback')}}</p>
<div class="center">
{{=FORM(INPUT(_type='submit',_name='nodowngrade',_value=T('Cancel')), _class='inline')}}
{{=FORM(INPUT(_type='submit',_name='downgrade',_value=T('Downgrade')), _class='inline')}}
</div>
@@ -0,0 +1,92 @@
{{extend 'layout.html'}}
{{
def shortcut(combo, description):
return XML('<li><tt>%s</tt> %s</li>' % (combo, description))
}}
{{if TEXT_EDITOR == 'amy':}}
{{include 'default/amy_ajax.html'}}
{{else:}}
<script language="Javascript" type="text/javascript" src="{{=URL(r=request,c='static',f='edit_area/edit_area_full.js')}}"></script><script language="Javascript" type="text/javascript">
editAreaLoader.init({id: "body",start_highlight: true,allow_resize: "both",allow_toggle: {{=editarea_preferences['ALLOW_TOGGLE']}},language: "en",syntax: "{{=filetype}}",replace_tab_by_spaces: {{=editarea_preferences['REPLACE_TAB_BY_SPACES']}}, font_size: {{=editarea_preferences['FONT_SIZE']}}, fullscreen: {{=editarea_preferences['FULL_SCREEN']}}, display: "{{=editarea_preferences['DISPLAY']}}", show_line_colors: true, word_wrap: true, save_callback: "doClickSave" {{if filetype=='html':}},plugins: "zencoding"{{pass}} });
</script>
<script language="Javascript" type="text/javascript" src="{{=URL('static','js/ajax_editor.js')}}"></script>
<script language="Javascript" type="text/javascript">
jQuery(document).ready(function(){
setTimeout("keepalive('{{=URL('keepalive')}}')",10000);
});
</script>
{{pass}}
{{block sectionclass}}edit{{end}}
<h2>{{=T('Editing file "%s"',filename)}}</h2>
{{if functions:}}
<p class="formfield">
<span style="text-align:left;" id="exposed">
{{=B(T('exposes:'))}}{{=XML(', '.join([A(f,_href=URL(a=app,c=controller,f=f)).xml() for f in functions]))}}
</span>
{{if editviewlinks:}}<br/>
{{=B(T('edit views:'))}}
{{=XML(', '.join([v.xml() for v in editviewlinks]))}}
{{pass}}
</p>
{{pass}}
<p class="right controls">
{{=button(URL('design',args=request.args[0]), T('back'))}}
{{if edit_controller:}}
{{=button(edit_controller, T('edit controller'))}}
{{pass}}
{{if view_link:}}
{{=button(view_link, T('try view'))}}
{{pass}}
{{if request.args[1]=='models':}}
<a class="button" href="http://www.web2py.com/sqldesigner" target="_blank"><span>{{=T('online designer')}}</span></a>
{{pass}}
<a class="button" href="http://www.web2py.com/examples/static/epydoc/index.html" target="_blank"><span>{{=T('docs')}}</span></a>
</p>
<div id="editor_area">
<form action="{{=URL('edit',args=filename)}}" method="post" name="editform" id="editform">
<a value="save" name="save" onclick="return doClickSave();" class="icon saveicon">
{{=IMG(_src=URL('static', 'images/save_icon.png'), _alt=T('Save'))}}
</a>
{{=T('Saved file hash:')}}
<input type="input" name="file_hash" value="{{=file_hash}}" readonly="readonly"/>
{{=T('Last saved on:')}} <input type="input" name="saved_on" value="{{=saved_on}}" readonly="readonly"/>
{{if TEXT_EDITOR=='amy':}}
<textarea style="width: auto; height:400px;direction:ltr;" rows="58" cols="100" -amy-enabled="true" id="body" name="data">{{=data}}</textarea>
{{else:}}
<textarea cols="80" rows="25" id="body" style="direction:ltr;" name="data">{{=data}}</textarea>
{{pass}}
<button class="editbutton" onclick="window.location.reload(); return false">{{=T('restore')}}</button> {{=T('currently saved or')}} <button class="editbutton" type="submit" name="revert">{{=T('revert')}}</button>
{{=T('to previous version.')}}
<br/>
</form>
</div>
{{if filetype=='html':}}
<div class="help">
<h3>Key bindings for ZenCoding Plugin</h3>
<ul>
{{=shortcut('Ctrl+S', 'Save via Ajax')}}
{{=shortcut('Ctrl+,', 'Expand Abbreviation')}}
{{=shortcut('Ctrl+M', 'Match Pair')}}
{{=shortcut('Ctrl+H', 'Wrap with Abbreviation')}}
{{=shortcut('Shift+Ctrl+M', 'Merge Lines')}}
{{=shortcut('Ctrl+Shift+←', 'Previous Edit Point')}}
{{=shortcut('Ctrl+Shift+→', 'Next Edit Point')}}
{{=shortcut('Ctrl+Shift+↑', 'Go to Matching Pair')}}
</ul>
</div>
{{else:}}
<div class="help">
<h3>Key bindings</h3>
<ul>
{{=shortcut('Ctrl+S', 'Save via Ajax')}}
</ul>
</div>
{{pass}}
@@ -0,0 +1,18 @@
{{extend 'layout.html'}}
<script>
function delkey(id) {
jQuery('#'+id).hide();
jQuery('#'+id+' INPUT').val(String.fromCharCode(127));
jQuery('#'+id+' TEXTAREA').val(String.fromCharCode(127));
return false;
}
</script>
{{block sectionclass}}edit_language{{end}}
<h2>{{=T('Editing Language file')}} "{{=filename}}"</h2>
<div class="languageform">
{{=form}}
</div>
@@ -0,0 +1,133 @@
{{extend 'layout.html'}}
{{import os, stat, time}}
{{block sectionclass}}errors{{end}}
<style>
table.sortable {
border-spacing:0px;
}
table.sortable td, table.sortable th {
padding: 2px 5px 2px 5px;
}
table.sortable thead {
background-color:#eee;
color:#666666;
font-weight: bold;
cursor: default;
}
tr.error_ticket:hover {
background-color: #eee;
}
</style>
<script language="JavaScript">
function check(){
for (var i = 0; i < document.myform.elements.length; i++) {
var e = document.myform.elements[i];
if (e.type == 'checkbox') e.checked = true;
}
}
function uncheck(){
for (var i = 0; i < document.myform.elements.length; i++) {
var e = document.myform.elements[i];
if (e.type == 'checkbox') e.checked = false;
}
}
jQuery(document).ready(function() { jQuery('.traceback').hide(); });
</script>
<h2>{{=T('Error logs for "%(app)s"',dict(app=app))}}</h2>
<div class="errorform">
<form name="myform" method="post">
<input name="CheckAll" value="{{=T('check all')}}"
onclick="check()" type="button">
<input name="CheckAll" value="{{=T('uncheck all')}}"
onclick="uncheck()" type="button">
<input value="{{=T('delete all checked')}}" type="submit"><br><br>
{{ if 'new' in method: }}
{{base_url = 'db' in method and 'ticketdb' or 'ticket' }}
<h3>{{=T('Click row to expand traceback')}}</h3>
<p class="controls">
{{if 'db' in method:}}
source : db
<a class="button" href="{{=URL(args=[app, 'new'])}}"><span>switch to : filesystem</span></a>
<a class="button" href="{{=URL(args=[app, 'dbold'])}}"><span>lists by ticket</span></a>
{{else:}}
source : filesystem
<a class="button" href="{{=URL(args=[app, 'dbnew'])}}"><span>switch to : db</span></a>
<a class="button" href="{{=URL(args=[app, 'old'])}}"><span>lists by ticket</span></a>
{{pass}}
</p>
<table id="trck_errors" class="sortable">
<thead>
<tr>
<th>{{=T("Delete")}}</th>
<th>{{=T("Count")}}</th>
<th>{{=T("File")}}</th>
<th>{{=T("Error")}}</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
{{for e in errors:}}
<tr class="error_ticket">
<td><input type="checkbox" name="delete_{{=e['hash']}}" /></td>
<td>{{=e['count']}}</td>
<td>{{=e['causer']}}</td>
<td>{{=A(e['last_line'],_href="#",_onclick="collapse('%s');"%e['hash'])}}</td>
<td>+</td>
<td>{{=A(T('details'),_href=URL(base_url,args=[app,e['ticket']]))}}</td>
</tr>
<tr id="{{=e['hash']}}" class="traceback">
<td colspan="6">
<div>
{{=CODE(e['pickel']['traceback'])}}
</div>
</td>
</tr>
{{pass}}
</tbody>
</table>
{{ else: }}
<h3>{{=T('Click row to view a ticket')}}</h3>
<p class="controls">
{{if 'db' in method:}}
source : db
<a class="button" href="{{=URL(args=[app, 'old'])}}"><span>switch to : filesystem</span></a>
<a class="button" href="{{=URL(args=[app, 'dbnew'])}}"><span>lists by exception</span></a>
{{else:}}
source : filesystem
<a class="button" href="{{=URL(args=[app, 'dbold'])}}"><span>switch to : db</span></a>
<a class="button" href="{{=URL(args=[app, 'new'])}}"><span>lists by exception</span></a>
{{pass}}
</p>
<table class="sortable">
<thead>
<tr>
<th>{{=T("Delete")}}</th>
<th>{{=T("Ticket")}}</th>
<th>{{=T("Date and Time")}}</th>
</tr>
</thead>
<tbody>
{{for ticket in tickets:}}
<tr>
<td><input type="checkbox" name="delete_{{=ticket}}"/></td>
{{if 'db' in method:}}
<td><a href="{{=URL('ticketdb',args=[app,ticket])}}">{{=ticket}}</a></td>
<td>{{=time.strftime('%Y-%m-%d %H:%M:%S',times[ticket].timetuple())}}</td>
{{else:}}
<td><a href="{{=URL('ticket',args=[app,ticket])}}">{{=ticket}}</a></td>
<td>{{=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(os.stat(os.path.join(request.folder,'../%s/errors/%s' % (app,ticket)))[stat.ST_CTIME]))}}</td>
{{pass}}
</tr>
{{pass}}
</tbody>
</table>
{{ pass }}
</form>
</div>
@@ -0,0 +1,21 @@
{{extend 'layout.html'}}
<script type="text/javascript">
jQuery(function() {
jQuery("#password").focus();
});
</script>
{{block sectionclass}}login{{end}}
<h2>web2py&trade; {{=T('Web Framework')}}</h2>
<h3>{{=T('Login to the Administrative Interface')}}</h3>
<p class="help">{{=T('ATTENTION: Login requires a secure (HTTPS) connection or running on localhost.')}}</p>
<div class="form">
<form action="{{=URL(r=request)}}" method="post">
<div><input type="hidden" name="send" value="{{=send}}"/></div>
<table>
<tr><td>{{=T('Administrator Password:')}}</td><td><input type="password" name="password" id="password"/></td></tr>
<tr><td></td><td><input type="submit" name="login" value="{{=T('Login')}}"/></td></tr>
</table>
</form>
</div>
@@ -0,0 +1,16 @@
{{extend 'layout.html'}}
{{block sectionclass}}peek{{end}}
<h2>{{=T("Peeking at file")}} "{{=filename}}"</h2>
<p class="controls">
{{=button(URL('design',args=request.args[0]), T('back'))}}
{{=button(URL('edit',args=request.args), T('Edit'))}}
</p>
{{
if filename[-3:]=='.py': language='python'
else: language='html'
}}
{{=CODE(data,language=language,link='/examples/global/vars/')}}
@@ -0,0 +1,221 @@
{{extend 'layout.html'}}
{{
import os
def all(items):
return reduce(lambda a,b:a and b,items,True)
def peekfile(path,file):
return A(file.replace('\\\\','/'),_href=URL('peek', args=(app, path, file)))
def editfile(path,file):
return A(SPAN(T('Edit')),_class='button editbutton',_href=URL('edit', args=(app, path, file)))
def testfile(path,file):
return A(TAG[''](IMG(_src=URL('static', 'images/test_icon.png'), _alt=T('test')), SPAN(T("Run tests in this file"))), _class='icon test tooltip',_href=URL('test', args=(app, file)))
def editlanguagefile(path,file):
return A(SPAN(T('Edit')),_class='button editbutton',_href=URL('edit_language', args=(app, path, file)))
def file_upload_form(location):
form=FORM(T("upload file:")," ",
INPUT(_type="file",_name="file")," ",T("and rename it:")," ",
INPUT(_type="text",_name="filename",requires=IS_NOT_EMPTY),
INPUT(_type="hidden",_name="location",_value=location),
INPUT(_type="hidden",_name="sender",_value=URL('design/'+app)),
INPUT(_type="submit",_value=T("submit")),_action=URL('upload_file'))
return form
def file_create_form(location):
form=FORM(T("create file with filename:")," ",
INPUT(_type="text",_name="filename",requires=IS_NOT_EMPTY),
INPUT(_type="hidden",_name="location",_value=location),
INPUT(_type="hidden",_name="sender",_value=URL('design/'+app)),
INPUT(_type="submit",_value=T("submit")),_action=URL('create_file'))
return form
def upload_plugin_form(app):
form=FORM(T("upload plugin file:")," ",
INPUT(_type="file",_name="pluginfile"),
INPUT(_type="submit",_value=T("submit")))
return form
def deletefile(arglist):
return A(TAG[''](IMG(_src=URL('static', 'images/delete_icon.png')), SPAN(T('Delete this file (you will be asked to confirm deletion)'))), _class='icon delete tooltip', _href=URL('delete',args=arglist,vars=dict(sender=request.function+'/'+app)))
}}
{{block sectionclass}}plugin{{end}}
<h2>
{{=T('Plugin "%s" in application', request.args(1))}} "{{=app}}"
</h2>
<div class="right-full controls">
<a class="button special" href="#" onclick="jQuery('h3').click();return false"><span>{{=T("collapse/expand all")}}</span></a>
<span class="buttongroup">
{{=button("#models", T("models"))}}
{{=button("#controllers", T("controllers"))}}
{{=button("#views", T("views"))}}
{{=button("#static", T("static"))}}
{{=button("#modules", T("modules"))}}
</span>
<span class="buttongroup">
{{=sp_button(URL('plugin',args=app), T("back"))}}
{{=sp_button(URL('delete_plugin',args=request.args), T("delete plugin"))}}
{{=sp_button(URL('pack_plugin',args=request.args), T("pack plugin"))}}
</span>
</div>
<!-- MODELS -->
<h3 id="models" onclick="collapse('models_inner');" class="component">
{{=T("Models")}}
</h3>
<div id="models_inner" class="component_contents">
{{if not models:}}
<p><strong>{{=T("There are no models")}}</strong></p>
{{pass}}
<div class="controls comptools">
</div>
<ul>
{{for m in models:}}
<li>
<span class="filetools controls">
{{=editfile('models',m)}}
{{=deletefile([app, 'models', m])}}
</span>
<span class="file">
{{=peekfile('models',m)}}
</span>
<span class="extras">
{{if len(defines[m]):}}{{=T("defines tables")}} {{pass}}{{=XML(', '.join([B(table).xml() for table in defines[m]]))}}
</span>
</li>
{{pass}}
</ul>
</div>
<!-- FIND CONTROLLER FUNCTIONS -->
{{
controller_functions=[]
for c in controllers: controller_functions+=[c[:-3]+'/%s.html'%x for x in functions[c]]
}}
<!-- CONTROLLERS -->
<h3 id="controllers" onclick="collapse('controllers_inner');" class="component">
{{=T("Controllers")}}
</h3>
<div id="controllers_inner" class="component_contents">
{{if not controllers:}}
<p><strong>{{=T("There are no controllers")}}</strong></p>
{{pass}}
<div class="controls comptools">
</div>
<ul>
{{for c in controllers:}}
<li>
<span class="filetools controls">
{{=editfile('controllers',c)}}
{{=deletefile([app,'controllers',c])}}
{{=testfile('controllers',c)}}
</span>
<span class="file">
{{=peekfile('controllers',c)}}
</span>
<span class="extras">
{{if functions[c]:}}{{=T("exposes")}} {{pass}}{{=XML(', '.join([A(f,_href=URL(a=app,c=c[:-3],f=f)).xml() for f in functions[c]]))}}
</span>
</li>
{{pass}}
</ul>
</div>
<!-- VIEWS -->
<h3 id="views" onclick="collapse('views_inner');" class="component">
{{=T("Views")}}
</h3>
<div id="views_inner" class="component_contents">
{{if not views:}}
<p><strong>{{=T("There are no views")}}</strong></p>
{{pass}}
<div class="controls comptools">
</div>
<ul>
{{for c in views:}}
<li>
<span class="filetools controls">
{{=editfile('views',c)}}
{{=deletefile([app,'views',c])}}
</span>
<span class="file">
{{=peekfile('views',c)}}
</span>
<span class="extras">
{{if extend.has_key(c):}}{{=T("extends")}} <b>{{=extend[c]}}</b> {{pass}}
{{if include[c]:}}{{=T("includes")}} {{pass}}{{=XML(', '.join([B(f).xml() for f in include[c]]))}}
</span>
</li>
{{pass}}
</ul>
</div>
<!-- STATIC -->
<h3 id="static" onclick="collapse('static_inner');" class="component">
{{=T("Static files")}}
</h3>
<div id="static_inner" class="component_contents">
{{if not statics:}}<p><strong>{{=T("There are no static files")}}</strong></p>{{pass}}
<ul>
{{
path=[]
for file in statics+['']:
items=file.split('/')
file_path=items[:-1]
filename=items[-1]
while path!=file_path:
if len(file_path)>=len(path) and all([v==file_path[k] for k,v in enumerate(path)]):
path.append(file_path[len(path)])
thispath='static__'+'__'.join(path)
}}
<li class="folder">
<a href="javascript:collapse('{{=thispath}}');" class="file">{{=path[-1]}}/</a>
<ul id="{{=thispath}}" style="display: none;" class="sublist">{{
else:
path = path[:-1]
}}
</ul></li>
{{
pass
pass
if filename:
}}<li>
<span class="filetools controls">
{{=editfile('static',file)}} {{=deletefile([app,'static',file])}}
</span>
<span class="file">
<a href="{{=URL(a=app,c='static',f=file)}}">{{=filename}}</a>
</span>
</li>{{
pass
pass
}}
{{pass}}
</ul>
</div>
<!-- MODULES -->
<h3 id="modules" onclick="collapse('modules_inner');" class="component">
{{=T("Modules")}}
</h3>
<div id="modules_inner" class="component_contents">
{{if not modules:}}
<p><strong>{{=T("There are no modules")}}</strong></p>
{{pass}}
<div class="controls comptools">
</div>
<ul>
{{for m in modules:}}
<li>
{{=editfile('modules',m)}}
{{if m!='__init__.py':}}<a class="button" href="{{=URL('delete',args=[app,'modules',m],vars=dict(sender=request.function+'/'+app))}}">{{=T("delete")}}</a>{{pass}}
{{=peekfile('modules',m)}}
</li>
{{pass}}
</ul>
</div>
@@ -0,0 +1,24 @@
{{extend 'layout.html'}}
{{block sectionclass}}resolve{{end}}
<h2>{{=T('Resolve Conflict file')}} "{{=filename}}"</h2>
<script>
function plus() {jQuery('.plus').show(); jQuery('.minus').hide(); }
function minus() {jQuery('.plus').hide(); jQuery('.minus').show(); }
function all() {jQuery('.plus').show(); jQuery('.minus').show(); }
</script>
<div class="controls">
<button onclick="plus()">new</button>
<button onclick="minus()">old</button>
<button onclick="all()">all</button>
</div>
<div class="form">
<form action="{{=URL(r=request,args=request.args)}}" method="post">
{{=diff}}
<input type="submit" name="merge" value="{{=T('merge')}}" /><br/>
</form>
</div>
+158
View File
@@ -0,0 +1,158 @@
{{extend 'layout.html'}}
{{import os, glob}}
{{block sectionclass}}site{{end}}
<div class="applist f60">
<div class="applist_inner">
<h2>{{=T("Installed applications")}}</h2>
<ul>
{{for a in apps:}}
<li class="application"> <!-- onmouseover="jQuery(this).children('p').show()" onmouseout="jQuery(this).children('p').hide()"-->
{{if a==request.application:}}
<h3 class="currentapp">{{=a}} ({{=T('currently running')}})</h3>
<p class="controls">
{{else:}}
<h3 class="editableapp">{{=A(a,_href=URL(a,'default','index'))}}</h3>
{{if MULTI_USER_MODE and db.app(name=a):}}(created by {{="%(first_name)s %(last_name)s" % db.auth_user[db.app(name=a).owner]}}){{pass}}
<p class="controls">
{{if not os.path.exists('applications/%s/compiled' % a):}}
{{=sp_button(URL('design',args=a), T("Edit"))}}
{{else:}}
{{=button(URL(a,'appadmin','index'), T("appadmin"))}}
{{pass}}
{{=button(URL('about',args=a), T("About"))}}
{{pass}}
{{=button(URL('errors',args=a), T("Errors"))}}
{{=button(URL('cleanup',args=a), T("Clean"))}}
{{=button(URL('pack',args=a), T("Pack all"))}}
{{if not os.path.exists('applications/%s/compiled' % a):}}
{{=button(URL('compile_app',args=a), T("Compile"))}}
{{else:}}
{{=button(URL('pack',args=(a, 'compiled')), T("Pack compiled"))}}
{{if glob.glob('applications/%s/controllers/*.py' % a):}}
{{=button(URL('remove_compiled_app',args=a), T("Remove compiled"))}}
{{pass}}
{{pass}}
{{if a!=request.application:}}
{{=button(URL('uninstall',args=a), T("Uninstall"))}}
{{=button_enable(URL('enable',args=a), a)}}
{{pass}}
</p>
</li>
{{pass}}
</ul>
</div>
</div>
<div class="sidebar fl60">
<div class="sidebar_inner controls">
<div class="pwdchange">
<!-- CHANGE ADMIN PWD -->
{{if MULTI_USER_MODE:}}
{{=auth.navbar()}}
{{else:}}
{{=sp_button(URL('change_password'), T('Change admin password'))}}
{{pass}}
</div>
<!-- VERSION -->
{{if is_manager():}}
<div class="box">
<h3>{{="Version %s.%s.%s (%s) %s" % myversion}}</h3>
{{if session.check_version:}}
<p id="check_version">
{{=T('Checking for upgrades...')}}
<script>ajax('{{=URL('check_version')}}',[],'check_version');</script>{{session.check_version=False}}
{{else:}}
<p id="check_version">
{{=button("javascript:ajax('"+URL('check_version')+"',[],'check_version')", T('Check for upgrades'))}}
{{pass}}
</p>
<div class="formfield">
Running on {{=request.env.server_software}}
</div>
<p>{{=button(URL('default','reload_routes'), T('Reload routes'))}}</p>
</div>
{{pass}}
<!-- APP WIZARD -->
<div class="box">
<h3>{{=T("New application wizard")}}</h3>
<p>{{=button(URL('wizard','index'), T('Start wizard'))}}
{{=T("(requires internet access)")}}</p>
</div>
<!-- SCAFFOLD APP -->
<div class="box">
<h3>{{=T("New simple application")}}</h3>
<form action="" enctype="multipart/form-data" method="post">
<div class="formfield">
{{=LABEL(T("Application name:"), _for="scaffold_filename")}}
<input name="filename" type="text" id="scaffold_filename" />
<button type="submit" class="button">{{=T('Create')}}</button>
</div>
<div class="hidden"></div>
</form>
</div>
<!-- UPLOAD PACKAGE -->
<div class="box">
<h3>{{=T("Upload and install packed application")}}</h3>
<form action="" enctype="multipart/form-data" method="post">
<div class="formfield">
<table>
<tr>
<td>
{{=LABEL(T("Application name:"), _form='upload_filename')}}
</td>
<td>
<input id="appname" name="filename" type="text" id="upload_filename" />
</td>
</tr>
<tr>
<td>
{{=LABEL(T("Upload a package:"), _for='upload_file')}}
</td>
<td>
<input id="file" name="file" type="file" id="upload_file" />
<b>OR</b>
</td>
</tr>
<tr>
<td>
{{=LABEL(T("Get from URL:"), _for='upload_url')}}
</td>
<td>
<input id="appurl" name="appurl" type="text" id="upload_url"/>
</td>
</tr>
<tr>
<td></td>
<td>
<input type="checkbox" name="overwrite_check" id="upload_overwrite" />
{{=LABEL(T("Overwrite installed app"), _for='upload_overwrite')}}
</td>
</tr>
<tr>
<td></td>
<td>
<button type="submit">{{=T('Install')}}</button>
</td>
</tr>
</table>
</div>
</form>
</div>
<!-- DEPLOY ON GAE -->
<div class="box">
<h3>{{=T("Deploy on Google App Engine")}}</h3>
<p>{{=button(URL('gae','deploy'), T('Deploy'))}}</p>
</div><br/>
{{if TWITTER_HASH:}}
<div class="box">
<h3>{{=T("%s Recent Tweets"%TWITTER_HASH)}}</h3>
<div id="tweets">{{=T('loading...')}}</div>
<script>
jQuery(document).ready(function(){jQuery('#tweets').load('{{=URL('twitter')}}')});
</script>
</div>
{{pass}}
</div>
</div>
@@ -0,0 +1,20 @@
{{extend 'layout.html'}}
{{block sectionclass}}test{{end}}
<h2>{{=T('Testing application')}} "{{=app}}"</h2>
{{for controller in sorted(controllers):}}
<div id='output_{{=controller[:-3]}}'>
<h3>Testing controller "{{=controller}}"... <blink>please wait!</blink></h3>
</div>
<script><!--
ajax('{{=URL(a=app,c=controller[:-3],f='_TEST')}}',[],'output_{{=controller[:-3]}}');
//--></script>
{{pass}}
<p class="help">{{=T("""If the report above contains a ticket number it indicates a failure in executing the controller, before any attempt to execute the doctests. This is usually due to an indentation error or an error outside function code.
A green title indicates that all tests (if defined) passed. In this case test results are not shown.""")}}</p>
<p class="help">{{=T('Functions with no doctests will result in [passed] tests.')}}</p>
<p class="help">{{=T('ATTENTION: TESTING IS NOT THREAD SAFE SO DO NOT PERFORM MULTIPLE TESTS CONCURRENTLY.')}}</p>
@@ -0,0 +1,132 @@
{{extend 'layout.html'}}
{{block sectionclass}}ticket{{end}}
<h2>{{=T('Error ticket')}} for "{{=app}}"</h2>
<h3>{{=T('Ticket ID')}}</h3>
<p>{{=ticket}}</p>
{{if output:}}<h4>{{=output}}</h4>{{pass}}
<h3>{{=T('Version')}}</h3>
<table class="versions">
<tbody>
<tr>
<th>web2py&trade;</th>
<td>{{=myversion}}</td>
</tr>
<tr>
<th>Python</th>
<td>{{=snapshot.get('pyver','')}}</td>
</tr>
</tbody>
</table>
<h3>{{=T('Traceback')}}</h3>
<div class="inspect">
{{=traceback}}
</div>
{{if snapshot:}}
{{try:}}
<!-- ERROR SNAPSHOT -->
<h3>
{{=T('Error snapshot')}}
<span class="tooltip">{{=helpicon()}} <span>{{=T('Detailed traceback description')}}</span></span>
</h3>
<!-- SNAPSHOT LIST -->
<div id="snapshot">
<!-- Exception details -->
<p class="exception_object inspect">
<code>{{=snapshot['etype']}}({{=snapshot['evalue']}})</code>
</p>
<p class="controls">
<a class="button" onclick="collapse('exception_inner');"><span>{{=T('inspect attributes')}}</span></a>
</p>
<div id="exception_inner" class="hide">
<div class="inspect">
<h5>{{=T("Exception instance attributes")}}</h5>
<table>
<tbody>
{{for k,v in snapshot['exception'].items():}}
<tr>
<th>{{=k}}</th>
<td>{{=v}}</td>
</tr>
{{pass}}
</tbody>
</table>
</div>
</div>
</div>
<!-- FRAMES -->
<div id="frames">
<h4>{{=T('Frames')}}</h4>
<ul>
{{for i, frame in enumerate(snapshot['frames']):}}
<li>
{{is_hidden = (i != len(snapshot['frames'])-1 and 'hide' or 'inspect')}}
<div class="framefile inspect controls">
<p>
<strong>File {{="%s in %s at line %s" % (frame['file'], frame['func'], frame['lnum'])}}</strong>
<a class="button tbbutton" onclick="collapse('{{="%s_code_inner" % i}}');"><span>{{=T("code")}}</span></a>
<a class="button tbbutton" onclick="collapse('{{="%s_args_inner" % i}}');"><span>{{=T("arguments")}}</span></a>
<a class="button tbbutton" onclick="collapse('{{="%s_vars_inner" % i}}');"><span>{{=T("variables")}}</span></a>
</p>
<div id="{{="%s_args_inner" % i}}" class="{{=is_hidden}}">
<h5>Function argument list</h5>
<p>{{=frame['call']}}</p>
</div>
<div id="{{="%s_code_inner" % i}}" class="{{=is_hidden}}">
<h5>Code listing</h5>
{{if frame['lines']:}}
<pre>{{=CODE('\n'.join([x[1] for x in sorted(frame['lines'].items(),key=lambda x: x[0])]),
language='python', link=None, counter=min(frame['lines'].keys()), highlight_line=frame['lnum'])}}</pre>
{{pass}}
</div>
<div id="{{="%s_vars_inner" % i}}" class="{{=is_hidden}}">
<h5>Variables</h5>
<table>
<tbody>
{{for k,v in frame['dump'].items():}}
<tr>
<th>{{=k}}</th>
<td>{{=v}}</td>
</tr>
{{pass}}
</tbody>
</table>
</div>
</div>
</li>
{{pass}}
</ul>
</div>
<!-- VIEW ENVIRONMENT -->
<div class="viewenv">
<h4>Context</h4>
<p class="controls">
<a class="button" onclick="jQuery('#locals').slideToggle()"><span>{{=T('locals')}}</span></a>
<a class="button" onclick="jQuery('#request').slideToggle()"><span>{{=T('request')}}</span></a>
<a class="button" onclick="jQuery('#session').slideToggle()"><span>{{=T('session')}}</span></a>
<a class="button" onclick="jQuery('#response').slideToggle()"><span>{{=T('response')}}</span></a>
</p>
<div class="hide inspect" id="locals"><h6>locals</h6>{{=BEAUTIFY(snapshot['locals'])}}</div>
<div class="hide inspect" id="request"><h6>request</h6>{{=BEAUTIFY(snapshot['request'])}}</div>
<div class="hide inspect" id="session"><h6>session</h6>{{=BEAUTIFY(snapshot['session'])}}</div>
<div class="hide inspect" id="response"><h6>response</h6>{{=BEAUTIFY(snapshot['response'])}}</div>
</div>
{{except Exception, e:}}
<!-- this should not happen, just in case... (cannot output normal hmtl as we don't know current open tags) -->
{{import traceback;tb=traceback.format_exc().replace("\n","\\n") }}
<script language='javascript'>alert("Exception during snapshot rendering: {{=tb}} ");</script>
{{pass}}
{{pass}}
<div class="errorsource">
<h3>In file: {{=layer}}</h3>
{{=CODE(code.replace('\r',''),language='python',link='/examples/global/vars/')}}
</div>
@@ -0,0 +1,130 @@
{{block sectionclass}}ticket{{end}}
<h2>{{=T('Error ticket')}} for "{{=app}}"</h2>
<h3>{{=T('Ticket ID')}}</h3>
<p>{{=ticket}}</p>
{{if output:}}<h4>{{=output}}</h4>{{pass}}
<h3>{{=T('Version')}}</h3>
<table class="versions">
<tbody>
<tr>
<th>web2py&trade;</th>
<td>{{=myversion}}</td>
</tr>
<tr>
<th>Python</th>
<td>{{=snapshot.get('pyver','')}}</td>
</tr>
</tbody>
</table>
<h3>{{=T('Traceback')}}</h3>
<div class="inspect">
{{=traceback}}
</div>
{{if snapshot:}}
{{try:}}
<!-- ERROR SNAPSHOT -->
<h3>
{{=T('Error snapshot')}}
<span class="tooltip">{{=helpicon()}} <span>{{=T('Detailed traceback description')}}</span></span>
</h3>
<!-- SNAPSHOT LIST -->
<div id="snapshot">
<!-- Exception details -->
<p class="exception_object inspect">
<code>{{=snapshot['etype']}}({{=snapshot['evalue']}})</code>
</p>
<p class="controls">
<a class="button" onclick="collapse('exception_inner');"><span>{{=T('inspect attributes')}}</span></a>
</p>
<div id="exception_inner" class="hide">
<div class="inspect">
<h5>{{=T("Exception instance attributes")}}</h5>
<table>
<tbody>
{{for k,v in snapshot['exception'].items():}}
<tr>
<th>{{=k}}</th>
<td>{{=v}}</td>
</tr>
{{pass}}
</tbody>
</table>
</div>
</div>
</div>
<!-- FRAMES -->
<div id="frames">
<h4>{{=T('Frames')}}</h4>
<ul>
{{for i, frame in enumerate(snapshot['frames']):}}
<li>
{{is_hidden = (i != len(snapshot['frames'])-1 and 'hide' or 'inspect')}}
<div class="framefile inspect controls">
<p>
<strong>File {{="%s in %s at line %s" % (frame['file'], frame['func'], frame['lnum'])}}</strong>
<a class="button tbbutton" onclick="collapse('{{="%s_code_inner" % i}}');"><span>{{=T("code")}}</span></a>
<a class="button tbbutton" onclick="collapse('{{="%s_args_inner" % i}}');"><span>{{=T("arguments")}}</span></a>
<a class="button tbbutton" onclick="collapse('{{="%s_vars_inner" % i}}');"><span>{{=T("variables")}}</span></a>
</p>
<div id="{{="%s_args_inner" % i}}" class="{{=is_hidden}}">
<h5>Function argument list</h5>
<p>{{=frame['call']}}</p>
</div>
<div id="{{="%s_code_inner" % i}}" class="{{=is_hidden}}">
<h5>Code listing</h5>
{{if frame['lines']:}}
<pre>{{=CODE('\n'.join([x[1] for x in sorted(frame['lines'].items(),key=lambda x: x[0])]),
language='python', link=None, counter=min(frame['lines'].keys()), highlight_line=frame['lnum'])}}</pre>
{{pass}}
</div>
<div id="{{="%s_vars_inner" % i}}" class="{{=is_hidden}}">
<h5>Variables</h5>
<table>
<tbody>
{{for k,v in frame['dump'].items():}}
<tr>
<th>{{=k}}</th>
<td>{{=v}}</td>
</tr>
{{pass}}
</tbody>
</table>
</div>
</div>
</li>
{{pass}}
</ul>
</div>
<!-- VIEW ENVIRONMENT -->
<div class="viewenv">
<h4>Context</h4>
<p class="controls">
<a class="button" onclick="jQuery('#locals').slideToggle()"><span>{{=T('locals')}}</span></a>
<a class="button" onclick="jQuery('#request').slideToggle()"><span>{{=T('request')}}</span></a>
<a class="button" onclick="jQuery('#session').slideToggle()"><span>{{=T('session')}}</span></a>
<a class="button" onclick="jQuery('#response').slideToggle()"><span>{{=T('response')}}</span></a>
</p>
<div class="hide inspect" id="locals"><h6>locals</h6>{{=BEAUTIFY(snapshot['locals'])}}</div>
<div class="hide inspect" id="request"><h6>request</h6>{{=BEAUTIFY(snapshot['request'])}}</div>
<div class="hide inspect" id="session"><h6>session</h6>{{=BEAUTIFY(snapshot['session'])}}</div>
<div class="hide inspect" id="response"><h6>response</h6>{{=BEAUTIFY(snapshot['response'])}}</div>
</div>
{{except Exception, e:}}
<!-- this should not happen, just in case... (cannot output normal hmtl as we don't know current open tags) -->
{{import traceback;tb=traceback.format_exc().replace("\n","\\n") }}
<script language='javascript'>alert("Exception during snapshot rendering: {{=tb}} ");</script>
{{pass}}
{{pass}}
<div class="errorsource">
<h3>In file: {{=layer}}</h3>
{{=CODE(code.replace('\r',''),language='python',link='/examples/global/vars/')}}
</div>
@@ -0,0 +1,9 @@
{{extend 'layout.html'}}
<center>
<h2>{{=T('Are you sure you want to uninstall application "%s"?', app)}}</h2>
<table><tr>
<td>{{=FORM(INPUT(_type='submit',_name='nodelete',_value=T('Abort')))}}</td>
<td>{{=FORM(INPUT(_type='submit',_name='delete',_value=T('Uninstall')))}}</td>
</tr></table>
</center>
@@ -0,0 +1,13 @@
{{extend 'layout.html'}}
{{block sectionclass}}upgrade{{end}}
<h2>{{=T('web2py upgrade')}}</h2>
<p class="center"><strong class="att">{{=T('ATTENTION:')}}</strong> {{=T('This is an experimental feature and it needs more testing. If you decide to upgrade you do it at your own risk')}}<br />
{{=T('If start the upgrade, be patient, it may take a while to download')}}</p>
<div class="center">
{{=FORM(INPUT(_type='submit',_name='noupgrade',_value=T('Cancel')), _class='inline')}}
{{=FORM(INPUT(_type='submit',_name='upgrade',_value=T('Upgrade')), _class='inline')}}
</div>
@@ -0,0 +1,19 @@
{{extend 'layout.html'}}
<h2>{{=T( request.args(0).replace('_',' ').capitalize() )}}</h2>
<div id="web2py_user_form">
{{=form}}
{{if request.args(0)=='login':}}
{{if not 'register' in auth.settings.actions_disabled:}}
<br/><a href="{{=URL(r=request,args='register')}}">register</a>
{{pass}}
{{if not 'request_reset_password' in auth.settings.actions_disabled:}}
<br/><a href="{{=URL(r=request,args='request_reset_password')}}">lost password</a>
{{pass}}
{{pass}}
</div>
<script language="javascript">
<!--
jQuery("#web2py_user_form input:visible:enabled:first").focus();
//-->
</script>
+30
View File
@@ -0,0 +1,30 @@
{{extend 'layout.html'}}
<script>$=jQuery</script>
<link rel="stylesheet" type="text/css" href="{{=URL(r=request,c='static',f='css/jqueryMultiSelect.css')}}" />
<script src="{{=URL(r=request,c='static',f='js/jqueryMultiSelect.js')}}"></script>
<script>
function callback() {
$.get('{{=URL(r=request,f='callback')}}','',function(data,status){ if(data!='<done/>') { $('#target').html($('#target').html()+data); callback(); } });
}
$(document).ready(function() {
$('#no_table_applications').multiSelect({selectAll: false});
callback();
});
</script>
<h2>Google App Engine Deployment Interface</h2>
<p class="help">{{=T("This page can upload your application to the Google App Engine computing cloud. Mind that you must first create indexes locally and this is done by installing the Google appserver and running the app locally with it once, or there will be errors when selecting records. Attention: deployment may take long time, depending on the network speed. Attention: it will overwrite your app.yaml. DO NOT SUBMIT TWICE.")}}</p>
{{if command:}}
<h3>Command</h3>
<button onclick="$.get('{{=URL(r=request,f='kill')}}');">kill process</button>
{{=CODE(command)}}
<h3>GAE Output</h3>
<pre id="target"></pre>
{{else:}}
<h3>Deployment form</h3>
<div class="deploy_form form">
{{=form}}
</div>
{{pass}}
+18
View File
@@ -0,0 +1,18 @@
{{extend 'layout.html'}}
{{"""
You should not modify this file.
It is used as default when a view is not provided for your controllers
"""}}
{{=BEAUTIFY(response._vars)}}
<button onclick="document.location='{{=URL("admin","default","design",args=request.application)}}'">admin</button>
<button onclick="jQuery('#request').slideToggle()">request</button>
<div class="hidden" id="request"><h2>request</h2>{{=BEAUTIFY(request)}}</div>
<button onclick="jQuery('#session').slideToggle()">session</button>
<div class="hidden" id="session"><h2>session</h2>{{=BEAUTIFY(session)}}</div>
<button onclick="jQuery('#response').slideToggle()">response</button>
<div class="hidden" id="response"><h2>response</h2>{{=BEAUTIFY(response)}}</div>
<script>jQuery('.hidden').hide();</script>
+44
View File
@@ -0,0 +1,44 @@
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta http-equiv="P3P" content="CP=\"IDC DSP COR CURa ADMa OUR IND PHY ONL COM STA\"" />
<title>{{=response.title or URL()}}</title>
{{response.files.append(URL('static','css/styles.css'))}}
{{include 'web2py_ajax.html'}}
<script>jQuery.noConflict();</script>
</head>
<body class="{{=T('direction: ltr') == 'direction: rtl' and 'RTLbody' or ''}} {{block sectionclass}}home{{end}}">
<div id="header">
<h1 id="start">
<a href="{{=URL('default', 'index')}}" class="button"><span>web2py&trade; {{=T('administrative interface')}}</span></a>
</h1>
{{if response.menu is not None:}}
<ul id="menu">
{{for _name,_active,_link in response.menu:}}
<li>{{=A(SPAN(_name), _href=_link, _class=_active and 'button select' or 'button')}}</li>
{{pass}}
</ul>
{{pass}}
</div>
<div id="main">
<div id="main_inner">
<div class="flash">{{=response.flash or ''}}</div>
{{include}}
</div>
</div>
<div id="footer" class="fixed">
{{=T('Powered by')}} {{=A('web2py', _href='http://www.web2py.com')}}&trade; {{=T('created by')}} Massimo Di Pierro &copy;2007-2011 -
{{if hasattr(T,'get_possible_languages'):}}
<span>
{{=T('Admin language')}}
<select name="adminlanguage" onchange="var date = new Date();cookieDate=date.setTime(date.getTime()+(100*24*60*60*1000));document.cookie='adminLanguage='+this.options[this.selectedIndex].value+'; expires='+cookieDate+'; path=/';window.location.reload()">
{{for language in T.get_possible_languages():}}
<option {{=T.accepted_language==language and 'selected' or ''}} >{{=language}}</option>
{{pass}}
</select>
</span>
{{pass}}
</div>
</body>
</html>
@@ -0,0 +1,33 @@
{{extend 'layout.html'}}
{{import time}}
<h2>Mercurial Version Control System Interface<br />
for application "{{=request.args[0]}}"</h2>
<h3>Commit form</h3>
{{=form}}
{{if repo['.'].rev()>=0:}}
<h3>Last Revision</h3>
<table>
<tr><td>Revision:</td><td>{{=repo['.'].rev()}}</td></tr>
<tr><td>Node:</td><td>{{=repo['.']}}</td></tr>
<tr><td>Created by:</td><td>{{=repo['.'].user()}}</td></tr>
<tr><td>Created on:</td><td>{{=time.ctime(repo['.'].date()[0])}}</td></tr>
<tr><td>Description:</td><td>{{=repo['.'].description()}}</td></tr>
</table>
<h3>Past revisions</h3>
<div class="changes">
{{=changes}}
</div>
{{if files:}}
<h3>Committed files</h3>
<div class="files">
{{=files}}
</div>
{{pass}}
{{pass}}
@@ -0,0 +1,17 @@
{{extend 'layout.html'}}
<h2 class="section">Revision {{=rev}}</h2>
{{=form}}
<br/><br/>
<h3>Changelog</h3>
{{=desc}}
<br/><br/>
<h3>Files added</h3>
{{=TABLE(*[TR(f) for f in files])}}
+165
View File
@@ -0,0 +1,165 @@
{{extend 'layout.html'}}
{{block sectionclass}}shell{{end}}
<!--style type="text/css">
.prompt, #output {
width: 45em;
border: 1px solid #CCCCCC;
font-size: 10pt;
margin: 0.5em;
padding: 0.5em;
padding-right: 0em;
overflow: auto;
wrap: hard;
}
#output {
height:250px;overflow:auto;
}
#toolbar {
margin-left: 0.5em;
padding-left: 0.5em;
}
#caret {
width: 2.5em;
margin-right: 0px;
padding-right: 0px;
border-right: 0px;
}
#statement {
width: 43em;
margin-left: -1em;
padding-left: 0px;
border-left: 0px;
background-position: top right;
background-repeat: no-repeat;
}
.processing {
background-image: url("{{=URL('static','images/spinner.gif')}}");
}
#ajax-status {
font-weight: bold;
}
.message {
color: #8AD;
font-weight: bold;
font-style: italic;
}
.error {
color: #F44;
}
.username {
font-weight: bold;
}
</style-->
<div id="wrapper">
<textarea id="output" readonly="readonly">web2py Shell {{=request.env.web2py_version}}</textarea>
<form id="form" action="{{=URL(r=request,f='callback',args=app)}}" method="get">
<div id="shellwrapper">
<div id="caret">&gt;&gt;&gt;</div>
<div class="tooltip">
<textarea class="prompt" name="statement" id="statement"></textarea>
<span>Type some Python code in here and hit Return (Enter) to execute it.</span>
</div>
<div id="autoscroll" style="float:right;">autoscroll</div>
</div>
</form>
</div>
<div class="help">
<ul>
<li>Using the shell may lock the database to other users of this app.</li>
<li>Each db statement is automatically committed.</li>
<li>Creating new tables dynamically is not allowed.</li>
<li>Models are automatically imported in the shell.</li>
</ul>
</div>
<script type="text/javascript" src="{{=URL('static', 'js/autoscroll.js')}}"></script>
<script type="text/javascript">
var bShellScrolling=0
jQuery(document).ready(function(){
jQuery('#statement').focus();
jQuery('#statement').keyup(function(event){
var t=jQuery(this),
s=t.val(),
o=jQuery('#output'),
RETURN = 38;
if(s=='\n') t.val('');
if(s.length>1 && s.substr(s.length-1,1)=='\n' && s.substr(s.length-2,1)!=':' &&
(s.indexOf(':\n ')<0 || s.substr(s.length-2,1)=='\n')) {
t.val('');
jQuery.post("{{=URL(r=request,f='callback',args=app)}}",
{statement:s},function(data){o.html(o.html()+data).attr('scrollTop',o.attr('scrollHeight'));});
} else { };
if(event.keyCode==RETURN){
var i=s.length
if(i==0){
var s=o.find('table:last pre:first').text();
bShellScrolling=o.find('table').length;
}else if(bShellScrolling){
var i=bShellScrolling
if(i<1){
return
}else{
i--
var s=o.find('table:nth-child('+(i)+') pre:first').text();
bShellScrolling=i
}
}else if(s.indexOf('\n')<0){
var oo=o.find('tr:first-child pre:contains("'+s+'")')
if(oo.length==0){
return
}else if(oo.length==1){
s=oo.text();
}else{
sVar=oo.text();
o.html(o.html()+'<dd>'+s+' ?</dd><dt>'+sVar+'</dt>').attr('scrollTop',o.attr('scrollHeight'))
return
}
}else{
//multistring expr
return;
}
// if(s.slice(s.length-1)=='\n'){
s=s.slice(0,s.length-1)
// }
t.val(s);
}
if(bShellScrolling && event.keyCode==40){
var i=bShellScrolling
i++
var s=o.find('table:nth-child('+i+') tr:first-child pre').text();
if(s){
s=s.slice(0,s.length-1)
t.val(s);
bShellScrolling=i
}else{
bShellScrolling=0
t.val('')
}
};
if(bShellScrolling && (event.keyCode==37 || event.keyCode==39)){
bShellScrolling=0;
};
if(event.keyCode==27){
bShellScrolling=0;
t.val('');
};
});
});
</script>
@@ -0,0 +1,17 @@
<html>
<head>
{{response.files.append(URL('static','js/jquery.js'))}}
{{include 'web2py_ajax.html'}}
</head>
<body style="border:0; margin:0; padding:0;">
<div style="background: #aaaaaa; font-family:hevetica;font-size:9px">
URL: {{=URL(app,'default','index')}}
<button onclick="ajax('{{=URL('admin','toolbar','profiler')}}',[],'profiler_inner');jQuery('#profiler').slideDown()">profiler</button>
<div id="profiler" class="hidden">
<button onclick="jQuery('#profiler').slideUp()">close</button>
<pre id="profiler_inner">profiler info</pre>
</div>
</div>
<iframe style="border:0;" width="100%" height="100%" src="{{=URL(app,'default','index')}}"></iframe>
</body>
</html>
+14
View File
@@ -0,0 +1,14 @@
<script type="text/javascript"><!--
// These variables are used by the web2py_ajax_init function in web2py_ajax.js (which is loaded below).
var w2p_ajax_confirm_message = "{{=T('Are you sure you want to delete this object?')}}";
var w2p_ajax_date_format = "{{=T('%Y-%m-%d')}}";
var w2p_ajax_datetime_format = "{{=T('%Y-%m-%d %H:%M:%S')}}";
//--></script>
{{
response.files.insert(0,URL('static','js/jquery.js'))
response.files.insert(1,URL('static','css/anytime.css'))
response.files.insert(2,URL('static','js/anytime.js'))
response.files.insert(2,URL('static','js/web2py.js'))
response.include_meta()
response.include_files()
}}
@@ -0,0 +1,13 @@
{{extend 'layout.html'}}
{{block sectionclass}}generated{{end}}
<a class="button" href="{{=URL(app,'default','index')}}">Open new app in new window</a>
<a class="button" href="{{=URL('step1')}}">Back to wizard</a>
<a class="button" href="{{=URL('default','design',args=app)}}">Admin design page</a>
{{if have_mercurial:}}
<a class="button" href="{{=URL('mercurial','commit',args=app)}}">Admin versioning page</a>
{{pass}}
<a class="button" href="{{=URL(app,'appadmin','index')}}">Database administration</a>
<br/><br/>
<iframe style="width: 100%; height: 100%; min-height:600px" src="{{=URL(app,'default','index')}}"></iframe>
+140
View File
@@ -0,0 +1,140 @@
{{extend 'layout.html'}}
{{block sectionclass}}step{{end}}
<h2>{{=T('New Application Wizard')}}</h2>
<div id="wizard_nav" class="f20 controls">
{{if request.function=='index':}}
<h3>{{=T('Start a new app')}}</h3>
{{else:}}
<div class="box">
<h3>{{=T('Basics')}}</h3>
<p>{{=button(URL('index'), T('restart'))}}</p>
<p><strong>App Name:</strong> {{=session.app['name']}}</p>
</div>
<div class="box">
<h3>Current settings</h3>
<p>{{=button(URL('step1'), T('Edit'))}}</p>
<ul id="current_settings">
{{for key,value in session.app['params']:}}
<li><b>{{=key}}:</b> {{=value}}</li>
{{pass}}
</ul>
</div>
<div class="box">
<h3>Tables</h3>
<p>{{=button(URL('step2'), T('edit all'))}}</p>
<ul>
{{for i,table in enumerate(session.app['tables']):}}
<li>{{=button(URL('step3',args=i), T('Edit'))}} <strong>{{=table}}</strong></li>
{{pass}}
</ul>
</div>
<div class="box">
<h3>Pages</h3>
<p>{{=button(URL('step4'), T('edit all'))}}</p>
<ul>
{{for i,page in enumerate(session.app['pages']):}}
<li>{{=button(URL('step5',args=i), T('Edit'))}} <strong>{{=page}}</strong></li>
{{pass}}
</ul>
</div>
<div class="box">
<h3>{{=T('Generate')}}</h3>
<p>{{=button(URL('step6'), T('go!'))}}</p>
</div>
{{pass}}
</div>
<div id="wizard_form" class="fl20 controls">
<!-- FORM -->
{{if 'step' in request.function:}}
<h3>{{=T('Step')}} {{=step}}</h3>
{{if request.function!='step1':}}
{{=button(URL('step' + str(int(request.function[-1])-1)), T('back'))}}
{{pass}}
{{else:}}
<h3>{{=T('Begin')}}</h3>
{{pass}}
{{if request.function in ('step1','step2','step3','step4','step5'):}}
{{=button(URL('step6'), T('skip to generate'))}}
{{pass}}
<br /><br />
{{if request.function in ('step1','step6'):}}
<img src="{{=LAYOUTS_APP}}/static/plugin_layouts/layouts/{{=dict(session.app['params'])['layout_theme']}}/preview.png" alt="" align="right" id="preview"/>
{{pass}}
<div class="form">
{{=form}}
</div>
<script>
jQuery(document).ready(function(){
var t=jQuery('#no_table_layout_theme');
t.change(function(){
jQuery('#preview').attr('src','{{=LAYOUTS_APP}}/static/plugin_layouts/layouts/'+t.val()+'/preview.png');
});
});
</script>
<!-- INSTRUCTIONS -->
<div class="box">
<h4>Instructions</h4>
<div class="help">
{{if request.function=='index':}}
<ul>
<li>Insert the name of a new app.</li>
<li>If the app exists and was created with the wizard, you will be able to edit it, but any manual editing to the app <b>will be lost</b>.</li>
</ul>
{{elif request.function=='step1':}}
<ul>
<li>This Wizard will help you build a new web2py app.</li>
<li>You can create an app with a name that already exists.</li>
<li>If you do not have an email server set email server to "logging".</li>
<li>If you want to use Janrain Engage for login: 1) Sign up for a <a href="http://www.janrain.com/products/engage">Janrain Engage</a> account; 2) Register you hostname, domain, and obtain an api key; 3) Set Login Config above to "domain:api_key".</li>
<li>ATTENTION: you can use the wizard to download plugins BUT we cannot guarantee the stability or backward compatibility of plugins. Moreover plugins may conflict with each other. Anyway, we do recommend installing plugin "wiki" with adds CMS like capabilities to your app.</li>
</ul>
{{elif request.function=='step2':}}
<ul>
<li>List the names of table that you need.</li>
<li>If you do not need authentication remove the table "auth_user".</li>
<li>Press enter to create a new input row.</li>
<li>Empty rows are ignored.</li>
<li>Other tables for role based access control will be created automatically, and do not need to be listed.</li>
<li>You will be able to add fields later.</li>
</ul>
{{elif request.function=='step3':}}
<ul>
<li>List the fields for this table (do not include an id field, it is automatic), for example "name unique" or "birthday date" or "image upload" or "comments multiple" or "description wiki required"</li>
<li>The first keyword(s) for each entry will be used to generate a name for the table field and its label. You can use spaces an other unicode characters.</li>
<li>Keywords "string" (default), "text", "integer", "boolean", "float", "double", "file", "date", "time", "datetime", "file", "upload" will be used to determine the field type and they will not be made part of the field name.</ li>
<li>For a reference field use a field name, followed by the name of the referenced table.</li>
<li>Other special keywords are "required", "notnull" or "notempty", "unique". They map into equivalent validators but (at this time) should only be used with string and text types.</li>
<li>The keywords "html" and "wiki" force a text type and set a representation for the field value as sanitized HTML and MARKMIN resepectively.</li>
<li>string, integer and reference fields can be "multiple", i.e. multiple values will be allowed</li>
<li>For the "auth_user" table do not add attributes to the default fields (username, first_name, last_name, password and email). They are handled automatically.</li>
<li>Some fields will be added automatically upon creation and handled automatically: "created_by", "created_on", "modified_by", "modified_on", "active" (only active fields can be selected).</li>
<li>For every table "table" another table "table_archive" is created and it contains the previous versions of each record. This is only accessible via appadmin or programmatically.</li>
</ul>
{{elif request.function=='step4':}}
<ul>
<li>List the names of the pages you want to create.</li>
<li>Some pages are listed automatically because they expose Create/Read/Update/Delete for each tables you have created.</li>
<li>All pages, except "error" and those with name starting in underscore willbe listed in the menu. You will be able to edit the menu later.</li>
<li>You should have page "index", the starting point of your app, and page "error", where web2py will redirect to in case of error.</li>
</ul>
{{elif request.function=='step5':}}
<ul>
<li>Use the markmin syntax to add text to your pages.</li>
</ul>
{{elif request.function=='step6':}}
<ul>
<li>Almost done. Click on the button above to create your new app.</li>
<li>Once done you will be able to edit it as any normal web2py app.</li>
</ul>
{{pass}}
</div>
</div>
</div>