catswhocode.com 的 jbj 写道:我很喜欢Python,Python具有强大的扩展能力,我列出了50个很棒的Python模块,包含几乎所有的需要:比如Databases,GUIs,Images, Sound, OS interaction, Web,以及其他。推荐收藏。
还有其他好的模块需要加入这个列表吗?欢迎留言。
--
郎啊郎别太忙 | langalang.blogspot.com
catswhocode.com 的 jbj 写道:我很喜欢Python,Python具有强大的扩展能力,我列出了50个很棒的Python模块,包含几乎所有的需要:比如Databases,GUIs,Images, Sound, OS interaction, Web,以及其他。推荐收藏。
还有其他好的模块需要加入这个列表吗?欢迎留言。
CPU Used | |
---|---|
Data Sent | |
Data Received | |
Emails Sent | |
Megabytes Stored | |
Data Sent (HTTPS) | |
Data Received (HTTPS) | |
译文原始出处不可考。保留译者信息。
原文网址:
http://code.google.com/appengine/docs/gettingstarted/
翻译者:
otherrrr@gmail.com
(注:转载请告知我一声,谢谢!)
(注:在我翻译的同时,版本从1.0.0升到了1.0.1,
我还没有发现文字有什么变化,但是有可能有些许不同)
入门指南
本教程描述了如何使用Google App Engine开发和部署一个简单的项目。
作为案例项目的"用户留言簿"演示如何使用各种App Engine服务,
这些服务包括数据存储和Google用户服务。
本教程包括下列部分:
・介绍
・开发环境
・Hello, World!(译注:这个不用翻译吧)
・使用webapp框架
・使用用户服务
・使用webapp处理表单
・使用数据存储
・使用模板
・使用静态文件
・上传你的程序
(译注:小节名会用"#"来标注,小小节名会用"##"来标注)
# 介绍
欢迎使用Google App Engine!创建一个App Engine程序非常容易,
而且只需要花费很少的时间。它是免费的,只需要上传你的程序,
马上就能和使用者来分享,不需要任何费用和许可。
在本教程中,会创建一个简单的用户留言簿程序,可以让用户发表
信息到一个公共的信息版。用户可以匿名发表,也可以使用他们的
Google帐户。
用户留言簿程序会演示如何使用App Engine数据仓库,如何将App
Engine程序和Google帐户结合起来,以及演示如何使用一个简单的
Python Web框架。这个Web框架已经包含在App Engine中,即:webapp。
这个程序也会演示如何使用Django模板引擎。
(译注:原文在每个小节之后会有一个"Next",有些承上启下的文字,未译)
# 开发环境
使用Google App Engine开发和上传程序需要用到App Engine软件开发包(SDK)。
SDK包括Web服务器程序,该程序用来模仿App Engine环境,包含一个本地的数据库、
Google帐户以及获取URL的能力和使用App Engine API来从你的电脑上直接发送Email。
SDK可以运行在任何安装Python 2.5的电脑上,提供的版本包括Windows、Mac OS X和
Linux。
(译注:不知道是不是应该把App Engine翻译成程序引擎?)
如果没有安装Python 2.5,请从Python的官方网站(http://www.python.org/)下载
和安装对应操作系统的版本。Mac OS X 10.5 Leopard用户已经直接安装了Python 2.5。
下载App Engine SDK(http://code.google.com/appengine/downloads.html)。
按照下载页面的提示来安装SDK到你的电脑上。
对于本教程来说,你会使用到SDK中的两个命令:
・dev_appserver.py,Web服务器开发
(http://code.google.com/appengine/docs/thedevwebserver.html)
・appcfg.py,用来上传你的程序到App Engine
(http://code.google.com/appengine/docs/appcfgpy.html)
Windows和Mac OS X安装程序会把这些命令直接放到命令路径中。
安装完成之后,你可以直接从命令行窗口下运行这些命令。
(译注:在Windows下是命令提示符)
如果你使用SDK的Zip文档版本,你会在google_appengine目录下发现这些命令。
# Hello, World!
Google App Engine程序和Web服务器之间使用CGI标准进行交互。
(查看CGI标准:http://hoohoo.ncsa.uiuc.edu/cgi/interface.html)
当服务器收到你的程序的一个请求时,它使用请求的数据来运行程序
并处理标准输入流(对于POST数据来说)。作为相应,应用程序写响应到标准
输出流中,包括HTTP头和内容。
(译注:这一段翻译的不好)
让我们来实现一个小小的程序:显示一段信息。
## 创建一个简单的请求处理器
创建一个名为helloworld的目录。本程序的所有文件都放置在这个目录中。
进入到helloworld目录中,创建一个名为helloworld.py的文件,并添加如下代码:
print 'Content-Type: text/plain'
print ''
print 'Hello, world!'
这个Python脚本响应一个请求,这个响应包括描述内容类型的HTTP头、一个空行
以及信息"Hello world!"。
## 创建配置文件
App Engine应用程序有一个名为app.yaml的配置文件。
此文件描述了哪个处理器(handler)脚本对应哪个URL。
在helloworld目录中,创建一个名为app.yaml的文件,并添加如下内容:
application:helloworld
version:1
runtime:python
api_version:1
handlers:
- url:/.*
script:helloworld.py
从上至下,配置文件依次说明了关于程序的下列信息:
・应用程序的标识符是"helloworld"。当你使用App Engine注册你的应用程序时,
在最后一步你会选择一个唯一的标识符,并更新这个值。这个值在开发阶段
可以是任意值。从现在开始,将它设置为"helloworld"。
・版本号"1"是这个应用程序的编号。如果程序更新到了新的版本,App Engine会
保留前面的版本,可以用管理控制台回溯至前面的版本。
・这个代码运行在"python"运行环境下。不久的将来会支持其他运行环境和语言。
・每一个对URL的请求的路径会匹配正则表达式"/.*"(这个正则表达式表示所有的
URL),这将会由"helloworld.py"脚本来处理。
(译注:上面的小节中引号部分在原文中均为绿色,指代上上小节中的代码)
(译注:第一行application后面不能加"_",比如"hello_world"就不行)
这个文件的语法是YAML
(http://www.yaml.org/)。
若要查看完整的配置选项列表,请查看app.yaml参考
(http://code.google.com/appengine/docs/configuringanapp.html)。
## 测试应用程序
使用处理器脚本和配置文件会将每个URL映射至处理器,这样程序就算是完成了。
现在你可以使用App Engine SDK中包含的Web服务器来测试这个程序了。
使用下列命令启动Web服务器,路径为helloworld的目录:
google_appengine/dev_appserver.py helloworld/
(译注:注意目录名不能包含空格,比如放置在桌面就不行)
(译注:我是在google_appengine目录下,输入:python dev_appserver.py hellworld,
然后问是否更新,我看到最新版本是1.0.1了,但是我这里因为网络问题更新不了)
这个Web服务器开始运行,可以监听8080端口的请求。
通过在浏览器中访问下面的地址来测试这个程序。
http://localhost:8080/
想要了解更多关于运行开发Web服务器的信息,包括如何修改使用的端口,
请查看Dev Web服务器参考
(http://code.google.com/appengine/docs/thedevwebserver.html),
或者运行命令时附加选项:--help。
## 迭代开发
你可以在开发程序的过程中保持Web服务器一直在运行。
Web服务器会监视源程序的变化,并在适当的时候重载它们。
试一下:保持Web服务器在运行中,编辑helloworld.py文件,将其中的Hello, world!
改为其他语句。刷新http://localhost:8080/就可以看到变化。
若要关闭Web服务器,在终端窗口激活的情况下,按下Control-C
(或Control-Break)。
你可以保持Web服务器一直运行,因为教程的后面还会用到。
如果你需要停止它,你可以重启它通过运行上面的命令。
# 使用webapp框架
CGI标准非常简单,但是手写全部的代码还是非常笨重的。
Web应用程序框架就会替你处理这些细节,这样你就可以只关注于你的应用程序功能。
Google App Engine支持任何使用纯Python编写的支持CGI的框架
(以及任何使用CGI适配器的WSGI框架),包括Django、CherryPy、Pylons和web.py。
你可以选择你的程序代码绑定到一个框架,只需要将代码复制到程序目录中。
(WSGI:http://www.python.org/dev/peps/pep-0333/)
(Django:http://www.djangoproject.com/)
(CherryPy:http://www.cherrypy.org/)
(Pylons:http://pylonshq.com/)
(web.py:http://webpy.org/)
App Engine包括一个简单的Web程序框架,名为:webapp。
webapp框架已经安装在App Engine环境和SDK中,所以你不需要绑定它,
可以直接在应用程序代码中使用。在教程的后续部分中,我们会使用webapp。
## Hello, webapp!
一个webapp应用程序由三个部分组成:
・一个或多RequestHandler类,用来处理请求和创建响应
・一个WSGIApplication实例,用来将输入请求连到基于URL的处理器
・使用CGI适应器运行WSGIApplication的主程序
让我们重新写我们的"友好的问候"(译注:这里指Hello world,幽默一下),
作为一个webapp程序。
编辑Helloworld/helloworld.py,并用下面的内容来进行替换:
import wsgiref.handlers
from google.appengine.ext import webapp
class MainPage(webapp.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write('Hello, webapp World!')
def main():
application = webapp.WSGIApplication(
[('/', MainPage)],
debug=True)
wsgiref.handlers.CGIHandler().run(application)
if __name__ == "__main__":
main()
(译注:我第一次看有人用两个空格作为缩进)
在浏览器中刷新http://localhost:8080/,可以看到新版本的运行结果。
(如果你已经停止了你的Web服务器,请重新启动它,
具体的命令在"Hello, World!"章节中有介绍)
## webapp做了什么
webapp模块在google.appengine.ext包中。
这个模块在SDK中提供,也在生产运行环境中。
代码定义了一个请求处理器"MainPage",并映射到根URL(/)。
当webapp接收到一个HTTP GET对URL"/"的请求时,它会实例化MainPage类,
并调用这个实例的get方法。在这个方法中,关于请求的信息可以被self.request
所调用。例如:这个方法为每个响应来设置self.response的变量,然后退出。
webapp在MainPage实例的最后阶段发送一个响应。
应用程序本身由webapp.WSGIApplication实例来呈现。
参数debug=true传递到构造器,通知webapp打印出浏览器输出的栈跟踪,
当然前提是如果处理器遇到错误或引发一个为捕捉的异常。
在你的程序的最终版本中,你会去除这个选项。
代码使用了来自Python标准库的wsgiref模块来运行WSGIApplication,即一个
CGI适应器。想要了解这个模块更多的信息,请访问wsgiref模块文档
(http://docs.python.org/lib/module-wsgiref.html)。
在本教程的后面我们会用到webapp的一些其他功能。
想要了解webapp的更多信息,请查看webapp参考
(http://code.google.com/appengine/docs/webapp/)。
# 使用用户服务
Google App Engine提供很多有用的服务,这些服务都基于Google基础构造,
(注:我将infrastructure翻译为基础构造,
但是我理解的是Google的一些基础服务及文件)
可以通过SDK中包含的库来使得程序可以访问这些服务。
其中的一个服务就是用户(User)服务,这个服务可以使你的程序和
Google用户帐户进行整合。
使用用户服务,你的用户可以使用他们已有的Google帐户来申请你的应用。
让我们看看用户服务是如何定制应用程序的个性化问候。
## 使用用户(Users)
再次编辑helloworld/helloworld.py,
使用下面的内容进行替换:
import wsgiref.handlers
from google.appengine.api import users
from google.appengine.ext import webapp
class MainPage(webapp.RequestHandler):
def get(self):
user = users.get_current_user()
if user:
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write('Hello, ' + user.nickname())
else:
self.redirect(users.create_login_url(self.request.uri))
def main():
application = webapp.WSGIApplication(
[('/', MainPage)],
debug=True)
wsgiref.handlers.CGIHandler().run(application)
if __name__ == "__main__":
main()
在浏览器中重新加载页面。
你的程序会重定向到一个本地版本的Google登陆页面,
这个页面可以用来测试你的程序。
你可以在屏幕上输入任何你喜欢的用户名,
然后你的程序会发现一个基于这个用户名的伪造User对象。
当你的程序运行在App Engine上时,用户会被导向到Google帐户
的登陆页面,当登陆之后,或注册了一个新帐户之后,
会重新返回到你的应用。
## Users API
让我们来仔细研究一下新的代码:
user = users.get_current_user()
如果用户已经注册了你的应用,get_current_user()返回用户的
User对象。如果没有,那么返回None。
if user:
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write('Hello, ' + user.nickname())
如果用户已经登陆,显示一个个性化的信息,使用和用户帐户
相关的昵称。
else:
self.redirect(users.create_login_url(self.request.uri))
如果用户没有登陆,告诉webapp重定向用户的浏览器至Google帐户登陆页面。
重定向中包含此页的网址(self.request.uri),这样Google帐户登陆机制
才能在用户登陆完成或注册完成之后将用户返回来。
想要了解更多Users API的信息,请参见用户参考
(http://code.google.com/appengine/docs/users/)。
# 使用webapp处理表单
如果你想要用户提交他们自己的问候,我们就需要一个方法来处理
用户通过Web表格提供的信息。
webapp框架使得处理表格数据变得更容易。
## 使用webapp处理Web表格
使用下列内容替换helloworld/helloworld.py中的内容:
import cgi
import wsgiref.handlers
from google.appengine.api import users
from google.appengine.ext import webapp
class MainPage(webapp.RequestHandler):
def get(self):
self.response.out.write("""
<html>
<body>
<form action="/sign" method="post">
<div><textarea name="content" rows="3" cols="60"></textarea></div>
<div><input type="submit" value="Sign Guestbook"></div>
</form>
</body>
</html>""")
class Guestbook(webapp.RequestHandler):
def post(self):
self.response.out.write('<html><body>You wrote:<pre>')
self.response.out.write(cgi.escape(self.request.get('content')))
self.response.out.write('</pre></body></html>')
def main():
application = webapp.WSGIApplication(
[('/', MainPage),
('/sign', Guestbook)],
debug=True)
wsgiref.handlers.CGIHandler().run(application)
if __name__ == "__main__":
main()
刷新页面就可看到此表格,然后试着提交一条信息。
当前版本有两个处理器(handler):
MainPage,映射到地址"/",显示一个Web表格。
Guestbook,映射到地址"/sign",显示Web表格提交的数据。
Guestbook处理器有一个post()方法,而没有get()方法。
这是因为MainPage显示的表格使用了HTTP POST方法(method="post")
来提交表格数据。
如果因为某些原因你想要一个处理器可以对同一个网址进行GET和POST
操作,你可以在相同类中为每个动作定义这样一个方法。
post()方法中的代码获取来自self.request的表格信息。
在显示给用户之前,它使用cgi.escape()来将HTML特定字符转换成
这些字符的对应体。cgi是一个标准的Python库;查看cgi文档来获取
更多信息(http://docs.python.org/lib/module-cgi.html)。
注意:App Engine环境包含完整的Python 2.5标准库。
但是,不是所有的操作都被允许。
App Engine程序运行在一个受限的环境中,
只能允许App Engine安全的进行扩展。
例如:对操作系统的低层调用、网络操作以及一些文件系统操作
都是不允许的,当尝试这些操作时,会引起错误。
了解更多信息,查看Python运行环境
(http://code.google.com/appengine/docs/python/)。
# 使用数据存储
在可扩展的Web应用程序中,存储数据是非常困难的。
用户在某段时间中会和多个Web服务器进行交流,
用户的上一个请求是这个服务器进行处理的,
但是下一个请求会跳至其他的服务器。
所有的Web服务器会对数据进行沟通,
这也许会扩展到数十个服务器,
这些服务器有可能在不同的地方。
但是依靠Google App Engine,你不用过多考虑上述的问题。
App Engine的架构考虑到了数据的所有发布、分派和加载平衡,
这些都在一个简单API后面,
这就是一个强大的查询和处理引擎。
## 保存提交的问候
App Engine包括Python的数据模型API(data modelling API)。
它和Django的数据模型API比较相似
(http://www.djangoproject.com/documentation/model-api/)。
但是在后端使用了App Engine的可扩展数据存储。
对于留言簿应用程序来说,我们想要去存储用户提交的问候语。
每个问候语包括作者的名字、信息的内容以及信息提交的日期和时间,
日期和时间能确保我们按照时间顺序来显示这些信息。
编辑helloworld/helloworld.py文件,
并在顶部添加下列import语句:
from google.appengine.ext import db
在MainPage类上面添加下面这个类:
class Greeting(db.Model):
author = db.UserProperty()
content = db.StringProperty(multiline=True)
date = db.DateTimeProperty(auto_now_add=True)
这个类定义了Greeting模型,该模型有3个属性:
author,值为User对象
content,值为一个字符串
date,值为datetime.datetime
(译注:datetime请参考python说明,import datetime; help(datetime))
带有参数的属性构造器可以进一步指定它们的行为。
带有multiline=True参数的db.StringProperty构造器
标明这个值可以包含多行字符。
带有auto_now_add=True参数的db.DateTimeProperty构造器
指定了当对象被创建时,如果应用程序没有赋予其他值,
那么新的对象自动被赋予一个date的时间。
查看万张的属性类型和选项列表,查看数据存储参考
(http://code.google.com/appengine/docs/datastore/)。
现在我们有了一个问候语的数据模型,应用程序可以用这个模型
来创建一个新的Greeting对象,并将它们存进数据库中。
编辑Guestbook处理器,代码如下:
class Guestbook(webapp.RequestHandler):
def post(self):
greeting = Greeting()
if users.get_current_user():
greeting.author = users.get_current_user()
greeting.content = self.request.get('content')
greeting.put()
self.redirect('/')
新的Guestbook处理器创建一个新的Greeting对象,并将用户提交
的数据来设置了它的author和content属性。
如果没有设置date属性,那么date会被自动设置为"now"(当前),
就像我们在模型中制定的那样。
最后,greeting.put()保存我们的新对象到数据库中。
如果我们获取到对象的查询,put()会坑新当前对象。
因为我们使用模型构造器来创建对象,
因此put()创建了一个新的对象到数据库中。
## 使用GQL找回存储的问候语
App Engine数据库有一个优秀的(sophisticated)的数据模型
查询引擎。因为App Engine数据库不是传统关系数据库,因此查询
不是用SQL来定义的。但是你可以使用一种类似SQL的查询语言,
我们称之为GQL。GQL提供了访问App Engine数据库的查询引擎功能,
语法与SQL十分相近。
编辑MainPage处理器,代码如下:
class MainPage(webapp.RequestHandler):
def get(self):
self.response.out.write('<html><body>')
greetings = db.GqlQuery("SELECT * FROM Greeting ORDER BY date DESC LIMIT 10")
for greeting in greetings:
if greeting.author:
self.response.out.write('<b>%s</b> wrote:' % greeting.author.nickname())
else:
self.response.out.write('An anonymous person wrote:')
self.response.out.write('<blockquote>%s</blockquote>' %
cgi.escape(greeting.content))
# Write the submission form and the footer of the page
self.response.out.write("""
<form action="/sign" method="post">
<div><textarea name="content" rows="3" cols="60"></textarea></div>
<div><input type="submit" value="Sign Guestbook"></div>
</form>
</body>
</html>""")
在浏览器中刷新http://localhost:8080/,输入一些消息来确认消息可以被
正常发送。
查询代码如下所示:
greetings = db.GqlQuery("SELECT * FROM Greeting ORDER BY date DESC LIMIT 10")
(译注:我看不出来这和SQL有什么区别)
另外,你也可以调用Greeting类的gql(...)方法,
省略查询中的"SELECT * FROM Greeting":
greetings = Greeting.gql("ORDER BY date DESC LIMIT 10")
和SQL一样,关键词(例如"SELECT")是大小写不敏感的。
但是,其他变量名是大小写敏感的。
(译注:我感觉把SQL的关键词都大写是一种很好的习惯)
因为查询返回全部数据对象,因此选择模型的特定属性没有什么意义。
所有的GQL查询都是以"SELECT * FROM model"开头,
(或应用模型的gql方法),
或者与之类似的SQL等效语句。
(译注:我其实发现了把model翻译成模型不是太合适,或者是模组?)
(译注:其实greeting翻译成祝福语也挺不准确的,问候语?)
一个有WHERE语句的GQL查询会依据一个或几个条件的属性值来过滤得到的结果。
和SQL不同,GQL查询"不"包含常量:相反,GQL使用查询中所有值的绑定参数。
例如,若只想获取当前用户的祝福语:
if users.get_current_user():
greetings = Greeting.gql("WHERE author = :1 ORDER BY date DESC",
users.get_current_user())
你也可以使用命名的参数代替位置参数:
greetings = Greeting.gql("WHERE author = :author ORDER BY date DESC",
author=users.get_current_user())
除GQL之外,数据存储API提供了使用方法创建查询对象的其他机制。
上面的查询也可以修改为下面的代码:
greetings = Greeting.all()
greetings.filter("author =", users.get_current_user())
greetings.order("-date")
查看完整的GQL及查询API描述,请参见数据存储参考
(http://code.google.com/appengine/docs/datastore/)。
## 清除开发服务器数据库
开发Web服务器使用一个本地版本的数据库来测试你的应用程序,
即使用临时文件。
只要临时文件错在数据就会一直存在,Web服务器不会重置这些文件
除非你要求这么做。
如果你想要开发服务器在启动时预先清除数据库,请在启动服务器时
添加--clear_datastore选项:
dev_appserver.py --clear_datastore helloworld/
(注:我最近在找工作,但是找不到。对不起,这和本文没什么关系,sorry)
# 使用模板
代码嵌套在HTML中是很杂乱和难以维护的,最好的办法是使用模板系统。
在模板系统中,HTML被作为一个单独的文件,
使用得定的语法来表明程序中的数据从何而来。
有很多Python的模板系统:EZT、Cheetah、ClearSliver、Quixote和Django等等。
你可以使用你的模板引擎,并将它绑定到你的应用程序代码中。
(EZT:http://svn.webdav.org/repos/projects/ezt/trunk/ezt.py)
(Cheetah:http://www.cheetahtemplate.org/)
(ClearSliver:http://www.clearsilver.net/)
(Quixote:http://www.mems-exchange.org/software/quixote/)
(Django:http://www.djangoproject.com/documentation/templates/)
为了更加方便,webapp模块包含了Django模板引擎。这也作为一个部分包含在
SDK和App Engine中,所以你使用的时候不需要再去绑定它。
## 使用Django模板
添加下列import语句在helloworld/helloworld.py的顶部:
import os
from google.appengine.ext.webapp import template
使用下面代码替换MainPage处理器:
class MainPage(webapp.RequestHandler):
def get(self):
greetings = Greeting.all().order('-date')
if users.get_current_user():
url = users.create_logout_url(self.request.uri)
url_linktext = 'Logout'
else:
url = users.create_login_url(self.request.uri)
url_linktext = 'Login'
template_values = {
'greetings': greetings,
'url': url,
'url_linktext': url_linktext,
}
path = os.path.join(os.path.dirname(__file__), 'index.html')
self.response.out.write(template.render(path, template_values))
最后在helloworld目录中创建一个index.html文件,该文件的内容如下:
<html>
<body>
{% for greeting in greetings %}
{% if greeting.author %}
<b>{{ greeting.author.nickname }}</b> wrote:
{% else %}
An anonymous person wrote:
{% endif %}
<blockquote>{{ greeting.content|escape }}</blockquote>
{% endfor %}
<form action="/sign" method="post">
<div><textarea name="content" rows="3" cols="60"></textarea></div>
<div><input type="submit" value="Sign Guestbook"></div>
</form>
<a href="{{ url }}">{{ url_linktext }}</a>
</body>
</html>
刷新一下页面,然后看看。
template.render(path, template_values)有两个参数:一个是模板文件的文件路径;
一个是字典值。并返回递归文本。这个模板用了Django模板语法来访问和重申值,
以及来引用这些值的属性。在许多情况下,你可以将数据存储模板对象直接作为值,
并通过模板来访问他们的属性。
提示:一个App Engine应用程序有对这个项目所有上传文件、库文件的只读权限,
但是不包括其他文件。当前工作路径就是程序的主目录,所有index.html
的路径就是简单的"index.html"。
想要了解更多关于Django模板引擎的信息,请访问Django 0.96模板文档
(http://www.djangoproject.com/documentation/0.96/templates/)。
# 使用静态文件
和传统的Web主机环境不同,Google App Engine不支持直接访问你的
应用程序源代码目录下的文件,除非制定这样做。我们将我们的模板
文件命名为index.html,但是不会自动使得文件可以通过URL/index.html
来访问。
当时,有很多情况下你希望直接通过Web浏览器访问静态文件。
例如:图片、CSS文件、JavaScript代码、影片和Flash动画就会保存在应用
程序目录下并直接通过浏览器访问。你可以告知App Engine来直接访问特定
的文件,而不需要编辑处理器。
## 使用静态文件
编辑helloworld/app.yaml,并用下列内容进行替换:
application: helloworld
version: 1
runtime: python
api_version: 1
handlers:
- url: /stylesheets
static_dir: stylesheets
- url: /.*
script: helloworld.py
新的hanlers部分定义了两个用于URL的处理器。
当App Engine接收到一个来自网址头部包含/stylesheets的请求时,
它映射文件的剩余路径到stylesheets路径,如果找到对应的文件,
该文件的内容会被返回到客户端。其他网址映射"/"路径,并由
helloworld.py脚本来处理。
默认情况下,App Engine使用基于文件名扩展的MIME类型来访问静态文件。
例如一个文件名后缀为.csss的会被认为是text/css MIME类型。
你可以通过额外的选项来制定准确的MIME类型。
URL处理期路径参数会按照它们在app.yaml中的顺序从顶到底进行处理。
在本例中,/stylesheets参数会在/.*参数映射之前找到相应路径。
想了解更多URL映射的信息,以及可以制定app.yaml的参数信息,
请查看app.yaml参考(http://code.google.com/appengine/docs/configuringanapp.html)。
创建目录helloworld/stylesheets。
在这个新目录中,创建一个新文件,名为main.css,内容如下:
#body {
# font-family: Verdana, Helvetica, sans-serif;
# background-color: #DDDDDD;
#}
(注:css内容前面每一行我都加了"#"以免显示不正确)
(注:在支持文字定义的blog中,css代码都不能正常显示)
(otherrrr@gmail.com)
最后,编辑helloworld/index.html文件,并插入下面的代码,
在<html>行之后:
# <head>
# <link type="text/css" rel="stylesheet" href="/stylesheets/main.css" />
# </head>
(注:每一行我都加了一个"#")
在浏览器中刷新页面,会看到使用层叠演示表的新的页面。
# 上传你的程序
你可以使用管理控制台来创建和管理App Engine的应用程序。
如果你注册了你的应用程序ID,你可以使用SDK中的命令行工具
来上传程序到网站上。这个工具是appcfg.py。
注意:在写本文时,还没有办法来删除App Enginge上的程序。
这个功能会很快添加。在预览版本中,你可以注册3个程序ID。
如果你不想为本教程分配一个程序ID,你可只是简单看看这个
部分,当你准备上传程序时在详细的了解。
## 注册应用程序
你可以通过App Engine管理平台创建和管理App Enginge的Web应用程序,
网址如下:
http://appengine.google.com
通过你的Google帐户登陆App Engine。
如果你没有Google帐户,请可以通过一个E-mail地址和密码来创建一个
Google帐户(https://www.google.com/accounts/)。
单击"Create an Applicatio"按钮来创建一个新的应用u程序。
根据指引来注册一个应用程序ID,即这个程序的唯一的名称。
如果你选择使用免费的appspot.com域名,那么这个程序的完整网址
就是:http://application-id.appspot.com/。
你可以为你的应用购买一个顶级域名,也可以使用已经注册的域名。
编辑app.yaml文件,然后修改application的对应值:设置helloworld对应
你注册的应用程序ID。
(注:我发现很多人都是因为这个问题结果上传后出错或无法浏览)
## 上传程序
使用下列命令上传完成的应用程序到Google App Engine:
appcfg.py update helloworld/
在命令行(或终端)下输入你的Google用户名和密码。
现在你就可以看到你的程序已经运行在App Enginge上了。
如果你设置使用免费的appspot域名,
那么网址会是:
http://application-id.appspot.com
## 祝贺你!
你已经完成了本教程。
想要了解更多的信息,请参看App Engine文档。
(http://code.google.com/appengine/docs/)
PERMISSION COMMAND
U G W
rwx rwx rwx chmod 777 filename
rwx rwx r-x chmod 775 filename
rwx r-x r-x chmod 755 filename
rw- rw- r-- chmod 664 filename
rw- r-- r-- chmod 644 filename
U = User
G = Group
W = World
r = Readable
w = writable
x = executable
- = no permission另外一种维度来看:
Permissions:
400 read by owner
040 read by group
004 read by anybody (other)
200 write by owner
020 write by group
002 write by anybody
100 execute by owner
010 execute by group
001 execute by anybody
1.强大搜索功能
2.差异化表单
3.酬金设置
4.匹配邮件自动发送
JRuby 1.1.5 是从 JRuby 1.1以来的第5个发行版。主要改进了兼容性和效率问题。我们的目标是更快的更新周期(3-4周)。我们希望在一个更快的更新周期里面解决JRuby用户提出的问题。
主要更新: - 每个类方法缓存 (改进 _send_, respond_to?, and defined?)
- 常量缓存显著的改进了常量的搜索
- 减少了内存占用
- 几个 Java 集成的修复
- 更新到Rubygems 1.3.1 和 Rspec 1.1.11
- 更新了 ffi (Foreign Function Interface) 支持t
- 更多 1.9 mode支持
- 修复了从 1.1.4以来的113 bug
本文目的有两个:
1、记下VMware启动时如何选择启动介质:按ESC建。(总是记不住)
2、测试我的两个支持email post的blog能不能发送图片。附件是VMware启动时的截图。
sudo apt-get install build-essential
RPM Fusion 是为 Fedora 及 Red Hat Enterprise Linux 用户提供的一个软件包仓库。各位 Fedora/RHEL 朋友要是想要安装的软件在官方的仓库中找不到,不要泄气,兴许通过 RPM Fusion 你就找到了。Freshrpms这个网站是我用的比较多的。上次在RHEL4下面装Oracle,找缺少的rpm包全靠它了。新启动的 RPM Fusion 合并了原有的 Dribble、Freshrpms、Livna 等软件包仓库,将成为最大的第三方软件包仓库。
通过 RPM Fusion 软件包仓库,你将找到 ATI/NVIDIA 显卡驱动、私有的音频/视频编码/解码器、游戏、模拟器、以及其他软件包等。
RPM Fusion 网站位于:http://rpmfusion.org
sudo apt-get install language-pack-zh language-pack-gnome-zh
sudo apt-get install scim-pinyin sudo apt-get install ttf-wqy-zenhei
deb http://ubuntu.uestc.edu.cn/ubuntu/ intrepid main restricted universe multiverse
deb http://ubuntu.uestc.edu.cn/ubuntu/ intrepid-backports main restricted universe multiverse
deb http://ubuntu.uestc.edu.cn/ubuntu/ intrepid-proposed main restricted universe multiverse
deb http://ubuntu.uestc.edu.cn/ubuntu/ intrepid-security main restricted universe multiverse
deb http://ubuntu.uestc.edu.cn/ubuntu/ intrepid-updates main restricted universe multiverse
deb-src http://ubuntu.uestc.edu.cn/ubuntu/ intrepid main restricted universe multiverse
deb-src http://ubuntu.uestc.edu.cn/ubuntu/ intrepid-backports main restricted universe multiverse
deb-src http://ubuntu.uestc.edu.cn/ubuntu/ intrepid-proposed main restricted universe multiverse
deb-src http://ubuntu.uestc.edu.cn/ubuntu/ intrepid-security main restricted universe multiverse
deb-src http://ubuntu.uestc.edu.cn/ubuntu/ intrepid-updates main restricted universe multiverse
创建一个文件 /etc/redhat-release:添加如下内容。Red Hat Linux release 3.1 (drupal)oracle将会把系统认为是redhat 3了:)
sudo gedit /var/lib/locales/supported.d/zh
zh_CN GB18030然后运行:
zh_CN.GB2312 GB2312
zh_CN.UTF-8 UTF-8
zh_CN.GBK GBK
locale-gen等待几分钟,就会生成相应的locale。
Generating locales...最后运行locale -a检查一下:
zh_CN.GB18030... done
zh_CN.GB2312... done
zh_CN.GBK... done
zh_CN.UTF-8... up-to-date
zh_HK.UTF-8... up-to-date
zh_SG.UTF-8... up-to-date
zh_TW.UTF-8... up-to-date
Generation complete.
whylang@ubuntu:~/database$ locale
LANG=zh_CN.gbk
LC_CTYPE="zh_CN.gbk"
LC_NUMERIC="zh_CN.gbk"
LC_TIME="zh_CN.gbk"
LC_COLLATE="zh_CN.gbk"
LC_MONETARY="zh_CN.gbk"
LC_MESSAGES="zh_CN.gbk"
LC_PAPER="zh_CN.gbk"
LC_NAME="zh_CN.gbk"
LC_ADDRESS="zh_CN.gbk"
LC_TELEPHONE="zh_CN.gbk"
LC_MEASUREMENT="zh_CN.gbk"
LC_IDENTIFICATION="zh_CN.gbk"
LC_ALL=