Tornado学习笔记(四)
一、Tornado的語言國際化方法
Tornado做國際化折騰了一下下,Tornado這部分的官方文檔太poor了。所以自己記錄一下如何用tornado結合gettext做國際化。
第一步,在項目路徑下建立./locales/zh_CN/LC_MESSAGES文件夾。
第二步,使用xgettext或poedit在第一步的文件夾下創建一個po文件,比如messages.po,我用poedit創建,比xgettext方便一些。
第三步,編輯該messages.po文件,當然,po文件有自己特定的格式,需要按照它的格式編寫。
msgid?"" msgstr?"" "Project-Id-Version:?\n" "POT-Creation-Date:?\n" "PO-Revision-Date:?\n" "Last-Translator:?\n" "Language-Team:?\n" "MIME-Version:?1.0\n" "Content-Type:?text/plain;?charset=UTF-8\n" "Content-Transfer-Encoding:?8bit\n" "Language:?zh_CN\n" "X-Generator:?Poedit?1.8.4\n"msgid?"Sign?in" msgstr?"登入"msgid?"Sign?out" msgstr?"登出"msgid?"Username" msgstr?"用戶名"msgid?"Password" msgstr?"密碼"msgid是網頁里原先的文本內容,msgstr是準備替換的內容。新內容直接用編輯器往后追加msgid和msgstr就可以了。
第四步,修改HTML網頁模板
{%?include?'../header.html'?%}<form?method="post"?action="/User/Signin">{{?_("Sign?in")?}}<br/>{{?_("Username")?}}<br/><input?type="text"?name="username"?/><br/>{{?_("Password")?}}<br/><input?type="password"?name="password"?/><br?/>{%?module?xsrf_form_html()?%}<input?type="submit"?name="submit"?value="{{?_("Sign?in")?}}"?/> </form>{%?include?'../footer.html'?%}html里面的{{ _("Sign in") }}等內容就是需要gettext查找和替換的內容。
第五步,在tornado主文件內添加gettext支持的方法。
import?os import?tornado.autoreload import?tornado.httpserver import?tornado.ioloop import?tornado.web import?tornado.locale''' ... '''if?__name__?==?'__main__':tornado.locale.set_default_locale('zh_CN')tornado.locale.load_gettext_translations('./locales',?'messages')server?=?tornado.httpserver.HTTPServer(application)server.listen(20000)loop?=?tornado.ioloop.IOLoop.instance()tornado.autoreload.start(loop)loop.start()由于我用的ubuntu系統,所以服務器端會被強制認為使用en_US編碼,所以我作為調試,強制指定了set_default_locale('zh_CN'),然后使用tornado.locale.load_gettext_translations('./locales', 'messages')來讀取locales文件夾下的messages項目的mo文件。
第六步,在自己寫的Handler里面,加入locale.translate
class?BaseHandler(tornado.web.RequestHandler):def?get_current_user(self):_?=?self.locale.translateuser?=?self.get_secure_cookie('username')return?userclass?SigninHandler(BaseHandler):def?get(self):self.render('User/sign_in.html')def?post(self):username?=?self.get_argument('username')password?=?self.get_argument('password')if?username?==?'xianglei':self.set_secure_cookie('username',?'xianglei')self.redirect('/')class?SignoutHandler(BaseHandler):def?get(self,?*args,?**kwargs):self.clear_all_cookies()self.redirect('/')_=self.locale.translate,self.locale.translate實際是一個方法,那么把這個方法放到_這個對象里面,然后_方法會被自動代入到模板中去執行替換_("Sign in"),所以實際在模板里面寫的 {{ _("Sign in") }}實際上是讓Tornado執行tornado.locale.translate()方法。這樣的話,如果我去掉之前的set_default_locale(),頁面顯示的就是英文的Sign in,加上,顯示的就是中文的登入。
同樣,Tornado也可以使用一個csv文件作為翻譯的基礎字典,默認是采用csv方式的。
二、Tornado作為HTTP client執行RESTful命令。
之前已經記錄了Tornado異步的客戶端,昨天調試了一下用Tornado做HDFS和YARN的RESTful客戶端。HDFS的RESTful方式,不能使用異步,需要使用Tornado同步客戶端才可以。HDFS和YARN的RESTful管理方式需要用到HTTP的四種查詢方式,GET,POST,PUT,DELETE。其中PUT和DELETE的方式跟POST和GET很類似。
比如
class?MakeDirectoryHandler(BaseHandler):@tornado.web.authenticateddef?post(self):host?=?self.get_argument('host')port?=?self.get_argument('port')directory?=?self.get_argument('directory')username?=?self.get_secure_cookie('username')base_url?=?'http://'+host+':'+port+'/webhdfs/v1'+directory+'?op=MKDIRS&user.name='+usernameput_body?=?dict()put_body['op']?=?'MKDIRS'put_body['user.name']?=?usernameput_body?=?urllib.urlencode(put_body)try:http?=?tornado.httpclient.HTTPClient()response?=?http.fetch(tornado.httpclient.HTTPRequest(url=base_url,method='PUT',body=put_body,))self.write(response.body)except?tornado.httpclient.HTTPError,?e:self.write('{"errcode":"'+str(e).replace('\n',?'<br?/>')+'"}')HDFS的MKDIRS方法放在PUT組里面,所以提交的參數需要用urlencode進行編碼轉換后PUT給RESTful接口。
而DELETE則是。
class?RemoveHandler(BaseHandler):@tornado.web.authenticateddef?post(self):host?=?self.get_argument('host')port?=?self.get_argument('port')filename?=?self.get_argument('filename')'''If?recursive?=?true,?it?use?to?remove?whole?directoryIf?recursive?=?false,?it?use?to?remove?a?file?or?an?empty?directoryThe?argument?must?be?string.'''recursive?=?self.get_argument('recursive')username?=?self.get_secure_cookie('username')base_url?=?'http://'+host+':'+port+'/webhdfs/v1'+filename+'?op=DELETE&recursive='+recursive+'&user.name='+usernametry:http?=?tornado.httpclient.HTTPClient()response?=?http.fetch(tornado.httpclient.HTTPRequest(url=base_url,method='DELETE',))self.write(response.body)except?tornado.httpclient.HTTPError,?e:self.write('{"errcode":"'+str(e).replace('\n',?'<br?/>')+'"}')跟GET方式一樣,DELETE不需要封裝傳遞參數。
總結
以上是生活随笔為你收集整理的Tornado学习笔记(四)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何绕过浏览器的弹窗拦截机制
- 下一篇: 【转载】selenium webdriv