mobile admin, thanks Angelo

This commit is contained in:
Massimo Di Pierro
2011-12-09 20:55:57 -06:00
parent ac82f1e4e7
commit f0f8c8ce22
21 changed files with 313 additions and 319 deletions
+1 -1
View File
@@ -1 +1 @@
Version 1.99.3 (2011-12-09 20:46:02) stable
Version 1.99.3 (2011-12-09 20:55:52) stable
+2 -2
View File
@@ -1,9 +1,9 @@
# coding: utf8
EXPERIMENTAL_STUFF = False
EXPERIMENTAL_STUFF = True
if EXPERIMENTAL_STUFF:
is_mobile=request.user_agent().is_mobile
is_mobile = True #request.user_agent().is_mobile
if is_mobile:
response.view = response.view.replace(
'default/','default.mobile/')
+15 -2
View File
@@ -2,8 +2,17 @@
import os
def A_button(*a,**b):
b['_data-role'] = 'button'
b['_data-inline'] = 'true'
return A(*a,**b)
def button(href, label):
return A(SPAN(label),_class='button',_href=href)
if request.user_agent().is_mobile:
ret = A_button(SPAN(label), _href=href)
else:
ret = A(SPAN(label),_class='button',_href=href)
return ret
def button_enable(href, app):
if os.path.exists(os.path.join(apath(app,r=request),'DISABLED')):
@@ -14,7 +23,11 @@ def button_enable(href, app):
return A(label,_class='button',_id=id,callback=href,target=id)
def sp_button(href, label):
return A(SPAN(label),_class='button special',_href=href)
if request.user_agent().is_mobile:
ret = A_button(SPAN(label), _href=href)
else:
ret = A(SPAN(label),_class='button special',_href=href)
return ret
def helpicon():
return IMG(_src=URL('static', 'images/help.png'), _alt='help')
@@ -4,10 +4,10 @@
<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>
<p>{{=button(URL('edit/%s/ABOUT' % (app)), T('Edit'))}}</p>
<div>{{=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>
<p>{{=button(URL('edit/%s/LICENSE' % (app)), T('Edit'))}}</p>
<div>{{=license}}</div>
</ul>
@@ -1,10 +1,10 @@
{{extend 'layout.html'}}
{{extend 'default.mobile/layout.html'}}
{{block sectionclass}}change_password{{end}}
<h2>Change Admin Password</h2>
<div class="pwform">
<div>
{{=form}}
</div>
@@ -1,8 +1,8 @@
{{extend 'layout.html'}}
{{extend 'default.mobile/layout.html'}}
{{block sectionclass}}delete{{end}}
<div class="center">
<div>
<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>
@@ -1,8 +1,8 @@
{{extend 'layout.html'}}
{{extend 'default.mobile/layout.html'}}
{{block sectionclass}}delete_plugin{{end}}
<div class="center">
<div>
<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>
@@ -1,40 +1,88 @@
{{extend 'default.mobile/layout.html'}}
{{
def A_info(*a,**b):
b['_data-role'] = 'button'
b['_data-icon'] = 'info'
b['_data-theme'] = 'b'
return A(*a,**b)
def A_gear(*a,**b):
b['_data-role'] = 'button'
b['_data-icon'] = 'gear'
return A(*a,**b)
def A_delete(*a,**b):
b['_data-role'] = 'button'
b['_data-icon'] = 'delete'
return A(*a,**b)
def A_check(*a,**b):
b['_data-role'] = 'button'
b['_data-icon'] = 'check'
return A(*a,**b)
def all(items):
return reduce(lambda a,b:a and b,items,True)
def peekfile(path,file):
return A_info(file.replace('\\\\','/'),_href=URL('peek', args=(app, path, file)))
def editfile(path,file):
return A_gear(SPAN(T('Edit')),_href=URL('edit', args=(app, path, file)))
def testfile(path,file):
return A_check(SPAN(T('Run tests')), _href=URL('test', args=(app, file)))
def editlanguagefile(path,file):
return A_gear(SPAN(T('Edit')),_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_delete(SPAN(T('Delete')), _href=URL('delete',args=arglist,vars=dict(sender=request.function+'/'+app)))
}}
{{block sectionclass}}design {{=app}}{{end}}
<!-- MODELS -->
<div data-role="collapsible-set" data-content-theme="c">
<!-- MODELS -->
<div data-role="collapsible" data-content-theme="c">
<h3 id="models">
{{=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">
<div id="models_inner">
{{if not models:}}<p><strong>{{=T("There are no models")}}</strong></p>{{else:}}
<div class="controls comptools">
<div data-role="controlgroup" data-type="horizontal">
{{=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">
<span data-role="controlgroup">
{{=peekfile('models',m)}}
{{=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>
</br>
{{pass}}
</ul>
<div class="controls formfield">{{=file_create_form('%s/models/' % app)}}</div>
<div data-role="fieldcontain">{{=file_create_form('%s/models/' % app)}}</div>
</div>
</div>
<!-- FIND CONTROLLER FUNCTIONS -->
@@ -44,218 +92,165 @@ for c in controllers: controller_functions+=[c[:-3]+'/%s.html'%x for x in functi
}}
<!-- CONTROLLERS -->
<h3 id="controllers" onclick="collapse('controllers_inner');" class="component">
<div data-role="collapsible" data-content-theme="c">
<h3 id="controllers">
{{=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">
<div id="controllers_inner">
{{if not controllers:}}<p><strong>{{=T("There are no controllers")}}</strong></p>{{else:}}
<div class="controls comptools">
<div data-role="controlgroup" data-type="horizontal">
{{=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">
<span data-role="controlgroup">
{{=peekfile('controllers',c)}}
{{=editfile('controllers',c)}}
{{=deletefile([app, 'controllers', c])}}
{{=testfile('controllers',c)}}
</br>
</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 data-role="fieldcontain">{{=file_create_form('%s/controllers/' % app)}}</div>
</div>
</div>
<!-- VIEWS -->
<h3 id="views" onclick="collapse('views_inner');" class="component">
<div data-role="collapsible" data-content-theme="c">
<h3 id="views">
{{=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">
<div id="views_inner">
<div data-role="controlgroup" data-type="horizontal">
{{=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">
<span data-role="controlgroup">
{{=peekfile('views',c)}}
{{=editfile('views',c)}}
{{=deletefile([app, 'views', c])}}
</br>
</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 data-role="fieldcontain">{{=file_create_form('%s/views/' % app)}}</div>
</div>
</div>
<!-- LANGUAGES -->
<h3 id="languages" onclick="collapse('languages_inner');" class="component">
<div data-role="collapsible" data-content-theme="c">
<h3 id="languages">
{{=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">
<div id="languages_inner">
<div data-role="controlgroup" data-type="horizontal">
{{=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>
{{if not languages:}}<p><strong>{{=T("There are no translators")}}</strong></p>{{pass}}
{{for file in languages:}}
<li id="languages__{{=file.replace('.','__')}}">
<span class="filetools controls">
<span data-role="controlgroup">
{{=peekfile('languages',file)}}
{{=editlanguagefile('languages',file)}}
{{=deletefile([app, 'languages', file])}}
</br>
</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 data-role="fieldcontain">{{=file_create_form('%s/languages/' % app)}}</div>
</div>
</div>
<!-- STATIC -->
<h3 id="static" onclick="collapse('static_inner');" class="component">
<div data-role="collapsible" data-content-theme="c">
<h3 id="static">
{{=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>
</h3>
<div id="static_inner">
{{if not statics:}}<p><strong>{{=T("There are no static files")}}</strong></p>{{pass}}
<ul>
<ul data-role="listview" data-inset="true">
{{
path=[]
from collections import OrderedDict
tree=OrderedDict()
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
items=file.partition('/')
if not items[0] in tree:
tree[items[0]] = []
pass
tree[items[0]].append(items[2])
pass
}}
{{for k, v in tree.iteritems():}}
{{if k:}}
<li><a>{{=k}}</a>
<ul data-theme='c'>
</br>
{{if len(v) == 1 and v[0] =='':}}
<span data-role="controlgroup">
{{=peekfile('static', k)}}
{{=editfile('static', k)}}
{{=deletefile([app, 'static', k])}}
</br>
</span>
</ul>
{{continue}}
{{for f in v:}}
<span data-role="controlgroup">
{{=peekfile('static/'+k, f)}}
{{=editfile('static/'+k, f)}}
{{=deletefile([app, 'static/'+k, f])}}
</br>
</span>
{{pass}}
</ul>
</li>
{{pass}}
</ul>
<div class="controls formfield">{{=file_create_form('%s/static/' % app)}}
{{pass}}
</ul>
<div data-role="fieldcontain">{{=file_create_form('%s/static/' % app)}}
{{=file_upload_form('%s/static/' % app)}}</div>
</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>
<div data-role="collapsible" data-content-theme="c">
<h3 id="modules">
{{=T("Modules")}}</h3>
<div id="modules_inner">
{{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">
<span data-role="controlgroup">
{{=peekfile('modules',m)}}
{{=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)}}
<div data-role="fieldcontain">{{=file_create_form('%s/modules/' % app)}}
{{=file_upload_form('%s/modules/' % app)}}</div>
</div>
</div>
<!-- PLUGINS -->
<h3 id="plugins" onclick="collapse('plugins_inner');" class="component">
<div data-role="collapsible" data-content-theme="c">
<h3 id="plugins" >
{{=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">
<div id="plugins_inner">
<div data-role="controlgroup" data-type="horizontal">
{{=button(PLUGINS_APP, T('download plugins'))}}
</div>
<div class="controls">
</div>
{{if plugins:}}
<ul>
<div data-role="controlgroup">
{{for plugin in plugins:}}
<li>
{{=A('plugin_%s' % plugin, _class='file', _href=URL('plugin', args=[app, plugin]))}}
</li>
{{=button(URL('plugin', args=[app, plugin]), 'plugin_%s' % plugin)}}
{{pass}}
</ul>
</div>
{{else:}}
<p><strong>{{=T('There are no plugins')}}</strong></p>
{{pass}}
<div class="controls formfield">{{=upload_plugin_form(app)}}</div>
<div data-role="fieldcontain">{{=upload_plugin_form(app)}}</div>
</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>
</div>
@@ -1,13 +1,13 @@
{{extend 'layout.html'}}
{{extend 'default.mobile/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 />
<p><strong>{{=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">
<div>
{{=FORM(INPUT(_type='submit',_name='nodowngrade',_value=T('Cancel')), _class='inline')}}
{{=FORM(INPUT(_type='submit',_name='downgrade',_value=T('Downgrade')), _class='inline')}}
</div>
@@ -22,7 +22,7 @@ jQuery(document).ready(function(){
{{block sectionclass}}edit {{filename}}{{end}}
{{if functions:}}
<p class="formfield">
<p>
<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>
@@ -35,7 +35,7 @@ jQuery(document).ready(function(){
<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">
<a value="save" name="save" onclick="return doClickSave();">
{{=IMG(_src=URL('static', 'images/save_icon.png'), _alt=T('Save'))}}
</a>
{{=T('Saved file hash:')}}
@@ -46,8 +46,8 @@ jQuery(document).ready(function(){
{{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>
<button class="editbutton" type="submit" name="revert">{{=T('revert')}}</button>
<button onclick="window.location.reload(); return false">{{=T('restore')}}</button>
<button type="submit" name="revert">{{=T('revert')}}</button>
<br/>
</form>
</div>
@@ -1,4 +1,4 @@
{{extend 'layout.html'}}
{{extend 'default.mobile/layout.html'}}
<script>
function delkey(id) {
jQuery('#'+id).hide();
@@ -12,7 +12,7 @@ function delkey(id) {
<h2>{{=T('Editing Language file')}} "{{=filename}}"</h2>
<div class="languageform">
<div>
{{=form}}
</div>
@@ -1,4 +1,4 @@
{{extend 'layout.html'}}
{{extend 'default.mobile/layout.html'}}
{{import os, stat, time}}
{{block sectionclass}}errors{{end}}
@@ -39,26 +39,28 @@ tr.error_ticket:hover {
<h2>{{=T('Error logs for "%(app)s"',dict(app=app))}}</h2>
<div class="errorform">
<div>
<form name="myform" method="post">
<div data-role="controlgroup" data-type="horizontal">
<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>
</div>
{{ if 'new' in method: }}
{{base_url = 'db' in method and 'ticketdb' or 'ticket' }}
<h3>{{=T('Click row to expand traceback')}}</h3>
<p class="controls">
<p>
{{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>
<a data-role="button" data-inline="true" href="{{=URL(args=[app, 'new'])}}"><span>switch to : filesystem</span></a>
<a data-role="button" data-inline="true" 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>
<a data-role="button" data-inline="true" data-inline="true" href="{{=URL(args=[app, 'dbnew'])}}"><span>switch to : db</span></a>
<a data-role="button" data-inline="true" href="{{=URL(args=[app, 'old'])}}"><span>lists by ticket</span></a>
{{pass}}
</p>
<table id="trck_errors" class="sortable">
@@ -94,15 +96,15 @@ tr.error_ticket:hover {
</table>
{{ else: }}
<h3>{{=T('Click row to view a ticket')}}</h3>
<p class="controls">
<p>
{{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>
<a data-role="button" data-inline="true" href="{{=URL(args=[app, 'old'])}}"><span>switch to : filesystem</span></a>
<a data-role="button" data-inline="true" 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>
<a data-role="button" data-inline="true" href="{{=URL(args=[app, 'dbold'])}}"><span>switch to : db</span></a>
<a data-role="button" data-inline="true" href="{{=URL(args=[app, 'new'])}}"><span>lists by exception</span></a>
{{pass}}
</p>
<table class="sortable">
@@ -2,7 +2,7 @@
<h2>web2py&trade; {{=T('Web Framework')}}</h2>
<h3>{{=T('Login to the Administrative Interface')}}</h3>
<div class="form">
<div>
<form action="{{=URL(r=request)}}" method="post">
<div><input type="hidden" name="send" value="{{=send}}"/></div>
<table>
@@ -1,10 +1,10 @@
{{extend 'layout.html'}}
{{extend 'default.mobile/layout.html'}}
{{block sectionclass}}peek{{end}}
<h2>{{=T("Peeking at file")}} "{{=filename}}"</h2>
<p class="controls">
<p>
{{=button(URL('design',args=request.args[0]), T('back'))}}
{{=button(URL('edit',args=request.args), T('Edit'))}}
</p>
@@ -1,16 +1,37 @@
{{extend 'layout.html'}}
{{extend 'default.mobile/layout.html'}}
{{
import os
def A_info(*a,**b):
b['_data-role'] = 'button'
b['_data-icon'] = 'info'
b['_data-theme'] = 'b'
return A(*a,**b)
def A_gear(*a,**b):
b['_data-role'] = 'button'
b['_data-icon'] = 'gear'
return A(*a,**b)
def A_delete(*a,**b):
b['_data-role'] = 'button'
b['_data-icon'] = 'delete'
return A(*a,**b)
def A_check(*a,**b):
b['_data-role'] = 'button'
b['_data-icon'] = 'check'
return A(*a,**b)
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)))
return A_info(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)))
return A_gear(SPAN(T('Edit')),_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)))
return A_check(SPAN(T('Run tests')), _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)))
return A_gear(SPAN(T('Edit')),_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:")," ",
@@ -32,7 +53,7 @@ def upload_plugin_form(app):
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)))
return A_delete(SPAN(T('Delete')), _href=URL('delete',args=arglist,vars=dict(sender=request.function+'/'+app)))
}}
{{block sectionclass}}plugin{{end}}
@@ -40,49 +61,33 @@ def deletefile(arglist):
<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">
<div>
<div data-role="controlgroup" data-type="horizontal">
{{=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>
</div>
<div data-role="collapsible-set" data-content-theme="c">
<!-- MODELS -->
<h3 id="models" onclick="collapse('models_inner');" class="component">
<div data-role="collapsible" data-content-theme="c">
<h3 id="models">
{{=T("Models")}}
</h3>
<div id="models_inner" class="component_contents">
<div id="models_inner" >
{{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">
<span data-role="controlgroup" data-type="horizontal">
{{=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>
</div>
<!-- FIND CONTROLLER FUNCTIONS -->
@@ -92,130 +97,110 @@ for c in controllers: controller_functions+=[c[:-3]+'/%s.html'%x for x in functi
}}
<!-- CONTROLLERS -->
<h3 id="controllers" onclick="collapse('controllers_inner');" class="component">
<div data-role="collapsible" data-content-theme="c">
<h3 id="controllers">
{{=T("Controllers")}}
</h3>
<div id="controllers_inner" class="component_contents">
<div id="controllers_inner">
{{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">
<span data-role="controlgroup" data-type="horizontal">
{{=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>
</div>
<!-- VIEWS -->
<h3 id="views" onclick="collapse('views_inner');" class="component">
<div data-role="collapsible" data-content-theme="c">
<h3 class="component">
{{=T("Views")}}
</h3>
<div id="views_inner" class="component_contents">
<div id="views_inner">
{{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">
<span data-role="controlgroup">
{{=peekfile('views',c)}}
{{=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>
</div>
<!-- STATIC -->
<h3 id="static" onclick="collapse('static_inner');" class="component">
<div data-role="collapsible" data-content-theme="c">
<h3 id="static">
{{=T("Static files")}}
</h3>
<div id="static_inner" class="component_contents">
<div id="static_inner">
{{if not statics:}}<p><strong>{{=T("There are no static files")}}</strong></p>{{pass}}
<ul>
<ul data-role="listview" data-inset="true">
{{
path=[]
from collections import OrderedDict
tree=OrderedDict()
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
items=file.partition('/')
if not items[0] in tree:
tree[items[0]] = []
pass
tree[items[0]].append(items[2])
pass
}}
{{for k, v in tree.iteritems():}}
{{if k:}}
<li><a>{{=k}}</a>
<ul data-theme='c'>
</br>
{{if len(v) == 1 and v[0] =='':}}
<span data-role="controlgroup">
{{=peekfile('static', k)}}
{{=editfile('static', k)}}
{{=deletefile([app, 'static', k])}}
</br>
</span>
</ul>
{{continue}}
{{for f in v:}}
<span data-role="controlgroup">
{{=peekfile('static/'+k, f)}}
{{=editfile('static/'+k, f)}}
{{=deletefile([app, 'static/'+k, f])}}
</br>
</span>
{{pass}}
</ul>
</li>
{{pass}}
</ul>
{{pass}}
</ul>
</div>
</div>
<!-- MODULES -->
<div data-role="collapsible" data-content-theme="c">
<h3 id="modules" onclick="collapse('modules_inner');" class="component">
{{=T("Modules")}}
</h3>
<div id="modules_inner" class="component_contents">
<div id="modules_inner">
{{if not modules:}}
<p><strong>{{=T("There are no modules")}}</strong></p>
{{pass}}
<div class="controls comptools">
</div>
<ul>
{{for m in modules:}}
<li>
<span data-role="controlgroup">
{{=peekfile('modules',m)}}
{{=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>
</span>
{{pass}}
</ul>
</div>
</div>
@@ -1,4 +1,4 @@
{{extend 'layout.html'}}
{{extend 'default.mobile/layout.html'}}
{{block sectionclass}}resolve{{end}}
@@ -1,4 +1,4 @@
{{extend 'layout.html'}}
{{extend 'default.mobile/layout.html'}}
{{block sectionclass}}test{{end}}
@@ -1,4 +1,4 @@
{{extend 'layout.html'}}
{{extend 'default.mobile/layout.html'}}
{{block sectionclass}}ticket{{end}}
@@ -7,7 +7,7 @@
<p>{{=ticket}}</p>
{{if output:}}<h4>{{=output}}</h4>{{pass}}
<h3>{{=T('Version')}}</h3>
<table class="versions">
<table>
<tbody>
<tr>
<th>web2py&trade;</th>
@@ -20,7 +20,7 @@
</tbody>
</table>
<h3>{{=T('Traceback')}}</h3>
<div class="inspect">
<div>
{{=traceback}}
</div>
@@ -30,22 +30,21 @@
<!-- ERROR SNAPSHOT -->
<h3>
{{=T('Error snapshot')}}
<span class="tooltip">{{=helpicon()}} <span>{{=T('Detailed traceback description')}}</span></span>
{{=T('Error snapshot')}}<span>{{=T('Detailed traceback description')}}</span>
</h3>
<!-- SNAPSHOT LIST -->
<div id="snapshot">
<!-- Exception details -->
<p class="exception_object inspect">
<p>
<code>{{=snapshot['etype']}}({{=snapshot['evalue']}})</code>
</p>
<p class="controls">
<a class="button" onclick="collapse('exception_inner');"><span>{{=T('inspect attributes')}}</span></a>
<p>
<a data-role="button" onclick="collapse('exception_inner');"><span>{{=T('inspect attributes')}}</span></a>
</p>
<div id="exception_inner" class="hide">
<div class="inspect">
<div id="exception_inner">
<div>
<h5>{{=T("Exception instance attributes")}}</h5>
<table>
<tbody>
@@ -68,7 +67,7 @@
{{for i, frame in enumerate(snapshot['frames']):}}
<li>
{{is_hidden = (i != len(snapshot['frames'])-1 and 'hide' or 'inspect')}}
<div class="framefile inspect controls">
<div>
<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>
@@ -1,4 +1,4 @@
{{extend 'layout.html'}}
{{extend 'default.mobile/layout.html'}}
<center>
<h2>{{=T('Are you sure you want to uninstall application "%s"?', app)}}</h2>
@@ -1,13 +1,13 @@
{{extend 'layout.html'}}
{{extend 'default.mobile/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 />
<p><strong>{{=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">
<div>
{{=FORM(INPUT(_type='submit',_name='noupgrade',_value=T('Cancel')), _class='inline')}}
{{=FORM(INPUT(_type='submit',_name='upgrade',_value=T('Upgrade')), _class='inline')}}
</div>
@@ -1,4 +1,4 @@
{{extend 'layout.html'}}
{{extend 'default.mobile/layout.html'}}
<h2>{{=T( request.args(0).replace('_',' ').capitalize() )}}</h2>
<div id="web2py_user_form">
{{=form}}