yobin:我试过了,效果很好。我准备将此加入我的GAE代码中,但为了安全性,我增加了只有GAE项目作者或者凭取设定密码才能访问的小关卡。


原始出处:http://www.antlite.com/blog/2008/07/manager-your-google-app-engine-app/
以下是原文:

目前我们还不能从Google app engine直接管理项目代码文件,但是已经有人开发了相关的功能。早前,manatlanzipme能够将Google app engine项目打包成zip文件下载到本地。最近,chendaoan Chen BaipingGAE App files browser实现了更多管理的功能,看起来有点象Google app engine的管理页面了。

GAE App files browser目前能够做到:

1. 在线浏览GAE项目文件

  • 查看app目录结构和文件
  • 查看文件内容
  • 下载文件
  • 压缩目录到zip文件并下载

2. 在线运行和调试app

  • 在线python解析
  • 检查支持GAE的函数和模块
  • 快捷的调试GAE app

您可以访问http://enter.appspot.com/查看演示,从http://code.google.com/p/appfilesbrowser/下载代码。

文件编辑、删除和更名受制于Google app engine对文件系统访问的限制还无法实现,不过如果能够加上代码语法高亮,那一定很cool。我用google code prettify做了尝试,效果还不错。

1. 修改listfiles.py:

from django.utils.html import escape

class MainFile(webapp.RequestHandler):
def get(self):
unicode_fn= self.request.get(‘fn’)
fn = unicode_fn.encode(‘ascii’, ‘ignore’)
filename=fn

show_code = False

iLastSlash = fn.rfind(’/’)
if iLastSlash>=0:
filename=fn[iLastSlash+1:]
fullpath=ROOT_DIR+’/’+fn
# self.response.out.write(‘get file=’ + filename)
# return
if fullpath.find(’./’)==0:
fullpath=fullpath[2:]
if fullpath.find(’./’)==0:
fullpath=fullpath[2:]
logging.info(’ fn=’+fullpath)

if os.path.isfile( fullpath ):
# logginginfol(‘222222 fn=’+fullpath)
if self.request.get(‘op’)==‘view’:
logging.info(‘view=’+fullpath)
if re.match(’..gif$’, fn, re.IGNORECASE) :
self.response.headers[ ‘Content-Type’] = ‘image/gif’
elif re.match(’.
.jpe?g$’, fn, re.IGNORECASE) :
self.response.headers[ ‘Content-Type’] = ‘image/jpeg’
# logging.info(self.response.headers[ ‘Content-Type’])
elif re.match(’..bmp$’, fn, re.IGNORECASE) :
self.response.headers[ ‘Content-Type’] = ‘image/x-ms-bmp’
elif re.match(’.
.png$’, fn, re.IGNORECASE) :
self.response.headers[ ‘Content-Type’] = ‘image/x-png’
elif re.match(’.*.tiff?$’, fn, re.IGNORECASE) :
self.response.headers[ ‘Content-Type’] = ‘image/tiff’
else:
show_code = True
else:
logging.info(‘download=’+fullpath)
self.response.headers[ ‘Content-Type’] = ‘application/octet-stream’
self.response.headers[ "Content-Disposition"]= "attachment;filename="+filename;
#a file
f = open( fullpath, ‘rb’)
while True:
buf = f.read(1<<20) #1M, file length exceed 1M will be truncat by GAE.
if buf:
if show_code:
template_values = {‘buf’: buf,}
self.response.out.write(template.render(‘showcode.html’, template_values))
else:
self.response.out.write(buf)
else:
break

2. 新建template文件:showcode.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<link href="/static/prettify.css" type="text/css" rel="stylesheet" />
<script src="/static/prettify.js" type="text/javascript"></script>
<style>
pre { font-family: Verdana,Arial,Helvetica; font-size: 11px;}
</style>
</head>
<body onload="prettyPrint()">
<pre class="prettyprint" >
{{ buf|escape }}
</pre>
</body>
</html>

当然,您也可以不用template,直接在listfiles.py文件response.out.write() html代码。

3. 下载google code prettify保存在static目录。

最后的效果:

py

screenshoot-py

css

screenshoot-css

js

screenshoot-js

yaml

screenshoot-yaml