├── .gitignore ├── LICENSE ├── README.md └── src ├── readme.md ├── tornado-1.0.0 ├── README.md └── tornado │ ├── __init__.py │ ├── auth.py │ ├── autoreload.py │ ├── database.py │ ├── epoll.c │ ├── escape.py │ ├── httpclient.py │ ├── httpserver.py │ ├── httputil.py │ ├── ioloop.py │ ├── iostream.py │ ├── locale.py │ ├── options.py │ ├── s3server.py │ ├── template.py │ ├── test │ ├── README │ └── test_ioloop.py │ ├── web.py │ ├── win32_support.py │ └── wsgi.py ├── tornado-3.2.2 ├── demos │ ├── appengine │ │ ├── README │ │ ├── app.yaml │ │ ├── blog.py │ │ ├── static │ │ │ └── blog.css │ │ └── templates │ │ │ ├── archive.html │ │ │ ├── base.html │ │ │ ├── compose.html │ │ │ ├── entry.html │ │ │ ├── feed.xml │ │ │ ├── home.html │ │ │ └── modules │ │ │ └── entry.html │ ├── auth │ │ └── authdemo.py │ ├── benchmark │ │ ├── benchmark.py │ │ ├── chunk_benchmark.py │ │ ├── stack_context_benchmark.py │ │ └── template_benchmark.py │ ├── blog │ │ ├── README │ │ ├── blog.py │ │ ├── schema.sql │ │ ├── static │ │ │ └── blog.css │ │ └── templates │ │ │ ├── archive.html │ │ │ ├── base.html │ │ │ ├── compose.html │ │ │ ├── entry.html │ │ │ ├── feed.xml │ │ │ ├── home.html │ │ │ └── modules │ │ │ └── entry.html │ ├── chat │ │ ├── chatdemo.py │ │ ├── static │ │ │ ├── chat.css │ │ │ └── chat.js │ │ └── templates │ │ │ ├── index.html │ │ │ └── message.html │ ├── facebook │ │ ├── README │ │ ├── facebook.py │ │ ├── static │ │ │ ├── facebook.css │ │ │ └── facebook.js │ │ └── templates │ │ │ ├── modules │ │ │ └── post.html │ │ │ └── stream.html │ ├── helloworld │ │ └── helloworld.py │ ├── s3server │ │ └── s3server.py │ ├── twitter │ │ ├── home.html │ │ └── twitterdemo.py │ └── websocket │ │ ├── chatdemo.py │ │ ├── static │ │ ├── chat.css │ │ └── chat.js │ │ └── templates │ │ ├── index.html │ │ └── message.html ├── readme.md └── tornado │ ├── __init__.py │ ├── auth.py │ ├── autoreload.py │ ├── ca-certificates.crt │ ├── concurrent.py │ ├── curl_httpclient.py │ ├── escape.py │ ├── gen.py │ ├── httpclient.py │ ├── httpserver.py │ ├── httputil.py │ ├── ioloop.py │ ├── iostream.py │ ├── locale.py │ ├── log.py │ ├── netutil.py │ ├── options.py │ ├── platform │ ├── __init__.py │ ├── asyncio.py │ ├── auto.py │ ├── caresresolver.py │ ├── common.py │ ├── epoll.py │ ├── interface.py │ ├── kqueue.py │ ├── posix.py │ ├── select.py │ ├── twisted.py │ └── windows.py │ ├── process.py │ ├── simple_httpclient.py │ ├── speedups.c │ ├── stack_context.py │ ├── tcpserver.py │ ├── template.py │ ├── test │ ├── README │ ├── __init__.py │ ├── auth_test.py │ ├── concurrent_test.py │ ├── csv_translations │ │ └── fr_FR.csv │ ├── curl_httpclient_test.py │ ├── escape_test.py │ ├── gen_test.py │ ├── gettext_translations │ │ ├── extract_me.py │ │ └── fr_FR │ │ │ └── LC_MESSAGES │ │ │ └── tornado_test.po │ ├── httpclient_test.py │ ├── httpserver_test.py │ ├── httputil_test.py │ ├── import_test.py │ ├── ioloop_test.py │ ├── iostream_test.py │ ├── locale_test.py │ ├── log_test.py │ ├── netutil_test.py │ ├── options_test.cfg │ ├── options_test.py │ ├── process_test.py │ ├── resolve_test_helper.py │ ├── runtests.py │ ├── simple_httpclient_test.py │ ├── stack_context_test.py │ ├── static │ │ ├── dir │ │ │ └── index.html │ │ └── robots.txt │ ├── template_test.py │ ├── templates │ │ └── utf8.html │ ├── test.crt │ ├── test.key │ ├── testing_test.py │ ├── twisted_test.py │ ├── util.py │ ├── util_test.py │ ├── web_test.py │ ├── websocket_test.py │ └── wsgi_test.py │ ├── testing.py │ ├── util.py │ ├── web.py │ ├── websocket.py │ └── wsgi.py └── tornado-4.2.0 ├── .coveragerc ├── .travis.yml ├── LICENSE ├── MANIFEST.in ├── README.rst ├── demos ├── appengine │ ├── README │ ├── app.yaml │ ├── blog.py │ ├── static │ │ └── blog.css │ └── templates │ │ ├── archive.html │ │ ├── base.html │ │ ├── compose.html │ │ ├── entry.html │ │ ├── feed.xml │ │ ├── home.html │ │ └── modules │ │ └── entry.html ├── benchmark │ ├── benchmark.py │ ├── chunk_benchmark.py │ ├── gen_benchmark.py │ ├── stack_context_benchmark.py │ └── template_benchmark.py ├── blog │ ├── Dockerfile │ ├── README │ ├── blog.py │ ├── docker-compose.yml │ ├── requirements.txt │ ├── schema.sql │ ├── static │ │ └── blog.css │ └── templates │ │ ├── archive.html │ │ ├── base.html │ │ ├── compose.html │ │ ├── create_author.html │ │ ├── entry.html │ │ ├── feed.xml │ │ ├── home.html │ │ ├── login.html │ │ └── modules │ │ └── entry.html ├── chat │ ├── chatdemo.py │ ├── static │ │ ├── chat.css │ │ └── chat.js │ └── templates │ │ ├── index.html │ │ └── message.html ├── facebook │ ├── README │ ├── facebook.py │ ├── static │ │ ├── facebook.css │ │ └── facebook.js │ └── templates │ │ ├── modules │ │ └── post.html │ │ └── stream.html ├── helloworld │ └── helloworld.py ├── s3server │ └── s3server.py ├── twitter │ ├── home.html │ └── twitterdemo.py ├── websocket │ ├── chatdemo.py │ ├── static │ │ ├── chat.css │ │ └── chat.js │ └── templates │ │ ├── index.html │ │ └── message.html └── webspider │ └── webspider.py ├── maint ├── README ├── requirements.txt ├── scripts │ ├── custom_fixers │ │ ├── __init__.py │ │ ├── fix_future_imports.py │ │ └── fix_unicode_literal.py │ ├── run_autopep8.sh │ ├── run_fixers.py │ └── test_resolvers.py ├── test │ ├── README │ ├── appengine │ │ ├── README │ │ ├── common │ │ │ ├── cgi_runtests.py │ │ │ └── runtests.py │ │ ├── py27 │ │ │ ├── app.yaml │ │ │ ├── cgi_runtests.py │ │ │ ├── runtests.py │ │ │ └── tornado │ │ ├── setup.py │ │ └── tox.ini │ ├── pyuv │ │ └── tox.ini │ ├── redbot │ │ ├── README │ │ ├── red_test.py │ │ └── tox.ini │ └── websocket │ │ ├── .gitignore │ │ ├── client.py │ │ ├── fuzzingclient.json │ │ ├── fuzzingserver.json │ │ ├── run-client.sh │ │ ├── run-server.sh │ │ ├── server.py │ │ └── tox.ini └── vm │ ├── README │ ├── freebsd │ ├── Vagrantfile │ ├── setup.sh │ └── tox.ini │ ├── shared-setup.sh │ ├── ubuntu10.04 │ ├── Vagrantfile │ ├── setup.sh │ └── tox.ini │ ├── ubuntu12.04 │ ├── Vagrantfile │ ├── setup.sh │ └── tox.ini │ ├── ubuntu14.04 │ ├── Vagrantfile │ ├── setup.sh │ └── tox.ini │ └── windows │ ├── bootstrap.py │ └── tox.ini ├── runtests.sh ├── setup.py ├── tornado ├── __init__.py ├── auth.py ├── autoreload.py ├── concurrent.py ├── curl_httpclient.py ├── escape.py ├── gen.py ├── http1connection.py ├── httpclient.py ├── httpserver.py ├── httputil.py ├── ioloop.py ├── iostream.py ├── locale.py ├── locks.py ├── log.py ├── netutil.py ├── options.py ├── platform │ ├── __init__.py │ ├── asyncio.py │ ├── auto.py │ ├── caresresolver.py │ ├── common.py │ ├── epoll.py │ ├── interface.py │ ├── kqueue.py │ ├── posix.py │ ├── select.py │ ├── twisted.py │ └── windows.py ├── process.py ├── queues.py ├── simple_httpclient.py ├── speedups.c ├── stack_context.py ├── tcpclient.py ├── tcpserver.py ├── template.py ├── test │ ├── __init__.py │ ├── __main__.py │ ├── asyncio_test.py │ ├── auth_test.py │ ├── concurrent_test.py │ ├── csv_translations │ │ └── fr_FR.csv │ ├── curl_httpclient_test.py │ ├── escape_test.py │ ├── gen_test.py │ ├── gettext_translations │ │ ├── extract_me.py │ │ └── fr_FR │ │ │ └── LC_MESSAGES │ │ │ └── tornado_test.po │ ├── httpclient_test.py │ ├── httpserver_test.py │ ├── httputil_test.py │ ├── import_test.py │ ├── ioloop_test.py │ ├── iostream_test.py │ ├── locale_test.py │ ├── locks_test.py │ ├── log_test.py │ ├── netutil_test.py │ ├── options_test.cfg │ ├── options_test.py │ ├── process_test.py │ ├── queues_test.py │ ├── resolve_test_helper.py │ ├── runtests.py │ ├── simple_httpclient_test.py │ ├── stack_context_test.py │ ├── static │ │ ├── dir │ │ │ └── index.html │ │ └── robots.txt │ ├── tcpclient_test.py │ ├── tcpserver_test.py │ ├── template_test.py │ ├── templates │ │ └── utf8.html │ ├── test.crt │ ├── test.key │ ├── testing_test.py │ ├── twisted_test.py │ ├── util.py │ ├── util_test.py │ ├── web_test.py │ ├── websocket_test.py │ └── wsgi_test.py ├── testing.py ├── util.py ├── web.py ├── websocket.py └── wsgi.py └── tox.ini /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | 55 | # Sphinx documentation 56 | docs/_build/ 57 | 58 | # PyBuilder 59 | target/ 60 | 61 | 62 | *.pyc 63 | *~ 64 | build 65 | tornado.egg-info 66 | 67 | 68 | *.pyo 69 | *.class 70 | /dist/ 71 | MANIFEST 72 | /tornado.egg-info/ 73 | .vagrant 74 | /.coverage 75 | /htmlcov/ 76 | /env/ 77 | # Used in demo apps 78 | secrets.cfg 79 | 80 | # add 2016 81 | .idea/ 82 | .DS_Store 83 | 84 | src/tornado-4.2.0/docs/ 85 | tmp/ 86 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 hhstore 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tornado-annotated 2 | 3 | - tornado 源码 注解 4 | 5 | ## 1. 项目说明: 6 | 7 | 1. 对 tornado 框架 源码,添加学习注释 8 | 2. 目前选择的版本: 9 | - 1.0.0 这是 tornado 的第一版,代码应该是最简洁的 10 | - 4.2.1 简单对github 上 使用 tornado 框架的 版本,进行初步统计,发现使用该版本的项目最多. 11 | - 故不再选择 2.x, 3.x 的版本 学习注解 12 | 13 | 14 | ## 2. 本项目结构: 15 | 16 | - 会包含tornado框架的结构剖析. 17 | - 包括 思维导图等工具制作的笔记 18 | - 参考阅读文档 19 | - tornado 核心模块源码重点剖析 20 | 21 | 22 | 23 | ## 3. tornado 源码版本: 24 | 25 | 26 | - [releases](https://github.com/tornadoweb/tornado/releases) 27 | - 版本规律: 28 | - v1.x, v2.x, v3.x, v4.x, 当大版本更新时, 代码增长量, 比较多 29 | - v1.x 的 小版本更新时, 通常是修复 bug, 代码增长量, 比较少. 30 | - 选择阅读版本技巧: 31 | - 选定 某个大版本号, 如 v2.1 32 | - 选择该大版本号号下, 最后一个小版本, 如 v2.1.10 33 | 34 | 35 | ## 4. 各版本代码统计对比: 36 | 37 | - [v1.0.0](https://github.com/tornadoweb/tornado/releases/tag/v1.0.0): 38 | - 代码行数: 6207 (少量测试代码,忽略) 39 | - date: on 23 Jul 2010 40 | - 阅读指数: ✖✖✖✖ (版本过老, 不推荐) 41 | - [v2.1.0](https://github.com/tornadoweb/tornado/releases/tag/v2.1.0): 42 | - 代码行数: 9981 (含 gen.py 模块) 43 | - date: on 21 Sep 2011 44 | - 阅读指数: ✖✖✖✖ (不推荐) 45 | - 对比 v2.1.1, 无优势 46 | - [v2.1.1](https://github.com/tornadoweb/tornado/releases/tag/v2.1.1): 47 | - 代码行数: 12720 - 2721(测试代码) = 9999 48 | - date: on 5 Oct 2011 49 | - 阅读指数: ✖✖✖✖ (不推荐) 50 | - 对比 v2.2.0, 无优势 51 | - [v2.2.0](https://github.com/tornadoweb/tornado/releases/tag/v2.2.0): 52 | - 代码行数: 13654 - 3202(测试代码) = 10453 53 | - date: on 31 Jan 2012 54 | - 阅读指数: ✔✔ (可选) 55 | - [v2.4.1](https://github.com/tornadoweb/tornado/releases/tag/v2.4.1): 56 | - 代码行数: 15174 - 4145(测试代码) = 11029 57 | - date: on 25 Nov 2012 58 | - 阅读指数: ✔✔✔ (可选) 59 | - [v3.1.0](https://github.com/tornadoweb/tornado/releases/tag/v3.1.0): 60 | - 代码行数: 21242 - 7377(测试代码) = 13865 61 | - date: on 16 Jun 2013 62 | - 阅读指数: ✖✖✖✖ (不推荐) 63 | - 对比 v3.2.0, 无优势 64 | - [v3.2.0](https://github.com/tornadoweb/tornado/releases/tag/v3.2.0): 65 | - 代码行数: 22222 - 7873(测试代码) = 14349 66 | - 重大更新: 修改了很多文件 67 | - date: on 14 Jan 2014 68 | - 阅读指数: ✖✖✖✖ (不推荐) 69 | - 对比 v3.2.2, 无优势 70 | - [v3.2.2](https://github.com/tornadoweb/tornado/releases/tag/v3.2.2): 71 | - 代码行数: 22680 - 8107(测试代码) = `14573` 72 | - date: [on 4 Jun 2014]() 73 | - 阅读指数: ✔✔✔✔ (较推荐) 74 | - 本版本为 3.x 最后一个版本 75 | - 本版本 docs 可知有 python 3.4 测试 76 | - 包含 asyncio 模块: tornado.platform.asyncio 77 | - [asyncio 参考](http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001432090954004980bd351f2cd4cc18c9e6c06d855c498000) 78 | - asyncio是Python 3.4版本引入的标准库,直接内置了对异步IO的支持 79 | - asyncio的编程模型就是一个消息循环 80 | - 下一版本为 4.x 系列 81 | - 交叉时间对比: 82 | - `python 3.4.1 final`: [May 18, 2014](https://www.python.org/dev/peps/pep-0429/#id1) 83 | - `python 3.4.4 final`: [December 20, 2015](https://www.python.org/dev/peps/pep-0429/#id3) 84 | - v4.2.0: 85 | - 代码行数: 29851 - 12027(测试代码) = 17824 86 | 87 | -------------------------------------------------------------------------------- /src/tornado-1.0.0/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ## 1.0.0 注解备忘: 5 | 6 | 7 | - 此版本的代码,是python2.x的, 当在pycharm中阅读时,项目环境不要设置成python3. 8 | - 为方便阅读, 删除了 批注源码文件 的 LICENSE 说明, 请注意尊重版权. 9 | - 项目原有模块,函数的英文注释,根据需要,会作中文翻译. 10 | - 本版本 tornado 主体框架 Python 代码行数: `6023` (含注释) 11 | - 代码量,比想象中的少,很精简,很有必要花时间精读一下 12 | - 剔除 Demo 示例代码 13 | - 本版本 单元测试代码,忽略不计 14 | - 统计代码行数命令: find . -name "*.py" | xargs grep -v "^$" | wc -l 15 | 16 | 17 | - 阅读入口: 18 | - tornado/web.py 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | --- 29 | 30 | 31 | 32 | # 原项目 Readme 说明: 33 | 34 | Tornado 35 | ======= 36 | Tornado is an open source version of the scalable, non-blocking web server 37 | and and tools that power FriendFeed. Documentation and downloads are 38 | available at http://www.tornadoweb.org/ 39 | 40 | Tornado is licensed under the Apache Licence, Version 2.0 41 | (http://www.apache.org/licenses/LICENSE-2.0.html). 42 | 43 | Installation 44 | ============ 45 | To install: 46 | 47 | python setup.py build 48 | sudo python setup.py install 49 | 50 | Tornado has been tested on Python 2.5 and 2.6. To use all of the features 51 | of Tornado, you need to have PycURL and a JSON library like simplejson 52 | installed. 53 | 54 | On Mac OS X, you can install the packages with: 55 | 56 | sudo easy_install setuptools pycurl==7.16.2.1 simplejson 57 | 58 | On Ubuntu Linux, you can install the packages with: 59 | 60 | sudo apt-get install python-pycurl python-simplejson 61 | -------------------------------------------------------------------------------- /src/tornado-1.0.0/tornado/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2009 Facebook 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | 17 | """The Tornado web server and tools.""" 18 | -------------------------------------------------------------------------------- /src/tornado-1.0.0/tornado/test/README: -------------------------------------------------------------------------------- 1 | Test coverage is almost non-existent, but it's a start. Be sure to 2 | set PYTHONPATH apprioriately (generally to the root directory of your 3 | tornado checkout) when running tests to make sure you're getting the 4 | version of the tornado package that you expect. -------------------------------------------------------------------------------- /src/tornado-1.0.0/tornado/test/test_ioloop.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import unittest 4 | import time 5 | 6 | from tornado import ioloop 7 | 8 | 9 | class TestIOLoop(unittest.TestCase): 10 | def setUp(self): 11 | self.loop = ioloop.IOLoop() 12 | 13 | def tearDown(self): 14 | pass 15 | 16 | def _callback(self): 17 | self.called = True 18 | self.loop.stop() 19 | 20 | def _schedule_callback(self): 21 | self.loop.add_callback(self._callback) 22 | # Scroll away the time so we can check if we woke up immediately 23 | self._start_time = time.time() 24 | self.called = False 25 | 26 | def test_add_callback(self): 27 | self.loop.add_timeout(time.time(), self._schedule_callback) 28 | self.loop.start() # Set some long poll timeout so we can check wakeup 29 | self.assertAlmostEqual(time.time(), self._start_time, places=2) 30 | self.assertTrue(self.called) 31 | 32 | 33 | if __name__ == "__main__": 34 | import logging 35 | 36 | logging.basicConfig(level=logging.DEBUG, format='%(asctime)s:%(msecs)03d %(levelname)-8s %(name)-8s %(message)s', datefmt='%H:%M:%S') 37 | 38 | unittest.main() 39 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/appengine/README: -------------------------------------------------------------------------------- 1 | Running the Tornado AppEngine example 2 | ===================================== 3 | This example is designed to run in Google AppEngine, so there are a couple 4 | of steps to get it running. You can download the Google AppEngine Python 5 | development environment at http://code.google.com/appengine/downloads.html. 6 | 7 | 1. Link or copy the tornado code directory into this directory: 8 | 9 | ln -s ../../tornado tornado 10 | 11 | AppEngine doesn't use the Python modules installed on this machine. 12 | You need to have the 'tornado' module copied or linked for AppEngine 13 | to find it. 14 | 15 | 3. Install and run dev_appserver 16 | 17 | If you don't already have the App Engine SDK, download it from 18 | http://code.google.com/appengine/downloads.html 19 | 20 | To start the tornado demo, run the dev server on this directory: 21 | 22 | dev_appserver.py . 23 | 24 | 4. Visit http://localhost:8080/ in your browser 25 | 26 | If you sign in as an administrator, you will be able to create and 27 | edit blog posts. If you sign in as anybody else, you will only see 28 | the existing blog posts. 29 | 30 | 31 | If you want to deploy the blog in production: 32 | 33 | 1. Register a new appengine application and put its id in app.yaml 34 | 35 | First register a new application at http://appengine.google.com/. 36 | Then edit app.yaml in this directory and change the "application" 37 | setting from "tornado-appenginge" to your new application id. 38 | 39 | 2. Deploy to App Engine 40 | 41 | If you registered an application id, you can now upload your new 42 | Tornado blog by running this command: 43 | 44 | appcfg update . 45 | 46 | After that, visit application_id.appspot.com, where application_id 47 | is the application you registered. 48 | 49 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/appengine/app.yaml: -------------------------------------------------------------------------------- 1 | application: tornado-appengine 2 | version: 2 3 | runtime: python27 4 | api_version: 1 5 | threadsafe: yes 6 | 7 | handlers: 8 | - url: /static/ 9 | static_dir: static 10 | 11 | - url: /.* 12 | script: blog.application 13 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/appengine/static/blog.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 Facebook 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use this file except in compliance with the License. You may obtain 6 | * a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | body { 18 | background: white; 19 | color: black; 20 | margin: 15px; 21 | margin-top: 0; 22 | } 23 | 24 | body, 25 | input, 26 | textarea { 27 | font-family: Georgia, serif; 28 | font-size: 12pt; 29 | } 30 | 31 | table { 32 | border-collapse: collapse; 33 | border: 0; 34 | } 35 | 36 | td { 37 | border: 0; 38 | padding: 0; 39 | } 40 | 41 | h1, 42 | h2, 43 | h3, 44 | h4 { 45 | font-family: "Helvetica Nue", Helvetica, Arial, sans-serif; 46 | margin: 0; 47 | } 48 | 49 | h1 { 50 | font-size: 20pt; 51 | } 52 | 53 | pre, 54 | code { 55 | font-family: monospace; 56 | color: #060; 57 | } 58 | 59 | pre { 60 | margin-left: 1em; 61 | padding-left: 1em; 62 | border-left: 1px solid silver; 63 | line-height: 14pt; 64 | } 65 | 66 | a, 67 | a code { 68 | color: #00c; 69 | } 70 | 71 | #body { 72 | max-width: 800px; 73 | margin: auto; 74 | } 75 | 76 | #header { 77 | background-color: #3b5998; 78 | padding: 5px; 79 | padding-left: 10px; 80 | padding-right: 10px; 81 | margin-bottom: 1em; 82 | } 83 | 84 | #header, 85 | #header a { 86 | color: white; 87 | } 88 | 89 | #header h1 a { 90 | text-decoration: none; 91 | } 92 | 93 | #footer, 94 | #content { 95 | margin-left: 10px; 96 | margin-right: 10px; 97 | } 98 | 99 | #footer { 100 | margin-top: 3em; 101 | } 102 | 103 | .entry h1 a { 104 | color: black; 105 | text-decoration: none; 106 | } 107 | 108 | .entry { 109 | margin-bottom: 2em; 110 | } 111 | 112 | .entry .date { 113 | margin-top: 3px; 114 | } 115 | 116 | .entry p { 117 | margin: 0; 118 | margin-bottom: 1em; 119 | } 120 | 121 | .entry .body { 122 | margin-top: 1em; 123 | line-height: 16pt; 124 | } 125 | 126 | .compose td { 127 | vertical-align: middle; 128 | padding-bottom: 5px; 129 | } 130 | 131 | .compose td.field { 132 | padding-right: 10px; 133 | } 134 | 135 | .compose .title, 136 | .compose .submit { 137 | font-family: "Helvetica Nue", Helvetica, Arial, sans-serif; 138 | font-weight: bold; 139 | } 140 | 141 | .compose .title { 142 | font-size: 20pt; 143 | } 144 | 145 | .compose .title, 146 | .compose .body_source { 147 | width: 100%; 148 | } 149 | 150 | .compose .body_source { 151 | height: 500px; 152 | line-height: 16pt; 153 | } 154 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/appengine/templates/archive.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block head %} 4 | 20 | {% end %} 21 | 22 | {% block body %} 23 | 31 | {% end %} 32 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/appengine/templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{ handler.settings["blog_title"] }} 6 | 7 | 8 | {% block head %}{% end %} 9 | 10 | 11 |
12 | 25 |
{% block body %}{% end %}
26 |
27 | {% block bottom %}{% end %} 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/appengine/templates/compose.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block body %} 4 |
5 |
6 |
7 |
8 | 9 |  {{ _("Cancel") }} 10 |
11 | {% if entry %} 12 | 13 | {% end %} 14 | {% module xsrf_form_html() %} 15 |
16 | {% end %} 17 | 18 | {% block bottom %} 19 | 20 | 40 | {% end %} 41 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/appengine/templates/entry.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block body %} 4 | {% module Entry(entry) %} 5 | {% end %} 6 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/appengine/templates/feed.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | {% set date_format = "%Y-%m-%dT%H:%M:%SZ" %} 4 | {{ handler.settings["blog_title"] }} 5 | {% if len(entries) > 0 %} 6 | {{ max(e.updated for e in entries).strftime(date_format) }} 7 | {% else %} 8 | {{ datetime.datetime.utcnow().strftime(date_format) }} 9 | {% end %} 10 | http://{{ request.host }}/ 11 | 12 | 13 | {{ handler.settings["blog_title"] }} 14 | {% for entry in entries %} 15 | 16 | http://{{ request.host }}/entry/{{ entry.slug }} 17 | {{ entry.title }} 18 | 19 | {{ entry.updated.strftime(date_format) }} 20 | {{ entry.published.strftime(date_format) }} 21 | 22 |
{% raw entry.html %}
23 |
24 |
25 | {% end %} 26 |
27 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/appengine/templates/home.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block body %} 4 | {% for entry in entries %} 5 | {% module Entry(entry) %} 6 | {% end %} 7 |
{{ _("Archive") }}
8 | {% end %} 9 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/appengine/templates/modules/entry.html: -------------------------------------------------------------------------------- 1 |
2 |

{{ entry.title }}

3 |
{{ locale.format_date(entry.published, full_format=True, shorter=True) }}
4 |
{% raw entry.html %}
5 | {% if current_user and current_user.administrator %} 6 |
{{ _("Edit this post") }}
7 | {% end %} 8 |
9 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/auth/authdemo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2009 Facebook 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | 17 | import tornado.auth 18 | import tornado.escape 19 | import tornado.httpserver 20 | import tornado.ioloop 21 | import tornado.web 22 | 23 | from tornado import gen 24 | from tornado.options import define, options, parse_command_line 25 | 26 | define("port", default=8888, help="run on the given port", type=int) 27 | 28 | 29 | class Application(tornado.web.Application): 30 | def __init__(self): 31 | handlers = [ 32 | (r"/", MainHandler), 33 | (r"/auth/login", AuthHandler), 34 | (r"/auth/logout", LogoutHandler), 35 | ] 36 | settings = dict( 37 | cookie_secret="__TODO:_GENERATE_YOUR_OWN_RANDOM_VALUE_HERE__", 38 | login_url="/auth/login", 39 | ) 40 | tornado.web.Application.__init__(self, handlers, **settings) 41 | 42 | 43 | class BaseHandler(tornado.web.RequestHandler): 44 | def get_current_user(self): 45 | user_json = self.get_secure_cookie("authdemo_user") 46 | if not user_json: return None 47 | return tornado.escape.json_decode(user_json) 48 | 49 | 50 | class MainHandler(BaseHandler): 51 | @tornado.web.authenticated 52 | def get(self): 53 | name = tornado.escape.xhtml_escape(self.current_user["name"]) 54 | self.write("Hello, " + name) 55 | self.write("

Log out") 56 | 57 | 58 | class AuthHandler(BaseHandler, tornado.auth.GoogleMixin): 59 | @gen.coroutine 60 | def get(self): 61 | if self.get_argument("openid.mode", None): 62 | user = yield self.get_authenticated_user() 63 | self.set_secure_cookie("authdemo_user", 64 | tornado.escape.json_encode(user)) 65 | self.redirect("/") 66 | return 67 | self.authenticate_redirect() 68 | 69 | 70 | class LogoutHandler(BaseHandler): 71 | def get(self): 72 | # This logs the user out of this demo app, but does not log them 73 | # out of Google. Since Google remembers previous authorizations, 74 | # returning to this app will log them back in immediately with no 75 | # interaction (unless they have separately logged out of Google in 76 | # the meantime). 77 | self.clear_cookie("authdemo_user") 78 | self.write('You are now logged out. ' 79 | 'Click here to log back in.') 80 | 81 | def main(): 82 | parse_command_line() 83 | http_server = tornado.httpserver.HTTPServer(Application()) 84 | http_server.listen(options.port) 85 | tornado.ioloop.IOLoop.instance().start() 86 | 87 | 88 | if __name__ == "__main__": 89 | main() 90 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/benchmark/benchmark.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # A simple benchmark of tornado's HTTP stack. 4 | # Requires 'ab' to be installed. 5 | # 6 | # Running without profiling: 7 | # demos/benchmark/benchmark.py 8 | # demos/benchmark/benchmark.py --quiet --num_runs=5|grep "Requests per second" 9 | # 10 | # Running with profiling: 11 | # 12 | # python -m cProfile -o /tmp/prof demos/benchmark/benchmark.py 13 | # python -m pstats /tmp/prof 14 | # % sort time 15 | # % stats 20 16 | 17 | from tornado.ioloop import IOLoop 18 | from tornado.options import define, options, parse_command_line 19 | from tornado.web import RequestHandler, Application 20 | 21 | import random 22 | import signal 23 | import subprocess 24 | 25 | # choose a random port to avoid colliding with TIME_WAIT sockets left over 26 | # from previous runs. 27 | define("min_port", type=int, default=8000) 28 | define("max_port", type=int, default=9000) 29 | 30 | # Increasing --n without --keepalive will eventually run into problems 31 | # due to TIME_WAIT sockets 32 | define("n", type=int, default=15000) 33 | define("c", type=int, default=25) 34 | define("keepalive", type=bool, default=False) 35 | define("quiet", type=bool, default=False) 36 | 37 | # Repeat the entire benchmark this many times (on different ports) 38 | # This gives JITs time to warm up, etc. Pypy needs 3-5 runs at 39 | # --n=15000 for its JIT to reach full effectiveness 40 | define("num_runs", type=int, default=1) 41 | 42 | define("ioloop", type=str, default=None) 43 | 44 | class RootHandler(RequestHandler): 45 | def get(self): 46 | self.write("Hello, world") 47 | 48 | def _log(self): 49 | pass 50 | 51 | def handle_sigchld(sig, frame): 52 | IOLoop.instance().add_callback(IOLoop.instance().stop) 53 | 54 | def main(): 55 | parse_command_line() 56 | if options.ioloop: 57 | IOLoop.configure(options.ioloop) 58 | for i in xrange(options.num_runs): 59 | run() 60 | 61 | def run(): 62 | app = Application([("/", RootHandler)]) 63 | port = random.randrange(options.min_port, options.max_port) 64 | app.listen(port, address='127.0.0.1') 65 | signal.signal(signal.SIGCHLD, handle_sigchld) 66 | args = ["ab"] 67 | args.extend(["-n", str(options.n)]) 68 | args.extend(["-c", str(options.c)]) 69 | if options.keepalive: 70 | args.append("-k") 71 | if options.quiet: 72 | # just stops the progress messages printed to stderr 73 | args.append("-q") 74 | args.append("http://127.0.0.1:%d/" % port) 75 | subprocess.Popen(args) 76 | IOLoop.instance().start() 77 | IOLoop.instance().close() 78 | del IOLoop._instance 79 | assert not IOLoop.initialized() 80 | 81 | if __name__ == '__main__': 82 | main() 83 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/benchmark/chunk_benchmark.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Downloads a large file in chunked encoding with both curl and simple clients 4 | 5 | import logging 6 | from tornado.curl_httpclient import CurlAsyncHTTPClient 7 | from tornado.simple_httpclient import SimpleAsyncHTTPClient 8 | from tornado.ioloop import IOLoop 9 | from tornado.options import define, options, parse_command_line 10 | from tornado.web import RequestHandler, Application 11 | 12 | define('port', default=8888) 13 | define('num_chunks', default=1000) 14 | define('chunk_size', default=2048) 15 | 16 | class ChunkHandler(RequestHandler): 17 | def get(self): 18 | for i in xrange(options.num_chunks): 19 | self.write('A' * options.chunk_size) 20 | self.flush() 21 | self.finish() 22 | 23 | def main(): 24 | parse_command_line() 25 | app = Application([('/', ChunkHandler)]) 26 | app.listen(options.port, address='127.0.0.1') 27 | def callback(response): 28 | response.rethrow() 29 | assert len(response.body) == (options.num_chunks * options.chunk_size) 30 | logging.warning("fetch completed in %s seconds", response.request_time) 31 | IOLoop.instance().stop() 32 | 33 | logging.warning("Starting fetch with curl client") 34 | curl_client = CurlAsyncHTTPClient() 35 | curl_client.fetch('http://localhost:%d/' % options.port, 36 | callback=callback) 37 | IOLoop.instance().start() 38 | 39 | logging.warning("Starting fetch with simple client") 40 | simple_client = SimpleAsyncHTTPClient() 41 | simple_client.fetch('http://localhost:%d/' % options.port, 42 | callback=callback) 43 | IOLoop.instance().start() 44 | 45 | 46 | if __name__ == '__main__': 47 | main() 48 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/benchmark/stack_context_benchmark.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Benchmark for stack_context functionality.""" 3 | import collections 4 | import contextlib 5 | import functools 6 | import subprocess 7 | import sys 8 | 9 | from tornado import stack_context 10 | 11 | class Benchmark(object): 12 | def enter_exit(self, count): 13 | """Measures the overhead of the nested "with" statements 14 | when using many contexts. 15 | """ 16 | if count < 0: 17 | return 18 | with self.make_context(): 19 | self.enter_exit(count - 1) 20 | 21 | def call_wrapped(self, count): 22 | """Wraps and calls a function at each level of stack depth 23 | to measure the overhead of the wrapped function. 24 | """ 25 | # This queue is analogous to IOLoop.add_callback, but lets us 26 | # benchmark the stack_context in isolation without system call 27 | # overhead. 28 | queue = collections.deque() 29 | self.call_wrapped_inner(queue, count) 30 | while queue: 31 | queue.popleft()() 32 | 33 | def call_wrapped_inner(self, queue, count): 34 | if count < 0: 35 | return 36 | with self.make_context(): 37 | queue.append(stack_context.wrap( 38 | functools.partial(self.call_wrapped_inner, queue, count - 1))) 39 | 40 | class StackBenchmark(Benchmark): 41 | def make_context(self): 42 | return stack_context.StackContext(self.__context) 43 | 44 | @contextlib.contextmanager 45 | def __context(self): 46 | yield 47 | 48 | class ExceptionBenchmark(Benchmark): 49 | def make_context(self): 50 | return stack_context.ExceptionStackContext(self.__handle_exception) 51 | 52 | def __handle_exception(self, typ, value, tb): 53 | pass 54 | 55 | def main(): 56 | base_cmd = [ 57 | sys.executable, '-m', 'timeit', '-s', 58 | 'from stack_context_benchmark import StackBenchmark, ExceptionBenchmark'] 59 | cmds = [ 60 | 'StackBenchmark().enter_exit(50)', 61 | 'StackBenchmark().call_wrapped(50)', 62 | 'StackBenchmark().enter_exit(500)', 63 | 'StackBenchmark().call_wrapped(500)', 64 | 65 | 'ExceptionBenchmark().enter_exit(50)', 66 | 'ExceptionBenchmark().call_wrapped(50)', 67 | 'ExceptionBenchmark().enter_exit(500)', 68 | 'ExceptionBenchmark().call_wrapped(500)', 69 | ] 70 | for cmd in cmds: 71 | print cmd 72 | subprocess.check_call(base_cmd + [cmd]) 73 | 74 | if __name__ == '__main__': 75 | main() 76 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/benchmark/template_benchmark.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # A simple benchmark of tornado template rendering, based on 4 | # https://github.com/mitsuhiko/jinja2/blob/master/examples/bench.py 5 | 6 | import sys 7 | from timeit import Timer 8 | 9 | from tornado.options import options, define, parse_command_line 10 | from tornado.template import Template 11 | 12 | define('num', default=100, help='number of iterations') 13 | define('dump', default=False, help='print template generated code and exit') 14 | 15 | context = { 16 | 'page_title': 'mitsuhiko\'s benchmark', 17 | 'table': [dict(a=1,b=2,c=3,d=4,e=5,f=6,g=7,h=8,i=9,j=10) for x in range(1000)] 18 | } 19 | 20 | tmpl = Template("""\ 21 | 22 | 23 | 24 | {{ page_title }} 25 | 26 | 27 |
28 |

{{ page_title }}

29 |
30 | 39 |
40 | 41 | {% for row in table %} 42 | 43 | {% for cell in row %} 44 | 45 | {% end %} 46 | 47 | {% end %} 48 |
{{ cell }}
49 |
50 | 51 | \ 52 | """) 53 | 54 | def render(): 55 | tmpl.generate(**context) 56 | 57 | def main(): 58 | parse_command_line() 59 | if options.dump: 60 | print tmpl.code 61 | sys.exit(0) 62 | t = Timer(render) 63 | results = t.timeit(options.num) / options.num 64 | print '%0.3f ms per iteration' % (results*1000) 65 | 66 | if __name__ == '__main__': 67 | main() 68 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/blog/README: -------------------------------------------------------------------------------- 1 | Running the Tornado Blog example app 2 | ==================================== 3 | This demo is a simple blogging engine that uses MySQL to store posts and 4 | Google Accounts for author authentication. Since it depends on MySQL, you 5 | need to set up MySQL and the database schema for the demo to run. 6 | 7 | 1. Install prerequisites and build tornado 8 | 9 | See http://www.tornadoweb.org/ for installation instructions. If you can 10 | run the "helloworld" example application, your environment is set up 11 | correctly. 12 | 13 | 2. Install MySQL if needed 14 | 15 | Consult the documentation for your platform. Under Ubuntu Linux you 16 | can run "apt-get install mysql". Under OS X you can download the 17 | MySQL PKG file from http://dev.mysql.com/downloads/mysql/ 18 | 19 | 3. Install Python prerequisites 20 | 21 | Install the packages MySQL-python, torndb, and markdown (e.g. using pip or 22 | easy_install) 23 | 24 | 3. Connect to MySQL and create a database and user for the blog. 25 | 26 | Connect to MySQL as a user that can create databases and users: 27 | mysql -u root 28 | 29 | Create a database named "blog": 30 | mysql> CREATE DATABASE blog; 31 | 32 | Allow the "blog" user to connect with the password "blog": 33 | mysql> GRANT ALL PRIVILEGES ON blog.* TO 'blog'@'localhost' IDENTIFIED BY 'blog'; 34 | 35 | 4. Create the tables in your new database. 36 | 37 | You can use the provided schema.sql file by running this command: 38 | mysql --user=blog --password=blog --database=blog < schema.sql 39 | 40 | You can run the above command again later if you want to delete the 41 | contents of the blog and start over after testing. 42 | 43 | 5. Run the blog example 44 | 45 | With the default user, password, and database you can just run: 46 | ./blog.py 47 | 48 | If you've changed anything, you can alter the default MySQL settings 49 | with arguments on the command line, e.g.: 50 | ./blog.py --mysql_user=casey --mysql_password=happiness --mysql_database=foodblog 51 | 52 | 6. Visit your new blog 53 | 54 | Open http://localhost:8888/ in your web browser. You will be redirected to 55 | a Google account sign-in page because the blog uses Google accounts for 56 | authentication. 57 | 58 | Currently the first user to connect will automatically be given the 59 | ability to create and edit posts. 60 | 61 | Once you've created one blog post, subsequent users will not be 62 | prompted to sign in. 63 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/blog/schema.sql: -------------------------------------------------------------------------------- 1 | -- Copyright 2009 FriendFeed 2 | -- 3 | -- Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | -- not use this file except in compliance with the License. You may obtain 5 | -- a copy of the License at 6 | -- 7 | -- http://www.apache.org/licenses/LICENSE-2.0 8 | -- 9 | -- Unless required by applicable law or agreed to in writing, software 10 | -- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | -- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | -- License for the specific language governing permissions and limitations 13 | -- under the License. 14 | 15 | -- To create the database: 16 | -- CREATE DATABASE blog; 17 | -- GRANT ALL PRIVILEGES ON blog.* TO 'blog'@'localhost' IDENTIFIED BY 'blog'; 18 | -- 19 | -- To reload the tables: 20 | -- mysql --user=blog --password=blog --database=blog < schema.sql 21 | 22 | SET SESSION storage_engine = "InnoDB"; 23 | SET SESSION time_zone = "+0:00"; 24 | ALTER DATABASE CHARACTER SET "utf8"; 25 | 26 | DROP TABLE IF EXISTS entries; 27 | CREATE TABLE entries ( 28 | id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 29 | author_id INT NOT NULL REFERENCES authors(id), 30 | slug VARCHAR(100) NOT NULL UNIQUE, 31 | title VARCHAR(512) NOT NULL, 32 | markdown MEDIUMTEXT NOT NULL, 33 | html MEDIUMTEXT NOT NULL, 34 | published DATETIME NOT NULL, 35 | updated TIMESTAMP NOT NULL, 36 | KEY (published) 37 | ); 38 | 39 | DROP TABLE IF EXISTS authors; 40 | CREATE TABLE authors ( 41 | id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 42 | email VARCHAR(100) NOT NULL UNIQUE, 43 | name VARCHAR(100) NOT NULL 44 | ); 45 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/blog/static/blog.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 Facebook 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use this file except in compliance with the License. You may obtain 6 | * a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | body { 18 | background: white; 19 | color: black; 20 | margin: 15px; 21 | margin-top: 0; 22 | } 23 | 24 | body, 25 | input, 26 | textarea { 27 | font-family: Georgia, serif; 28 | font-size: 12pt; 29 | } 30 | 31 | table { 32 | border-collapse: collapse; 33 | border: 0; 34 | } 35 | 36 | td { 37 | border: 0; 38 | padding: 0; 39 | } 40 | 41 | h1, 42 | h2, 43 | h3, 44 | h4 { 45 | font-family: "Helvetica Nue", Helvetica, Arial, sans-serif; 46 | margin: 0; 47 | } 48 | 49 | h1 { 50 | font-size: 20pt; 51 | } 52 | 53 | pre, 54 | code { 55 | font-family: monospace; 56 | color: #060; 57 | } 58 | 59 | pre { 60 | margin-left: 1em; 61 | padding-left: 1em; 62 | border-left: 1px solid silver; 63 | line-height: 14pt; 64 | } 65 | 66 | a, 67 | a code { 68 | color: #00c; 69 | } 70 | 71 | #body { 72 | max-width: 800px; 73 | margin: auto; 74 | } 75 | 76 | #header { 77 | background-color: #3b5998; 78 | padding: 5px; 79 | padding-left: 10px; 80 | padding-right: 10px; 81 | margin-bottom: 1em; 82 | } 83 | 84 | #header, 85 | #header a { 86 | color: white; 87 | } 88 | 89 | #header h1 a { 90 | text-decoration: none; 91 | } 92 | 93 | #footer, 94 | #content { 95 | margin-left: 10px; 96 | margin-right: 10px; 97 | } 98 | 99 | #footer { 100 | margin-top: 3em; 101 | } 102 | 103 | .entry h1 a { 104 | color: black; 105 | text-decoration: none; 106 | } 107 | 108 | .entry { 109 | margin-bottom: 2em; 110 | } 111 | 112 | .entry .date { 113 | margin-top: 3px; 114 | } 115 | 116 | .entry p { 117 | margin: 0; 118 | margin-bottom: 1em; 119 | } 120 | 121 | .entry .body { 122 | margin-top: 1em; 123 | line-height: 16pt; 124 | } 125 | 126 | .compose td { 127 | vertical-align: middle; 128 | padding-bottom: 5px; 129 | } 130 | 131 | .compose td.field { 132 | padding-right: 10px; 133 | } 134 | 135 | .compose .title, 136 | .compose .submit { 137 | font-family: "Helvetica Nue", Helvetica, Arial, sans-serif; 138 | font-weight: bold; 139 | } 140 | 141 | .compose .title { 142 | font-size: 20pt; 143 | } 144 | 145 | .compose .title, 146 | .compose .markdown { 147 | width: 100%; 148 | } 149 | 150 | .compose .markdown { 151 | height: 500px; 152 | line-height: 16pt; 153 | } 154 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/blog/templates/archive.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block head %} 4 | 20 | {% end %} 21 | 22 | {% block body %} 23 | 31 | {% end %} 32 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/blog/templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{ escape(handler.settings["blog_title"]) }} 6 | 7 | 8 | {% block head %}{% end %} 9 | 10 | 11 |
12 | 23 |
{% block body %}{% end %}
24 |
25 | {% block bottom %}{% end %} 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/blog/templates/compose.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block body %} 4 |
5 |
6 |
7 |
8 |
{{ _("Syntax documentation") }}
9 | 10 |  {{ _("Cancel") }} 11 |
12 | {% if entry %} 13 | 14 | {% end %} 15 | {% module xsrf_form_html() %} 16 |
17 | {% end %} 18 | 19 | {% block bottom %} 20 | 21 | 41 | {% end %} 42 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/blog/templates/entry.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block body %} 4 | {% module Entry(entry) %} 5 | {% end %} 6 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/blog/templates/feed.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | {% set date_format = "%Y-%m-%dT%H:%M:%SZ" %} 4 | {{ handler.settings["blog_title"] }} 5 | {% if len(entries) > 0 %} 6 | {{ max(e.updated for e in entries).strftime(date_format) }} 7 | {% else %} 8 | {{ datetime.datetime.utcnow().strftime(date_format) }} 9 | {% end %} 10 | http://{{ request.host }}/ 11 | 12 | 13 | {{ handler.settings["blog_title"] }} 14 | {% for entry in entries %} 15 | 16 | http://{{ request.host }}/entry/{{ entry.slug }} 17 | {{ entry.title }} 18 | 19 | {{ entry.updated.strftime(date_format) }} 20 | {{ entry.published.strftime(date_format) }} 21 | 22 |
{% raw entry.html %}
23 |
24 |
25 | {% end %} 26 |
27 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/blog/templates/home.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block body %} 4 | {% for entry in entries %} 5 | {% module Entry(entry) %} 6 | {% end %} 7 |
{{ _("Archive") }}
8 | {% end %} 9 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/blog/templates/modules/entry.html: -------------------------------------------------------------------------------- 1 |
2 |

{{ entry.title }}

3 |
{{ locale.format_date(entry.published, full_format=True, shorter=True) }}
4 |
{% raw entry.html %}
5 | {% if current_user %} 6 |
{{ _("Edit this post") }}
7 | {% end %} 8 |
9 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/chat/static/chat.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 FriendFeed 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use this file except in compliance with the License. You may obtain 6 | * a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | body { 18 | background: white; 19 | margin: 10px; 20 | } 21 | 22 | body, 23 | input { 24 | font-family: sans-serif; 25 | font-size: 10pt; 26 | color: black; 27 | } 28 | 29 | table { 30 | border-collapse: collapse; 31 | border: 0; 32 | } 33 | 34 | td { 35 | border: 0; 36 | padding: 0; 37 | } 38 | 39 | #body { 40 | position: absolute; 41 | bottom: 10px; 42 | left: 10px; 43 | } 44 | 45 | #input { 46 | margin-top: 0.5em; 47 | } 48 | 49 | #inbox .message { 50 | padding-top: 0.25em; 51 | } 52 | 53 | #nav { 54 | float: right; 55 | z-index: 99; 56 | } 57 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/chat/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Tornado Chat Demo 6 | 7 | 8 | 9 | 13 |
14 |
15 | {% for message in messages %} 16 | {% module Template("message.html", message=message) %} 17 | {% end %} 18 |
19 |
20 |
21 | 22 | 23 | 24 | 29 | 30 |
25 | 26 | 27 | {% module xsrf_form_html() %} 28 |
31 |
32 |
33 |
34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/chat/templates/message.html: -------------------------------------------------------------------------------- 1 |
{{ message["from"] }}: {% module linkify(message["body"]) %}
2 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/facebook/README: -------------------------------------------------------------------------------- 1 | Running the Tornado Facebook example 2 | ===================================== 3 | To work with the provided Facebook api key, this example must be 4 | accessed at http://localhost:8888/ to match the Connect URL set in the 5 | example application. 6 | 7 | To use any other domain, a new Facebook application must be registered 8 | with a Connect URL set to that domain. 9 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/facebook/static/facebook.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 Facebook 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use this file except in compliance with the License. You may obtain 6 | * a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | body { 18 | background: white; 19 | color: black; 20 | margin: 15px; 21 | } 22 | 23 | body, 24 | input, 25 | textarea { 26 | font-family: "Lucida Grande", Tahoma, Verdana, sans-serif; 27 | font-size: 10pt; 28 | } 29 | 30 | table { 31 | border-collapse: collapse; 32 | border: 0; 33 | } 34 | 35 | td { 36 | border: 0; 37 | padding: 0; 38 | } 39 | 40 | img { 41 | border: 0; 42 | } 43 | 44 | a { 45 | text-decoration: none; 46 | color: #3b5998; 47 | } 48 | 49 | a:hover { 50 | text-decoration: underline; 51 | } 52 | 53 | .post { 54 | border-bottom: 1px solid #eeeeee; 55 | min-height: 50px; 56 | padding-bottom: 10px; 57 | margin-top: 10px; 58 | } 59 | 60 | .post .picture { 61 | float: left; 62 | } 63 | 64 | .post .picture img { 65 | height: 50px; 66 | width: 50px; 67 | } 68 | 69 | .post .body { 70 | margin-left: 60px; 71 | } 72 | 73 | .post .media img { 74 | border: 1px solid #cccccc; 75 | padding: 3px; 76 | } 77 | 78 | .post .media:hover img { 79 | border: 1px solid #3b5998; 80 | } 81 | 82 | .post a.actor { 83 | font-weight: bold; 84 | } 85 | 86 | .post .meta { 87 | font-size: 11px; 88 | } 89 | 90 | .post a.permalink { 91 | color: #777777; 92 | } 93 | 94 | #body { 95 | max-width: 700px; 96 | margin: auto; 97 | } 98 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/facebook/static/facebook.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/better-py/annotated-py-tornado/78fa3ab3b87a559c1db9ec11d86d79f6bf47853c/src/tornado-3.2.2/demos/facebook/static/facebook.js -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/facebook/templates/modules/post.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | {% set author_url="http://www.facebook.com/profile.php?id=" + escape(post["from"]["id"]) %} 4 | 5 |
6 |
7 | {{ escape(post["from"]["name"]) }} 8 | {% if "message" in post %} 9 | {{ escape(post["message"]) }} 10 | {% end %} 11 | 16 |
17 |
18 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/facebook/templates/stream.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Tornado Facebook Stream Demo 6 | 7 | 8 | 9 |
10 |
11 | {{ escape(current_user["name"]) }} - 12 | {{ _("Sign out") }} 13 |
14 |
{{ _("Refresh stream") }}
15 |
16 | {% for post in stream["data"] %} 17 | {{ modules.Post(post) }} 18 | {% end %} 19 |
20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/helloworld/helloworld.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2009 Facebook 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | 17 | import tornado.httpserver 18 | import tornado.ioloop 19 | import tornado.options 20 | import tornado.web 21 | 22 | from tornado.options import define, options 23 | 24 | define("port", default=8888, help="run on the given port", type=int) 25 | 26 | 27 | class MainHandler(tornado.web.RequestHandler): 28 | def get(self): 29 | self.write("Hello, world") 30 | 31 | 32 | def main(): 33 | tornado.options.parse_command_line() 34 | application = tornado.web.Application([ 35 | (r"/", MainHandler), 36 | ]) 37 | http_server = tornado.httpserver.HTTPServer(application) 38 | http_server.listen(options.port) 39 | tornado.ioloop.IOLoop.instance().start() 40 | 41 | 42 | if __name__ == "__main__": 43 | main() 44 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/twitter/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Tornado Twitter Demo 4 | 5 | 6 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/websocket/static/chat.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 FriendFeed 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use this file except in compliance with the License. You may obtain 6 | * a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | body { 18 | background: white; 19 | margin: 10px; 20 | } 21 | 22 | body, 23 | input { 24 | font-family: sans-serif; 25 | font-size: 10pt; 26 | color: black; 27 | } 28 | 29 | table { 30 | border-collapse: collapse; 31 | border: 0; 32 | } 33 | 34 | td { 35 | border: 0; 36 | padding: 0; 37 | } 38 | 39 | #body { 40 | position: absolute; 41 | bottom: 10px; 42 | left: 10px; 43 | } 44 | 45 | #input { 46 | margin-top: 0.5em; 47 | } 48 | 49 | #inbox .message { 50 | padding-top: 0.25em; 51 | } 52 | 53 | #nav { 54 | float: right; 55 | z-index: 99; 56 | } 57 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/websocket/static/chat.js: -------------------------------------------------------------------------------- 1 | // Copyright 2009 FriendFeed 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | // not use this file except in compliance with the License. You may obtain 5 | // a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | // License for the specific language governing permissions and limitations 13 | // under the License. 14 | 15 | $(document).ready(function() { 16 | if (!window.console) window.console = {}; 17 | if (!window.console.log) window.console.log = function() {}; 18 | 19 | $("#messageform").live("submit", function() { 20 | newMessage($(this)); 21 | return false; 22 | }); 23 | $("#messageform").live("keypress", function(e) { 24 | if (e.keyCode == 13) { 25 | newMessage($(this)); 26 | return false; 27 | } 28 | }); 29 | $("#message").select(); 30 | updater.start(); 31 | }); 32 | 33 | function newMessage(form) { 34 | var message = form.formToDict(); 35 | updater.socket.send(JSON.stringify(message)); 36 | form.find("input[type=text]").val("").select(); 37 | } 38 | 39 | jQuery.fn.formToDict = function() { 40 | var fields = this.serializeArray(); 41 | var json = {} 42 | for (var i = 0; i < fields.length; i++) { 43 | json[fields[i].name] = fields[i].value; 44 | } 45 | if (json.next) delete json.next; 46 | return json; 47 | }; 48 | 49 | var updater = { 50 | socket: null, 51 | 52 | start: function() { 53 | var url = "ws://" + location.host + "/chatsocket"; 54 | updater.socket = new WebSocket(url); 55 | updater.socket.onmessage = function(event) { 56 | updater.showMessage(JSON.parse(event.data)); 57 | } 58 | }, 59 | 60 | showMessage: function(message) { 61 | var existing = $("#m" + message.id); 62 | if (existing.length > 0) return; 63 | var node = $(message.html); 64 | node.hide(); 65 | $("#inbox").append(node); 66 | node.slideDown(); 67 | } 68 | }; 69 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/websocket/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Tornado Chat Demo 6 | 7 | 8 | 9 |
10 |
11 | {% for message in messages %} 12 | {% include "message.html" %} 13 | {% end %} 14 |
15 |
16 |
17 | 18 | 19 | 20 | 25 | 26 |
21 | 22 | 23 | {% module xsrf_form_html() %} 24 |
27 |
28 |
29 |
30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/demos/websocket/templates/message.html: -------------------------------------------------------------------------------- 1 |
{% module linkify(message["body"]) %}
2 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/readme.md: -------------------------------------------------------------------------------- 1 | 2 | ## tornado 3.2.2 说明: 3 | 4 | 5 | ### 1. 代码打印阅读: 6 | 7 | - ioloop.py 8 | - web.py 9 | - gen.py 10 | 11 | 12 | 13 | ### 2. 相关参考阅读: 14 | 15 | - [tornado 之 ioloop模块解读](https://github.com/dragondjf/dragondjfblog/blob/master/content/tornado%20%E4%B9%8B%20ioloop%E6%A8%A1%E5%9D%97%E8%A7%A3%E8%AF%BB.md) 16 | - 依赖的库,介绍. 17 | - [tornado 源码阅读-初步认识](https://segmentfault.com/a/1190000002971992) 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/tornado/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2009 Facebook 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | 17 | """The Tornado web server and tools.""" 18 | 19 | from __future__ import absolute_import, division, print_function, with_statement 20 | 21 | # version is a human-readable version number. 22 | 23 | # version_info is a four-tuple for programmatic comparison. The first 24 | # three numbers are the components of the version number. The fourth 25 | # is zero for an official release, positive for a development branch, 26 | # or negative for a release candidate or beta (after the base version 27 | # number has been incremented) 28 | version = "3.2.2" 29 | version_info = (3, 2, 2, 0) 30 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/tornado/platform/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/better-py/annotated-py-tornado/78fa3ab3b87a559c1db9ec11d86d79f6bf47853c/src/tornado-3.2.2/tornado/platform/__init__.py -------------------------------------------------------------------------------- /src/tornado-3.2.2/tornado/platform/auto.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2011 Facebook 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | 17 | """Implementation of platform-specific functionality. 18 | 19 | For each function or class described in `tornado.platform.interface`, 20 | the appropriate platform-specific implementation exists in this module. 21 | Most code that needs access to this functionality should do e.g.:: 22 | 23 | from tornado.platform.auto import set_close_exec 24 | """ 25 | 26 | from __future__ import absolute_import, division, print_function, with_statement 27 | 28 | import os 29 | 30 | if os.name == 'nt': 31 | from tornado.platform.common import Waker 32 | from tornado.platform.windows import set_close_exec 33 | else: 34 | from tornado.platform.posix import set_close_exec, Waker 35 | 36 | try: 37 | # monotime monkey-patches the time module to have a monotonic function 38 | # in versions of python before 3.3. 39 | import monotime 40 | except ImportError: 41 | pass 42 | try: 43 | from time import monotonic as monotonic_time 44 | except ImportError: 45 | monotonic_time = None 46 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/tornado/platform/caresresolver.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import, division, print_function, with_statement 2 | import pycares 3 | import socket 4 | 5 | from tornado import gen 6 | from tornado.ioloop import IOLoop 7 | from tornado.netutil import Resolver, is_valid_ip 8 | 9 | 10 | class CaresResolver(Resolver): 11 | """Name resolver based on the c-ares library. 12 | 13 | This is a non-blocking and non-threaded resolver. It may not produce 14 | the same results as the system resolver, but can be used for non-blocking 15 | resolution when threads cannot be used. 16 | 17 | c-ares fails to resolve some names when ``family`` is ``AF_UNSPEC``, 18 | so it is only recommended for use in ``AF_INET`` (i.e. IPv4). This is 19 | the default for ``tornado.simple_httpclient``, but other libraries 20 | may default to ``AF_UNSPEC``. 21 | """ 22 | def initialize(self, io_loop=None): 23 | self.io_loop = io_loop or IOLoop.current() 24 | self.channel = pycares.Channel(sock_state_cb=self._sock_state_cb) 25 | self.fds = {} 26 | 27 | def _sock_state_cb(self, fd, readable, writable): 28 | state = ((IOLoop.READ if readable else 0) | 29 | (IOLoop.WRITE if writable else 0)) 30 | if not state: 31 | self.io_loop.remove_handler(fd) 32 | del self.fds[fd] 33 | elif fd in self.fds: 34 | self.io_loop.update_handler(fd, state) 35 | self.fds[fd] = state 36 | else: 37 | self.io_loop.add_handler(fd, self._handle_events, state) 38 | self.fds[fd] = state 39 | 40 | def _handle_events(self, fd, events): 41 | read_fd = pycares.ARES_SOCKET_BAD 42 | write_fd = pycares.ARES_SOCKET_BAD 43 | if events & IOLoop.READ: 44 | read_fd = fd 45 | if events & IOLoop.WRITE: 46 | write_fd = fd 47 | self.channel.process_fd(read_fd, write_fd) 48 | 49 | @gen.coroutine 50 | def resolve(self, host, port, family=0): 51 | if is_valid_ip(host): 52 | addresses = [host] 53 | else: 54 | # gethostbyname doesn't take callback as a kwarg 55 | self.channel.gethostbyname(host, family, (yield gen.Callback(1))) 56 | callback_args = yield gen.Wait(1) 57 | assert isinstance(callback_args, gen.Arguments) 58 | assert not callback_args.kwargs 59 | result, error = callback_args.args 60 | if error: 61 | raise Exception('C-Ares returned error %s: %s while resolving %s' % 62 | (error, pycares.errno.strerror(error), host)) 63 | addresses = result.addresses 64 | addrinfo = [] 65 | for address in addresses: 66 | if '.' in address: 67 | address_family = socket.AF_INET 68 | elif ':' in address: 69 | address_family = socket.AF_INET6 70 | else: 71 | address_family = socket.AF_UNSPEC 72 | if family != socket.AF_UNSPEC and family != address_family: 73 | raise Exception('Requested socket family %d but got %d' % 74 | (family, address_family)) 75 | addrinfo.append((address_family, (address, port))) 76 | raise gen.Return(addrinfo) 77 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/tornado/platform/epoll.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2012 Facebook 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | """EPoll-based IOLoop implementation for Linux systems.""" 17 | from __future__ import absolute_import, division, print_function, with_statement 18 | 19 | import select 20 | 21 | from tornado.ioloop import PollIOLoop 22 | 23 | 24 | class EPollIOLoop(PollIOLoop): 25 | def initialize(self, **kwargs): 26 | super(EPollIOLoop, self).initialize(impl=select.epoll(), **kwargs) 27 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/tornado/platform/interface.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2011 Facebook 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | 17 | """Interfaces for platform-specific functionality. 18 | 19 | This module exists primarily for documentation purposes and as base classes 20 | for other tornado.platform modules. Most code should import the appropriate 21 | implementation from `tornado.platform.auto`. 22 | """ 23 | 24 | from __future__ import absolute_import, division, print_function, with_statement 25 | 26 | 27 | def set_close_exec(fd): 28 | """Sets the close-on-exec bit (``FD_CLOEXEC``)for a file descriptor.""" 29 | raise NotImplementedError() 30 | 31 | 32 | class Waker(object): 33 | """A socket-like object that can wake another thread from ``select()``. 34 | 35 | The `~tornado.ioloop.IOLoop` will add the Waker's `fileno()` to 36 | its ``select`` (or ``epoll`` or ``kqueue``) calls. When another 37 | thread wants to wake up the loop, it calls `wake`. Once it has woken 38 | up, it will call `consume` to do any necessary per-wake cleanup. When 39 | the ``IOLoop`` is closed, it closes its waker too. 40 | """ 41 | def fileno(self): 42 | """Returns the read file descriptor for this waker. 43 | 44 | Must be suitable for use with ``select()`` or equivalent on the 45 | local platform. 46 | """ 47 | raise NotImplementedError() 48 | 49 | def write_fileno(self): 50 | """Returns the write file descriptor for this waker.""" 51 | raise NotImplementedError() 52 | 53 | def wake(self): 54 | """Triggers activity on the waker's file descriptor.""" 55 | raise NotImplementedError() 56 | 57 | def consume(self): 58 | """Called after the listen has woken up to do any necessary cleanup.""" 59 | raise NotImplementedError() 60 | 61 | def close(self): 62 | """Closes the waker's file descriptor(s).""" 63 | raise NotImplementedError() 64 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/tornado/platform/posix.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2011 Facebook 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | 17 | """Posix implementations of platform-specific functionality.""" 18 | 19 | from __future__ import absolute_import, division, print_function, with_statement 20 | 21 | import fcntl 22 | import os 23 | 24 | from tornado.platform import interface 25 | 26 | 27 | def set_close_exec(fd): 28 | flags = fcntl.fcntl(fd, fcntl.F_GETFD) 29 | fcntl.fcntl(fd, fcntl.F_SETFD, flags | fcntl.FD_CLOEXEC) 30 | 31 | 32 | def _set_nonblocking(fd): 33 | flags = fcntl.fcntl(fd, fcntl.F_GETFL) 34 | fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK) 35 | 36 | 37 | class Waker(interface.Waker): 38 | def __init__(self): 39 | r, w = os.pipe() 40 | _set_nonblocking(r) 41 | _set_nonblocking(w) 42 | set_close_exec(r) 43 | set_close_exec(w) 44 | self.reader = os.fdopen(r, "rb", 0) 45 | self.writer = os.fdopen(w, "wb", 0) 46 | 47 | def fileno(self): 48 | return self.reader.fileno() 49 | 50 | def write_fileno(self): 51 | return self.writer.fileno() 52 | 53 | def wake(self): 54 | try: 55 | self.writer.write(b"x") 56 | except IOError: 57 | pass 58 | 59 | def consume(self): 60 | try: 61 | while True: 62 | result = self.reader.read() 63 | if not result: 64 | break 65 | except IOError: 66 | pass 67 | 68 | def close(self): 69 | self.reader.close() 70 | self.writer.close() 71 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/tornado/platform/select.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2012 Facebook 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | """Select-based IOLoop implementation. 17 | 18 | Used as a fallback for systems that don't support epoll or kqueue. 19 | """ 20 | from __future__ import absolute_import, division, print_function, with_statement 21 | 22 | import select 23 | 24 | from tornado.ioloop import IOLoop, PollIOLoop 25 | 26 | 27 | class _Select(object): 28 | """A simple, select()-based IOLoop implementation for non-Linux systems""" 29 | def __init__(self): 30 | self.read_fds = set() 31 | self.write_fds = set() 32 | self.error_fds = set() 33 | self.fd_sets = (self.read_fds, self.write_fds, self.error_fds) 34 | 35 | def close(self): 36 | pass 37 | 38 | def register(self, fd, events): 39 | if fd in self.read_fds or fd in self.write_fds or fd in self.error_fds: 40 | raise IOError("fd %d already registered" % fd) 41 | if events & IOLoop.READ: 42 | self.read_fds.add(fd) 43 | if events & IOLoop.WRITE: 44 | self.write_fds.add(fd) 45 | if events & IOLoop.ERROR: 46 | self.error_fds.add(fd) 47 | # Closed connections are reported as errors by epoll and kqueue, 48 | # but as zero-byte reads by select, so when errors are requested 49 | # we need to listen for both read and error. 50 | self.read_fds.add(fd) 51 | 52 | def modify(self, fd, events): 53 | self.unregister(fd) 54 | self.register(fd, events) 55 | 56 | def unregister(self, fd): 57 | self.read_fds.discard(fd) 58 | self.write_fds.discard(fd) 59 | self.error_fds.discard(fd) 60 | 61 | def poll(self, timeout): 62 | readable, writeable, errors = select.select( 63 | self.read_fds, self.write_fds, self.error_fds, timeout) 64 | events = {} 65 | for fd in readable: 66 | events[fd] = events.get(fd, 0) | IOLoop.READ 67 | for fd in writeable: 68 | events[fd] = events.get(fd, 0) | IOLoop.WRITE 69 | for fd in errors: 70 | events[fd] = events.get(fd, 0) | IOLoop.ERROR 71 | return events.items() 72 | 73 | 74 | class SelectIOLoop(PollIOLoop): 75 | def initialize(self, **kwargs): 76 | super(SelectIOLoop, self).initialize(impl=_Select(), **kwargs) 77 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/tornado/platform/windows.py: -------------------------------------------------------------------------------- 1 | # NOTE: win32 support is currently experimental, and not recommended 2 | # for production use. 3 | 4 | 5 | from __future__ import absolute_import, division, print_function, with_statement 6 | import ctypes 7 | import ctypes.wintypes 8 | 9 | # See: http://msdn.microsoft.com/en-us/library/ms724935(VS.85).aspx 10 | SetHandleInformation = ctypes.windll.kernel32.SetHandleInformation 11 | SetHandleInformation.argtypes = (ctypes.wintypes.HANDLE, ctypes.wintypes.DWORD, ctypes.wintypes.DWORD) 12 | SetHandleInformation.restype = ctypes.wintypes.BOOL 13 | 14 | HANDLE_FLAG_INHERIT = 0x00000001 15 | 16 | 17 | def set_close_exec(fd): 18 | success = SetHandleInformation(fd, HANDLE_FLAG_INHERIT, 0) 19 | if not success: 20 | raise ctypes.GetLastError() 21 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/tornado/speedups.c: -------------------------------------------------------------------------------- 1 | #define PY_SSIZE_T_CLEAN 2 | #include 3 | 4 | static PyObject* websocket_mask(PyObject* self, PyObject* args) { 5 | const char* mask; 6 | Py_ssize_t mask_len; 7 | const char* data; 8 | Py_ssize_t data_len; 9 | Py_ssize_t i; 10 | PyObject* result; 11 | char* buf; 12 | 13 | if (!PyArg_ParseTuple(args, "s#s#", &mask, &mask_len, &data, &data_len)) { 14 | return NULL; 15 | } 16 | 17 | result = PyBytes_FromStringAndSize(NULL, data_len); 18 | if (!result) { 19 | return NULL; 20 | } 21 | buf = PyBytes_AsString(result); 22 | for (i = 0; i < data_len; i++) { 23 | buf[i] = data[i] ^ mask[i % 4]; 24 | } 25 | 26 | return result; 27 | } 28 | 29 | static PyMethodDef methods[] = { 30 | {"websocket_mask", websocket_mask, METH_VARARGS, ""}, 31 | {NULL, NULL, 0, NULL} 32 | }; 33 | 34 | #if PY_MAJOR_VERSION >= 3 35 | static struct PyModuleDef speedupsmodule = { 36 | PyModuleDef_HEAD_INIT, 37 | "speedups", 38 | NULL, 39 | -1, 40 | methods 41 | }; 42 | 43 | PyMODINIT_FUNC 44 | PyInit_speedups() { 45 | return PyModule_Create(&speedupsmodule); 46 | } 47 | #else // Python 2.x 48 | PyMODINIT_FUNC 49 | initspeedups() { 50 | Py_InitModule("tornado.speedups", methods); 51 | } 52 | #endif 53 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/tornado/test/README: -------------------------------------------------------------------------------- 1 | Test coverage is almost non-existent, but it's a start. Be sure to 2 | set PYTHONPATH apprioriately (generally to the root directory of your 3 | tornado checkout) when running tests to make sure you're getting the 4 | version of the tornado package that you expect. -------------------------------------------------------------------------------- /src/tornado-3.2.2/tornado/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/better-py/annotated-py-tornado/78fa3ab3b87a559c1db9ec11d86d79f6bf47853c/src/tornado-3.2.2/tornado/test/__init__.py -------------------------------------------------------------------------------- /src/tornado-3.2.2/tornado/test/csv_translations/fr_FR.csv: -------------------------------------------------------------------------------- 1 | "school","école" 2 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/tornado/test/gettext_translations/extract_me.py: -------------------------------------------------------------------------------- 1 | # Dummy source file to allow creation of the initial .po file in the 2 | # same way as a real project. I'm not entirely sure about the real 3 | # workflow here, but this seems to work. 4 | # 5 | # 1) xgettext --language=Python --keyword=_:1,2 -d tornado_test extract_me.py -o tornado_test.po 6 | # 2) Edit tornado_test.po, setting CHARSET and setting msgstr 7 | # 3) msgfmt tornado_test.po -o tornado_test.mo 8 | # 4) Put the file in the proper location: $LANG/LC_MESSAGES 9 | 10 | from __future__ import absolute_import, division, print_function, with_statement 11 | _("school") 12 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/tornado/test/gettext_translations/fr_FR/LC_MESSAGES/tornado_test.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: PACKAGE VERSION\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2012-06-14 01:10-0700\n" 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 13 | "Last-Translator: FULL NAME \n" 14 | "Language-Team: LANGUAGE \n" 15 | "Language: \n" 16 | "MIME-Version: 1.0\n" 17 | "Content-Type: text/plain; charset=utf-8\n" 18 | "Content-Transfer-Encoding: 8bit\n" 19 | 20 | #: extract_me.py:1 21 | msgid "school" 22 | msgstr "école" 23 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/tornado/test/import_test.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import, division, print_function, with_statement 2 | from tornado.test.util import unittest 3 | 4 | 5 | class ImportTest(unittest.TestCase): 6 | def test_import_everything(self): 7 | # Some of our modules are not otherwise tested. Import them 8 | # all (unless they have external dependencies) here to at 9 | # least ensure that there are no syntax errors. 10 | import tornado.auth 11 | import tornado.autoreload 12 | import tornado.concurrent 13 | # import tornado.curl_httpclient # depends on pycurl 14 | import tornado.escape 15 | import tornado.gen 16 | import tornado.httpclient 17 | import tornado.httpserver 18 | import tornado.httputil 19 | import tornado.ioloop 20 | import tornado.iostream 21 | import tornado.locale 22 | import tornado.log 23 | import tornado.netutil 24 | import tornado.options 25 | import tornado.process 26 | import tornado.simple_httpclient 27 | import tornado.stack_context 28 | import tornado.tcpserver 29 | import tornado.template 30 | import tornado.testing 31 | import tornado.util 32 | import tornado.web 33 | import tornado.websocket 34 | import tornado.wsgi 35 | 36 | # for modules with dependencies, if those dependencies can be loaded, 37 | # load them too. 38 | 39 | def test_import_pycurl(self): 40 | try: 41 | import pycurl 42 | except ImportError: 43 | pass 44 | else: 45 | import tornado.curl_httpclient 46 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/tornado/test/locale_test.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import, division, print_function, with_statement 2 | 3 | import datetime 4 | import os 5 | import tornado.locale 6 | from tornado.escape import utf8 7 | from tornado.test.util import unittest 8 | from tornado.util import u, unicode_type 9 | 10 | 11 | class TranslationLoaderTest(unittest.TestCase): 12 | # TODO: less hacky way to get isolated tests 13 | SAVE_VARS = ['_translations', '_supported_locales', '_use_gettext'] 14 | 15 | def clear_locale_cache(self): 16 | if hasattr(tornado.locale.Locale, '_cache'): 17 | del tornado.locale.Locale._cache 18 | 19 | def setUp(self): 20 | self.saved = {} 21 | for var in TranslationLoaderTest.SAVE_VARS: 22 | self.saved[var] = getattr(tornado.locale, var) 23 | self.clear_locale_cache() 24 | 25 | def tearDown(self): 26 | for k, v in self.saved.items(): 27 | setattr(tornado.locale, k, v) 28 | self.clear_locale_cache() 29 | 30 | def test_csv(self): 31 | tornado.locale.load_translations( 32 | os.path.join(os.path.dirname(__file__), 'csv_translations')) 33 | locale = tornado.locale.get("fr_FR") 34 | self.assertTrue(isinstance(locale, tornado.locale.CSVLocale)) 35 | self.assertEqual(locale.translate("school"), u("\u00e9cole")) 36 | 37 | def test_gettext(self): 38 | tornado.locale.load_gettext_translations( 39 | os.path.join(os.path.dirname(__file__), 'gettext_translations'), 40 | "tornado_test") 41 | locale = tornado.locale.get("fr_FR") 42 | self.assertTrue(isinstance(locale, tornado.locale.GettextLocale)) 43 | self.assertEqual(locale.translate("school"), u("\u00e9cole")) 44 | 45 | 46 | class LocaleDataTest(unittest.TestCase): 47 | def test_non_ascii_name(self): 48 | name = tornado.locale.LOCALE_NAMES['es_LA']['name'] 49 | self.assertTrue(isinstance(name, unicode_type)) 50 | self.assertEqual(name, u('Espa\u00f1ol')) 51 | self.assertEqual(utf8(name), b'Espa\xc3\xb1ol') 52 | 53 | 54 | class EnglishTest(unittest.TestCase): 55 | def test_format_date(self): 56 | locale = tornado.locale.get('en_US') 57 | date = datetime.datetime(2013, 4, 28, 18, 35) 58 | self.assertEqual(locale.format_date(date, full_format=True), 59 | 'April 28, 2013 at 6:35 pm') 60 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/tornado/test/options_test.cfg: -------------------------------------------------------------------------------- 1 | port=443 2 | port=443 -------------------------------------------------------------------------------- /src/tornado-3.2.2/tornado/test/resolve_test_helper.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import, division, print_function, with_statement 2 | from tornado.ioloop import IOLoop 3 | from tornado.netutil import ThreadedResolver 4 | from tornado.util import u 5 | 6 | # When this module is imported, it runs getaddrinfo on a thread. Since 7 | # the hostname is unicode, getaddrinfo attempts to import encodings.idna 8 | # but blocks on the import lock. Verify that ThreadedResolver avoids 9 | # this deadlock. 10 | 11 | resolver = ThreadedResolver() 12 | IOLoop.current().run_sync(lambda: resolver.resolve(u('localhost'), 80)) 13 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/tornado/test/static/dir/index.html: -------------------------------------------------------------------------------- 1 | this is the index 2 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/tornado/test/static/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: / 3 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/tornado/test/templates/utf8.html: -------------------------------------------------------------------------------- 1 | Héllo 2 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/tornado/test/test.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICSDCCAbGgAwIBAgIJAN1oTowzMbkzMA0GCSqGSIb3DQEBBQUAMD0xCzAJBgNV 3 | BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRkwFwYDVQQKDBBUb3JuYWRvIFdl 4 | YiBUZXN0MB4XDTEwMDgyNTE4MjQ0NFoXDTIwMDgyMjE4MjQ0NFowPTELMAkGA1UE 5 | BhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExGTAXBgNVBAoMEFRvcm5hZG8gV2Vi 6 | IFRlc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALirW3mX4jbdFse2aZwW 7 | zszCJ1IsRDrzALpbvMYLLbIZqo+Z8v5aERKTRQpXFqGaZyY+tdwYy7X7YXcLtKqv 8 | jnw/MSeIaqkw5pROKz5aR0nkPLvcTmhJVLVPCLc8dFnIlu8aC9TrDhr90P+PzU39 9 | UG7zLweA9zXKBuW3Tjo5dMP3AgMBAAGjUDBOMB0GA1UdDgQWBBRhJjMBYrzddCFr 10 | /0vvPyHMeqgo0TAfBgNVHSMEGDAWgBRhJjMBYrzddCFr/0vvPyHMeqgo0TAMBgNV 11 | HRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAGP6GaxSfb21bikcqaK3ZKCC1sRJ 12 | tiCuvJZbBUFUCAzl05dYUfJZim/oWK+GqyUkUB8ciYivUNnn9OtS7DnlTgT2ws2e 13 | lNgn5cuFXoAGcHXzVlHG3yoywYBf3y0Dn20uzrlLXUWJAzoSLOt2LTaXvwlgm7hF 14 | W1q8SQ6UBshRw2X0 15 | -----END CERTIFICATE----- 16 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/tornado/test/test.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBALirW3mX4jbdFse2 3 | aZwWzszCJ1IsRDrzALpbvMYLLbIZqo+Z8v5aERKTRQpXFqGaZyY+tdwYy7X7YXcL 4 | tKqvjnw/MSeIaqkw5pROKz5aR0nkPLvcTmhJVLVPCLc8dFnIlu8aC9TrDhr90P+P 5 | zU39UG7zLweA9zXKBuW3Tjo5dMP3AgMBAAECgYEAiygNaWYrf95AcUQi9w00zpUr 6 | nj9fNvCwxr2kVbRMvd2balS/CC4EmXPCXdVcZ3B7dBVjYzSIJV0Fh/iZLtnVysD9 7 | fcNMZ+Cz71b/T0ItsNYOsJk0qUVyP52uqsqkNppIPJsD19C+ZeMLZj6iEiylZyl8 8 | 2U16c/kVIjER63mUEGkCQQDayQOTGPJrKHqPAkUqzeJkfvHH2yCf+cySU+w6ezyr 9 | j9yxcq8aZoLusCebDVT+kz7RqnD5JePFvB38cMuepYBLAkEA2BTFdZx30f4moPNv 10 | JlXlPNJMUTUzsXG7n4vNc+18O5ous0NGQII8jZWrIcTrP8wiP9fF3JwUsKrJhcBn 11 | xRs3hQJBAIDUgz1YIE+HW3vgi1gkOh6RPdBAsVpiXtr/fggFz3j60qrO7FswaAMj 12 | SX8c/6KUlBYkNjgP3qruFf4zcUNvEzcCQQCaioCPFVE9ByBpjLG6IUTKsz2R9xL5 13 | nfYqrbpLZ1aq6iLsYvkjugHE4X57sHLwNfdo4dHJbnf9wqhO2MVe25BhAkBdKYpY 14 | 7OKc/2mmMbJDhVBgoixz/muN/5VjdfbvVY48naZkJF1p1tmogqPC5F1jPCS4rM+S 15 | FfPJIHRNEn2oktw5 16 | -----END PRIVATE KEY----- 17 | -------------------------------------------------------------------------------- /src/tornado-3.2.2/tornado/test/util.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import, division, print_function, with_statement 2 | 3 | import os 4 | import sys 5 | 6 | # Encapsulate the choice of unittest or unittest2 here. 7 | # To be used as 'from tornado.test.util import unittest'. 8 | if sys.version_info >= (2, 7): 9 | import unittest 10 | else: 11 | import unittest2 as unittest 12 | 13 | skipIfNonUnix = unittest.skipIf(os.name != 'posix' or sys.platform == 'cygwin', 14 | "non-unix platform") 15 | 16 | # travis-ci.org runs our tests in an overworked virtual machine, which makes 17 | # timing-related tests unreliable. 18 | skipOnTravis = unittest.skipIf('TRAVIS' in os.environ, 19 | 'timing tests unreliable on travis') 20 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/.coveragerc: -------------------------------------------------------------------------------- 1 | # Test coverage configuration. 2 | # Usage: 3 | # pip install coverage 4 | # coverage erase # clears previous data if any 5 | # coverage run -m tornado.test.runtests 6 | # coverage report # prints to stdout 7 | # coverage html # creates ./htmlcov/*.html including annotated source 8 | [run] 9 | branch = true 10 | source = tornado 11 | omit = 12 | tornado/platform/* 13 | tornado/test/* 14 | */_auto2to3* 15 | 16 | [report] 17 | # Ignore missing source files, i.e. fake template-generated "files" 18 | ignore_errors = true 19 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/MANIFEST.in: -------------------------------------------------------------------------------- 1 | recursive-include demos *.py *.yaml *.html *.css *.js *.xml *.sql README 2 | recursive-include docs * 3 | prune docs/build 4 | include tornado/speedups.c 5 | include tornado/test/README 6 | include tornado/test/csv_translations/fr_FR.csv 7 | include tornado/test/gettext_translations/fr_FR/LC_MESSAGES/tornado_test.mo 8 | include tornado/test/gettext_translations/fr_FR/LC_MESSAGES/tornado_test.po 9 | include tornado/test/options_test.cfg 10 | include tornado/test/static/robots.txt 11 | include tornado/test/static/dir/index.html 12 | include tornado/test/templates/utf8.html 13 | include tornado/test/test.crt 14 | include tornado/test/test.key 15 | include README.rst 16 | include runtests.sh 17 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/appengine/README: -------------------------------------------------------------------------------- 1 | Running the Tornado AppEngine example 2 | ===================================== 3 | This example is designed to run in Google AppEngine, so there are a couple 4 | of steps to get it running. You can download the Google AppEngine Python 5 | development environment at http://code.google.com/appengine/downloads.html. 6 | 7 | 1. Link or copy the tornado code directory into this directory: 8 | 9 | ln -s ../../tornado tornado 10 | 11 | AppEngine doesn't use the Python modules installed on this machine. 12 | You need to have the 'tornado' module copied or linked for AppEngine 13 | to find it. 14 | 15 | 3. Install and run dev_appserver 16 | 17 | If you don't already have the App Engine SDK, download it from 18 | http://code.google.com/appengine/downloads.html 19 | 20 | To start the tornado demo, run the dev server on this directory: 21 | 22 | dev_appserver.py . 23 | 24 | 4. Visit http://localhost:8080/ in your browser 25 | 26 | If you sign in as an administrator, you will be able to create and 27 | edit blog posts. If you sign in as anybody else, you will only see 28 | the existing blog posts. 29 | 30 | 31 | If you want to deploy the blog in production: 32 | 33 | 1. Register a new appengine application and put its id in app.yaml 34 | 35 | First register a new application at http://appengine.google.com/. 36 | Then edit app.yaml in this directory and change the "application" 37 | setting from "tornado-appenginge" to your new application id. 38 | 39 | 2. Deploy to App Engine 40 | 41 | If you registered an application id, you can now upload your new 42 | Tornado blog by running this command: 43 | 44 | appcfg update . 45 | 46 | After that, visit application_id.appspot.com, where application_id 47 | is the application you registered. 48 | 49 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/appengine/app.yaml: -------------------------------------------------------------------------------- 1 | application: tornado-appengine 2 | version: 2 3 | runtime: python27 4 | api_version: 1 5 | threadsafe: yes 6 | 7 | handlers: 8 | - url: /static/ 9 | static_dir: static 10 | 11 | - url: /.* 12 | script: blog.application 13 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/appengine/static/blog.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 Facebook 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use this file except in compliance with the License. You may obtain 6 | * a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | body { 18 | background: white; 19 | color: black; 20 | margin: 15px; 21 | margin-top: 0; 22 | } 23 | 24 | body, 25 | input, 26 | textarea { 27 | font-family: Georgia, serif; 28 | font-size: 12pt; 29 | } 30 | 31 | table { 32 | border-collapse: collapse; 33 | border: 0; 34 | } 35 | 36 | td { 37 | border: 0; 38 | padding: 0; 39 | } 40 | 41 | h1, 42 | h2, 43 | h3, 44 | h4 { 45 | font-family: "Helvetica Nue", Helvetica, Arial, sans-serif; 46 | margin: 0; 47 | } 48 | 49 | h1 { 50 | font-size: 20pt; 51 | } 52 | 53 | pre, 54 | code { 55 | font-family: monospace; 56 | color: #060; 57 | } 58 | 59 | pre { 60 | margin-left: 1em; 61 | padding-left: 1em; 62 | border-left: 1px solid silver; 63 | line-height: 14pt; 64 | } 65 | 66 | a, 67 | a code { 68 | color: #00c; 69 | } 70 | 71 | #body { 72 | max-width: 800px; 73 | margin: auto; 74 | } 75 | 76 | #header { 77 | background-color: #3b5998; 78 | padding: 5px; 79 | padding-left: 10px; 80 | padding-right: 10px; 81 | margin-bottom: 1em; 82 | } 83 | 84 | #header, 85 | #header a { 86 | color: white; 87 | } 88 | 89 | #header h1 a { 90 | text-decoration: none; 91 | } 92 | 93 | #footer, 94 | #content { 95 | margin-left: 10px; 96 | margin-right: 10px; 97 | } 98 | 99 | #footer { 100 | margin-top: 3em; 101 | } 102 | 103 | .entry h1 a { 104 | color: black; 105 | text-decoration: none; 106 | } 107 | 108 | .entry { 109 | margin-bottom: 2em; 110 | } 111 | 112 | .entry .date { 113 | margin-top: 3px; 114 | } 115 | 116 | .entry p { 117 | margin: 0; 118 | margin-bottom: 1em; 119 | } 120 | 121 | .entry .body { 122 | margin-top: 1em; 123 | line-height: 16pt; 124 | } 125 | 126 | .compose td { 127 | vertical-align: middle; 128 | padding-bottom: 5px; 129 | } 130 | 131 | .compose td.field { 132 | padding-right: 10px; 133 | } 134 | 135 | .compose .title, 136 | .compose .submit { 137 | font-family: "Helvetica Nue", Helvetica, Arial, sans-serif; 138 | font-weight: bold; 139 | } 140 | 141 | .compose .title { 142 | font-size: 20pt; 143 | } 144 | 145 | .compose .title, 146 | .compose .body_source { 147 | width: 100%; 148 | } 149 | 150 | .compose .body_source { 151 | height: 500px; 152 | line-height: 16pt; 153 | } 154 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/appengine/templates/archive.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block head %} 4 | 20 | {% end %} 21 | 22 | {% block body %} 23 |
    24 | {% for entry in entries %} 25 |
  • 26 | 27 |
    {{ locale.format_date(entry.published, full_format=True, shorter=True) }}
    28 |
  • 29 | {% end %} 30 |
31 | {% end %} 32 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/appengine/templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{ handler.settings["blog_title"] }} 6 | 7 | 8 | {% block head %}{% end %} 9 | 10 | 11 |
12 | 25 |
{% block body %}{% end %}
26 |
27 | {% block bottom %}{% end %} 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/appengine/templates/compose.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block body %} 4 |
5 |
6 |
7 |
8 | 9 |  {{ _("Cancel") }} 10 |
11 | {% if entry %} 12 | 13 | {% end %} 14 | {% module xsrf_form_html() %} 15 |
16 | {% end %} 17 | 18 | {% block bottom %} 19 | 20 | 40 | {% end %} 41 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/appengine/templates/entry.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block body %} 4 | {% module Entry(entry) %} 5 | {% end %} 6 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/appengine/templates/feed.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | {% set date_format = "%Y-%m-%dT%H:%M:%SZ" %} 4 | {{ handler.settings["blog_title"] }} 5 | {% if len(entries) > 0 %} 6 | {{ max(e.updated for e in entries).strftime(date_format) }} 7 | {% else %} 8 | {{ datetime.datetime.utcnow().strftime(date_format) }} 9 | {% end %} 10 | http://{{ request.host }}/ 11 | 12 | 13 | {{ handler.settings["blog_title"] }} 14 | {% for entry in entries %} 15 | 16 | http://{{ request.host }}/entry/{{ entry.slug }} 17 | {{ entry.title }} 18 | 19 | {{ entry.updated.strftime(date_format) }} 20 | {{ entry.published.strftime(date_format) }} 21 | 22 |
{% raw entry.html %}
23 |
24 |
25 | {% end %} 26 |
27 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/appengine/templates/home.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block body %} 4 | {% for entry in entries %} 5 | {% module Entry(entry) %} 6 | {% end %} 7 |
{{ _("Archive") }}
8 | {% end %} 9 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/appengine/templates/modules/entry.html: -------------------------------------------------------------------------------- 1 |
2 |

{{ entry.title }}

3 |
{{ locale.format_date(entry.published, full_format=True, shorter=True) }}
4 |
{% raw entry.html %}
5 | {% if current_user and current_user.administrator %} 6 | 7 | {% end %} 8 |
9 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/benchmark/benchmark.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # A simple benchmark of tornado's HTTP stack. 4 | # Requires 'ab' to be installed. 5 | # 6 | # Running without profiling: 7 | # demos/benchmark/benchmark.py 8 | # demos/benchmark/benchmark.py --quiet --num_runs=5|grep "Requests per second" 9 | # 10 | # Running with profiling: 11 | # 12 | # python -m cProfile -o /tmp/prof demos/benchmark/benchmark.py 13 | # python -m pstats /tmp/prof 14 | # % sort time 15 | # % stats 20 16 | 17 | from tornado.ioloop import IOLoop 18 | from tornado.options import define, options, parse_command_line 19 | from tornado.web import RequestHandler, Application 20 | 21 | import random 22 | import signal 23 | import subprocess 24 | 25 | try: 26 | xrange 27 | except NameError: 28 | xrange = range 29 | 30 | # choose a random port to avoid colliding with TIME_WAIT sockets left over 31 | # from previous runs. 32 | define("min_port", type=int, default=8000) 33 | define("max_port", type=int, default=9000) 34 | 35 | # Increasing --n without --keepalive will eventually run into problems 36 | # due to TIME_WAIT sockets 37 | define("n", type=int, default=15000) 38 | define("c", type=int, default=25) 39 | define("keepalive", type=bool, default=False) 40 | define("quiet", type=bool, default=False) 41 | 42 | # Repeat the entire benchmark this many times (on different ports) 43 | # This gives JITs time to warm up, etc. Pypy needs 3-5 runs at 44 | # --n=15000 for its JIT to reach full effectiveness 45 | define("num_runs", type=int, default=1) 46 | 47 | define("ioloop", type=str, default=None) 48 | 49 | class RootHandler(RequestHandler): 50 | def get(self): 51 | self.write("Hello, world") 52 | 53 | def _log(self): 54 | pass 55 | 56 | def handle_sigchld(sig, frame): 57 | IOLoop.instance().add_callback_from_signal(IOLoop.instance().stop) 58 | 59 | def main(): 60 | parse_command_line() 61 | if options.ioloop: 62 | IOLoop.configure(options.ioloop) 63 | for i in xrange(options.num_runs): 64 | run() 65 | 66 | def run(): 67 | app = Application([("/", RootHandler)]) 68 | port = random.randrange(options.min_port, options.max_port) 69 | app.listen(port, address='127.0.0.1') 70 | signal.signal(signal.SIGCHLD, handle_sigchld) 71 | args = ["ab"] 72 | args.extend(["-n", str(options.n)]) 73 | args.extend(["-c", str(options.c)]) 74 | if options.keepalive: 75 | args.append("-k") 76 | if options.quiet: 77 | # just stops the progress messages printed to stderr 78 | args.append("-q") 79 | args.append("http://127.0.0.1:%d/" % port) 80 | subprocess.Popen(args) 81 | IOLoop.instance().start() 82 | IOLoop.instance().close() 83 | del IOLoop._instance 84 | assert not IOLoop.initialized() 85 | 86 | if __name__ == '__main__': 87 | main() 88 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/benchmark/chunk_benchmark.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Downloads a large file in chunked encoding with both curl and simple clients 4 | 5 | import logging 6 | from tornado.curl_httpclient import CurlAsyncHTTPClient 7 | from tornado.simple_httpclient import SimpleAsyncHTTPClient 8 | from tornado.ioloop import IOLoop 9 | from tornado.options import define, options, parse_command_line 10 | from tornado.web import RequestHandler, Application 11 | 12 | define('port', default=8888) 13 | define('num_chunks', default=1000) 14 | define('chunk_size', default=2048) 15 | 16 | 17 | class ChunkHandler(RequestHandler): 18 | def get(self): 19 | for i in xrange(options.num_chunks): 20 | self.write('A' * options.chunk_size) 21 | self.flush() 22 | self.finish() 23 | 24 | 25 | def main(): 26 | parse_command_line() 27 | app = Application([('/', ChunkHandler)]) 28 | app.listen(options.port, address='127.0.0.1') 29 | 30 | def callback(response): 31 | response.rethrow() 32 | assert len(response.body) == (options.num_chunks * options.chunk_size) 33 | logging.warning("fetch completed in %s seconds", response.request_time) 34 | IOLoop.current().stop() 35 | 36 | logging.warning("Starting fetch with curl client") 37 | curl_client = CurlAsyncHTTPClient() 38 | curl_client.fetch('http://localhost:%d/' % options.port, 39 | callback=callback) 40 | IOLoop.current().start() 41 | 42 | logging.warning("Starting fetch with simple client") 43 | simple_client = SimpleAsyncHTTPClient() 44 | simple_client.fetch('http://localhost:%d/' % options.port, 45 | callback=callback) 46 | IOLoop.current().start() 47 | 48 | 49 | if __name__ == '__main__': 50 | main() 51 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/benchmark/gen_benchmark.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # A simple benchmark of the tornado.gen module. 4 | # Runs in two modes, testing new-style (@coroutine and Futures) 5 | # and old-style (@engine and Tasks) coroutines. 6 | 7 | from timeit import Timer 8 | 9 | from tornado import gen 10 | from tornado.options import options, define, parse_command_line 11 | 12 | define('num', default=10000, help='number of iterations') 13 | 14 | # These benchmarks are delicate. They hit various fast-paths in the gen 15 | # machinery in order to stay synchronous so we don't need an IOLoop. 16 | # This removes noise from the results, but it's easy to change things 17 | # in a way that completely invalidates the results. 18 | 19 | @gen.engine 20 | def e2(callback): 21 | callback() 22 | 23 | @gen.engine 24 | def e1(): 25 | for i in range(10): 26 | yield gen.Task(e2) 27 | 28 | @gen.coroutine 29 | def c2(): 30 | pass 31 | 32 | @gen.coroutine 33 | def c1(): 34 | for i in range(10): 35 | yield c2() 36 | 37 | def main(): 38 | parse_command_line() 39 | t = Timer(e1) 40 | results = t.timeit(options.num) / options.num 41 | print('engine: %0.3f ms per iteration' % (results * 1000)) 42 | t = Timer(c1) 43 | results = t.timeit(options.num) / options.num 44 | print('coroutine: %0.3f ms per iteration' % (results * 1000)) 45 | 46 | if __name__ == '__main__': 47 | main() 48 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/benchmark/stack_context_benchmark.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Benchmark for stack_context functionality.""" 3 | import collections 4 | import contextlib 5 | import functools 6 | import subprocess 7 | import sys 8 | 9 | from tornado import stack_context 10 | 11 | class Benchmark(object): 12 | def enter_exit(self, count): 13 | """Measures the overhead of the nested "with" statements 14 | when using many contexts. 15 | """ 16 | if count < 0: 17 | return 18 | with self.make_context(): 19 | self.enter_exit(count - 1) 20 | 21 | def call_wrapped(self, count): 22 | """Wraps and calls a function at each level of stack depth 23 | to measure the overhead of the wrapped function. 24 | """ 25 | # This queue is analogous to IOLoop.add_callback, but lets us 26 | # benchmark the stack_context in isolation without system call 27 | # overhead. 28 | queue = collections.deque() 29 | self.call_wrapped_inner(queue, count) 30 | while queue: 31 | queue.popleft()() 32 | 33 | def call_wrapped_inner(self, queue, count): 34 | if count < 0: 35 | return 36 | with self.make_context(): 37 | queue.append(stack_context.wrap( 38 | functools.partial(self.call_wrapped_inner, queue, count - 1))) 39 | 40 | class StackBenchmark(Benchmark): 41 | def make_context(self): 42 | return stack_context.StackContext(self.__context) 43 | 44 | @contextlib.contextmanager 45 | def __context(self): 46 | yield 47 | 48 | class ExceptionBenchmark(Benchmark): 49 | def make_context(self): 50 | return stack_context.ExceptionStackContext(self.__handle_exception) 51 | 52 | def __handle_exception(self, typ, value, tb): 53 | pass 54 | 55 | def main(): 56 | base_cmd = [ 57 | sys.executable, '-m', 'timeit', '-s', 58 | 'from stack_context_benchmark import StackBenchmark, ExceptionBenchmark'] 59 | cmds = [ 60 | 'StackBenchmark().enter_exit(50)', 61 | 'StackBenchmark().call_wrapped(50)', 62 | 'StackBenchmark().enter_exit(500)', 63 | 'StackBenchmark().call_wrapped(500)', 64 | 65 | 'ExceptionBenchmark().enter_exit(50)', 66 | 'ExceptionBenchmark().call_wrapped(50)', 67 | 'ExceptionBenchmark().enter_exit(500)', 68 | 'ExceptionBenchmark().call_wrapped(500)', 69 | ] 70 | for cmd in cmds: 71 | print(cmd) 72 | subprocess.check_call(base_cmd + [cmd]) 73 | 74 | if __name__ == '__main__': 75 | main() 76 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/benchmark/template_benchmark.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # A simple benchmark of tornado template rendering, based on 4 | # https://github.com/mitsuhiko/jinja2/blob/master/examples/bench.py 5 | 6 | import sys 7 | from timeit import Timer 8 | 9 | from tornado.options import options, define, parse_command_line 10 | from tornado.template import Template 11 | 12 | define('num', default=100, help='number of iterations') 13 | define('dump', default=False, help='print template generated code and exit') 14 | 15 | context = { 16 | 'page_title': 'mitsuhiko\'s benchmark', 17 | 'table': [dict(a=1,b=2,c=3,d=4,e=5,f=6,g=7,h=8,i=9,j=10) for x in range(1000)] 18 | } 19 | 20 | tmpl = Template("""\ 21 | 22 | 23 | 24 | {{ page_title }} 25 | 26 | 27 |
28 |

{{ page_title }}

29 |
30 | 39 |
40 | 41 | {% for row in table %} 42 | 43 | {% for cell in row %} 44 | 45 | {% end %} 46 | 47 | {% end %} 48 |
{{ cell }}
49 |
50 | 51 | \ 52 | """) 53 | 54 | def render(): 55 | tmpl.generate(**context) 56 | 57 | def main(): 58 | parse_command_line() 59 | if options.dump: 60 | print(tmpl.code) 61 | sys.exit(0) 62 | t = Timer(render) 63 | results = t.timeit(options.num) / options.num 64 | print('%0.3f ms per iteration' % (results*1000)) 65 | 66 | if __name__ == '__main__': 67 | main() 68 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/blog/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:2.7 2 | 3 | EXPOSE 8888 4 | 5 | RUN apt-get update && apt-get install -y mysql-client 6 | 7 | # based on python:2.7-onbuild, but if we use that image directly 8 | # the above apt-get line runs too late. 9 | RUN mkdir -p /usr/src/app 10 | WORKDIR /usr/src/app 11 | 12 | COPY requirements.txt /usr/src/app/ 13 | RUN pip install -r requirements.txt 14 | 15 | COPY . /usr/src/app 16 | 17 | CMD python blog.py --mysql_host=mysql 18 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/blog/README: -------------------------------------------------------------------------------- 1 | Running the Tornado Blog example app 2 | ==================================== 3 | This demo is a simple blogging engine that uses MySQL to store posts and 4 | Google Accounts for author authentication. Since it depends on MySQL, you 5 | need to set up MySQL and the database schema for the demo to run. 6 | 7 | If you have `docker` and `docker-compose` installed, the demo and all 8 | its prerequisites can be installed with `docker-compose up`. 9 | 10 | 1. Install prerequisites and build tornado 11 | 12 | See http://www.tornadoweb.org/ for installation instructions. If you can 13 | run the "helloworld" example application, your environment is set up 14 | correctly. 15 | 16 | 2. Install MySQL if needed 17 | 18 | Consult the documentation for your platform. Under Ubuntu Linux you 19 | can run "apt-get install mysql". Under OS X you can download the 20 | MySQL PKG file from http://dev.mysql.com/downloads/mysql/ 21 | 22 | 3. Install Python prerequisites 23 | 24 | Install the packages MySQL-python, torndb, and markdown (e.g. using pip or 25 | easy_install). Note that these packages currently only work on 26 | Python 2. Tornado supports Python 3, but this blog demo does not. 27 | 28 | 3. Connect to MySQL and create a database and user for the blog. 29 | 30 | Connect to MySQL as a user that can create databases and users: 31 | mysql -u root 32 | 33 | Create a database named "blog": 34 | mysql> CREATE DATABASE blog; 35 | 36 | Allow the "blog" user to connect with the password "blog": 37 | mysql> GRANT ALL PRIVILEGES ON blog.* TO 'blog'@'localhost' IDENTIFIED BY 'blog'; 38 | 39 | 4. Create the tables in your new database. 40 | 41 | You can use the provided schema.sql file by running this command: 42 | mysql --user=blog --password=blog --database=blog < schema.sql 43 | 44 | You can run the above command again later if you want to delete the 45 | contents of the blog and start over after testing. 46 | 47 | 5. Run the blog example 48 | 49 | With the default user, password, and database you can just run: 50 | ./blog.py 51 | 52 | If you've changed anything, you can alter the default MySQL settings 53 | with arguments on the command line, e.g.: 54 | ./blog.py --mysql_user=casey --mysql_password=happiness --mysql_database=foodblog 55 | 56 | 6. Visit your new blog 57 | 58 | Open http://localhost:8888/ in your web browser. You will be redirected to 59 | a Google account sign-in page because the blog uses Google accounts for 60 | authentication. 61 | 62 | Currently the first user to connect will automatically be given the 63 | ability to create and edit posts. 64 | 65 | Once you've created one blog post, subsequent users will not be 66 | prompted to sign in. 67 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/blog/docker-compose.yml: -------------------------------------------------------------------------------- 1 | mysql: 2 | image: mysql:5.6 3 | environment: 4 | MYSQL_ROOT_PASSWORD: its_a_secret_to_everybody 5 | MYSQL_USER: blog 6 | MYSQL_PASSWORD: blog 7 | MYSQL_DATABASE: blog 8 | ports: 9 | - "3306" 10 | blog: 11 | build: . 12 | links: 13 | - mysql 14 | ports: 15 | - "8888:8888" 16 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/blog/requirements.txt: -------------------------------------------------------------------------------- 1 | bcrypt 2 | futures 3 | MySQL-python 4 | markdown 5 | tornado 6 | torndb 7 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/blog/schema.sql: -------------------------------------------------------------------------------- 1 | -- Copyright 2009 FriendFeed 2 | -- 3 | -- Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | -- not use this file except in compliance with the License. You may obtain 5 | -- a copy of the License at 6 | -- 7 | -- http://www.apache.org/licenses/LICENSE-2.0 8 | -- 9 | -- Unless required by applicable law or agreed to in writing, software 10 | -- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | -- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | -- License for the specific language governing permissions and limitations 13 | -- under the License. 14 | 15 | -- To create the database: 16 | -- CREATE DATABASE blog; 17 | -- GRANT ALL PRIVILEGES ON blog.* TO 'blog'@'localhost' IDENTIFIED BY 'blog'; 18 | -- 19 | -- To reload the tables: 20 | -- mysql --user=blog --password=blog --database=blog < schema.sql 21 | 22 | SET SESSION storage_engine = "InnoDB"; 23 | SET SESSION time_zone = "+0:00"; 24 | ALTER DATABASE CHARACTER SET "utf8"; 25 | 26 | DROP TABLE IF EXISTS entries; 27 | CREATE TABLE entries ( 28 | id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 29 | author_id INT NOT NULL REFERENCES authors(id), 30 | slug VARCHAR(100) NOT NULL UNIQUE, 31 | title VARCHAR(512) NOT NULL, 32 | markdown MEDIUMTEXT NOT NULL, 33 | html MEDIUMTEXT NOT NULL, 34 | published DATETIME NOT NULL, 35 | updated TIMESTAMP NOT NULL, 36 | KEY (published) 37 | ); 38 | 39 | DROP TABLE IF EXISTS authors; 40 | CREATE TABLE authors ( 41 | id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 42 | email VARCHAR(100) NOT NULL UNIQUE, 43 | name VARCHAR(100) NOT NULL, 44 | hashed_password VARCHAR(100) NOT NULL 45 | ); 46 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/blog/static/blog.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 Facebook 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use this file except in compliance with the License. You may obtain 6 | * a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | body { 18 | background: white; 19 | color: black; 20 | margin: 15px; 21 | margin-top: 0; 22 | } 23 | 24 | body, 25 | input, 26 | textarea { 27 | font-family: Georgia, serif; 28 | font-size: 12pt; 29 | } 30 | 31 | table { 32 | border-collapse: collapse; 33 | border: 0; 34 | } 35 | 36 | td { 37 | border: 0; 38 | padding: 0; 39 | } 40 | 41 | h1, 42 | h2, 43 | h3, 44 | h4 { 45 | font-family: "Helvetica Nue", Helvetica, Arial, sans-serif; 46 | margin: 0; 47 | } 48 | 49 | h1 { 50 | font-size: 20pt; 51 | } 52 | 53 | pre, 54 | code { 55 | font-family: monospace; 56 | color: #060; 57 | } 58 | 59 | pre { 60 | margin-left: 1em; 61 | padding-left: 1em; 62 | border-left: 1px solid silver; 63 | line-height: 14pt; 64 | } 65 | 66 | a, 67 | a code { 68 | color: #00c; 69 | } 70 | 71 | #body { 72 | max-width: 800px; 73 | margin: auto; 74 | } 75 | 76 | #header { 77 | background-color: #3b5998; 78 | padding: 5px; 79 | padding-left: 10px; 80 | padding-right: 10px; 81 | margin-bottom: 1em; 82 | } 83 | 84 | #header, 85 | #header a { 86 | color: white; 87 | } 88 | 89 | #header h1 a { 90 | text-decoration: none; 91 | } 92 | 93 | #footer, 94 | #content { 95 | margin-left: 10px; 96 | margin-right: 10px; 97 | } 98 | 99 | #footer { 100 | margin-top: 3em; 101 | } 102 | 103 | .entry h1 a { 104 | color: black; 105 | text-decoration: none; 106 | } 107 | 108 | .entry { 109 | margin-bottom: 2em; 110 | } 111 | 112 | .entry .date { 113 | margin-top: 3px; 114 | } 115 | 116 | .entry p { 117 | margin: 0; 118 | margin-bottom: 1em; 119 | } 120 | 121 | .entry .body { 122 | margin-top: 1em; 123 | line-height: 16pt; 124 | } 125 | 126 | .compose td { 127 | vertical-align: middle; 128 | padding-bottom: 5px; 129 | } 130 | 131 | .compose td.field { 132 | padding-right: 10px; 133 | } 134 | 135 | .compose .title, 136 | .compose .submit { 137 | font-family: "Helvetica Nue", Helvetica, Arial, sans-serif; 138 | font-weight: bold; 139 | } 140 | 141 | .compose .title { 142 | font-size: 20pt; 143 | } 144 | 145 | .compose .title, 146 | .compose .markdown { 147 | width: 100%; 148 | } 149 | 150 | .compose .markdown { 151 | height: 500px; 152 | line-height: 16pt; 153 | } 154 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/blog/templates/archive.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block head %} 4 | 20 | {% end %} 21 | 22 | {% block body %} 23 |
    24 | {% for entry in entries %} 25 |
  • 26 | 27 |
    {{ locale.format_date(entry.published, full_format=True, shorter=True) }}
    28 |
  • 29 | {% end %} 30 |
31 | {% end %} 32 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/blog/templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{ escape(handler.settings["blog_title"]) }} 6 | 7 | 8 | {% block head %}{% end %} 9 | 10 | 11 |
12 | 23 |
{% block body %}{% end %}
24 |
25 | {% block bottom %}{% end %} 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/blog/templates/compose.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block body %} 4 |
5 |
6 |
7 | 12 | {% if entry %} 13 | 14 | {% end %} 15 | {% module xsrf_form_html() %} 16 |
17 | {% end %} 18 | 19 | {% block bottom %} 20 | 21 | 41 | {% end %} 42 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/blog/templates/create_author.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block body %} 4 |
5 | Email:
6 | Name:
7 | Password:
8 | {% module xsrf_form_html() %} 9 | 10 |
11 | {% end %} 12 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/blog/templates/entry.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block body %} 4 | {% module Entry(entry) %} 5 | {% end %} 6 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/blog/templates/feed.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | {% set date_format = "%Y-%m-%dT%H:%M:%SZ" %} 4 | {{ handler.settings["blog_title"] }} 5 | {% if len(entries) > 0 %} 6 | {{ max(e.updated for e in entries).strftime(date_format) }} 7 | {% else %} 8 | {{ datetime.datetime.utcnow().strftime(date_format) }} 9 | {% end %} 10 | http://{{ request.host }}/ 11 | 12 | 13 | {{ handler.settings["blog_title"] }} 14 | {% for entry in entries %} 15 | 16 | http://{{ request.host }}/entry/{{ entry.slug }} 17 | {{ entry.title }} 18 | 19 | {{ entry.updated.strftime(date_format) }} 20 | {{ entry.published.strftime(date_format) }} 21 | 22 |
{% raw entry.html %}
23 |
24 |
25 | {% end %} 26 |
27 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/blog/templates/home.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block body %} 4 | {% for entry in entries %} 5 | {% module Entry(entry) %} 6 | {% end %} 7 |
{{ _("Archive") }}
8 | {% end %} 9 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/blog/templates/login.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block body %} 4 | {% if error %} 5 | Error: {{ error }}

6 | {% end %} 7 | 8 |

9 | Email:
10 | Password:
11 | {% module xsrf_form_html() %} 12 | 13 |
14 | {% end %} 15 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/blog/templates/modules/entry.html: -------------------------------------------------------------------------------- 1 |
2 |

{{ entry.title }}

3 |
{{ locale.format_date(entry.published, full_format=True, shorter=True) }}
4 |
{% raw entry.html %}
5 | {% if current_user %} 6 | 7 | {% end %} 8 |
9 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/chat/static/chat.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 FriendFeed 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use this file except in compliance with the License. You may obtain 6 | * a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | body { 18 | background: white; 19 | margin: 10px; 20 | } 21 | 22 | body, 23 | input { 24 | font-family: sans-serif; 25 | font-size: 10pt; 26 | color: black; 27 | } 28 | 29 | table { 30 | border-collapse: collapse; 31 | border: 0; 32 | } 33 | 34 | td { 35 | border: 0; 36 | padding: 0; 37 | } 38 | 39 | #body { 40 | position: absolute; 41 | bottom: 10px; 42 | left: 10px; 43 | } 44 | 45 | #input { 46 | margin-top: 0.5em; 47 | } 48 | 49 | #inbox .message { 50 | padding-top: 0.25em; 51 | } 52 | 53 | #nav { 54 | float: right; 55 | z-index: 99; 56 | } 57 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/chat/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Tornado Chat Demo 6 | 7 | 8 | 9 |
10 |
11 | {% for message in messages %} 12 | {% module Template("message.html", message=message) %} 13 | {% end %} 14 |
15 |
16 |
17 | 18 | 19 | 20 | 25 | 26 |
21 | 22 | 23 | {% module xsrf_form_html() %} 24 |
27 |
28 |
29 |
30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/chat/templates/message.html: -------------------------------------------------------------------------------- 1 |
{% module linkify(message["body"]) %}
2 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/facebook/README: -------------------------------------------------------------------------------- 1 | Running the Tornado Facebook example 2 | ==================================== 3 | 4 | To run this example, you must register a Facebook application with a 5 | Connect URL set to the domain the this demo will be running on 6 | (i.e. http://localhost:8888/ by default). The API key and secret 7 | for this application must be passed on the command line: 8 | 9 | python facebook.py --facebook_api_key=ABC --facebook_secret=XYZ 10 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/facebook/static/facebook.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 Facebook 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use this file except in compliance with the License. You may obtain 6 | * a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | body { 18 | background: white; 19 | color: black; 20 | margin: 15px; 21 | } 22 | 23 | body, 24 | input, 25 | textarea { 26 | font-family: "Lucida Grande", Tahoma, Verdana, sans-serif; 27 | font-size: 10pt; 28 | } 29 | 30 | table { 31 | border-collapse: collapse; 32 | border: 0; 33 | } 34 | 35 | td { 36 | border: 0; 37 | padding: 0; 38 | } 39 | 40 | img { 41 | border: 0; 42 | } 43 | 44 | a { 45 | text-decoration: none; 46 | color: #3b5998; 47 | } 48 | 49 | a:hover { 50 | text-decoration: underline; 51 | } 52 | 53 | .post { 54 | border-bottom: 1px solid #eeeeee; 55 | min-height: 50px; 56 | padding-bottom: 10px; 57 | margin-top: 10px; 58 | } 59 | 60 | .post .picture { 61 | float: left; 62 | } 63 | 64 | .post .picture img { 65 | height: 50px; 66 | width: 50px; 67 | } 68 | 69 | .post .body { 70 | margin-left: 60px; 71 | } 72 | 73 | .post .media img { 74 | border: 1px solid #cccccc; 75 | padding: 3px; 76 | } 77 | 78 | .post .media:hover img { 79 | border: 1px solid #3b5998; 80 | } 81 | 82 | .post a.actor { 83 | font-weight: bold; 84 | } 85 | 86 | .post .meta { 87 | font-size: 11px; 88 | } 89 | 90 | .post a.permalink { 91 | color: #777777; 92 | } 93 | 94 | #body { 95 | max-width: 700px; 96 | margin: auto; 97 | } 98 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/facebook/static/facebook.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/better-py/annotated-py-tornado/78fa3ab3b87a559c1db9ec11d86d79f6bf47853c/src/tornado-4.2.0/demos/facebook/static/facebook.js -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/facebook/templates/modules/post.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | {% set author_url="http://www.facebook.com/profile.php?id=" + escape(post["from"]["id"]) %} 4 | 5 |
6 |
7 | {{ escape(post["from"]["name"]) }} 8 | {% if "message" in post %} 9 | {{ escape(post["message"]) }} 10 | {% end %} 11 | 16 |
17 |
18 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/facebook/templates/stream.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Tornado Facebook Stream Demo 6 | 7 | 8 | 9 |
10 |
11 | {{ escape(current_user["name"]) }} - 12 | {{ _("Sign out") }} 13 |
14 | 15 |
16 | {% for post in stream["data"] %} 17 | {{ modules.Post(post) }} 18 | {% end %} 19 |
20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/helloworld/helloworld.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2009 Facebook 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | 17 | import tornado.httpserver 18 | import tornado.ioloop 19 | import tornado.options 20 | import tornado.web 21 | 22 | from tornado.options import define, options 23 | 24 | define("port", default=8888, help="run on the given port", type=int) 25 | 26 | 27 | class MainHandler(tornado.web.RequestHandler): 28 | def get(self): 29 | self.write("Hello, world") 30 | 31 | 32 | def main(): 33 | tornado.options.parse_command_line() 34 | application = tornado.web.Application([ 35 | (r"/", MainHandler), 36 | ]) 37 | http_server = tornado.httpserver.HTTPServer(application) 38 | http_server.listen(options.port) 39 | tornado.ioloop.IOLoop.current().start() 40 | 41 | 42 | if __name__ == "__main__": 43 | main() 44 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/twitter/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Tornado Twitter Demo 4 | 5 | 6 |
    7 | {% for tweet in timeline %} 8 |
  • {{ tweet['user']['screen_name'] }}: {{ tweet['text'] }}
  • 9 | {% end %} 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/websocket/static/chat.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 FriendFeed 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | * not use this file except in compliance with the License. You may obtain 6 | * a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | body { 18 | background: white; 19 | margin: 10px; 20 | } 21 | 22 | body, 23 | input { 24 | font-family: sans-serif; 25 | font-size: 10pt; 26 | color: black; 27 | } 28 | 29 | table { 30 | border-collapse: collapse; 31 | border: 0; 32 | } 33 | 34 | td { 35 | border: 0; 36 | padding: 0; 37 | } 38 | 39 | #body { 40 | position: absolute; 41 | bottom: 10px; 42 | left: 10px; 43 | } 44 | 45 | #input { 46 | margin-top: 0.5em; 47 | } 48 | 49 | #inbox .message { 50 | padding-top: 0.25em; 51 | } 52 | 53 | #nav { 54 | float: right; 55 | z-index: 99; 56 | } 57 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/websocket/static/chat.js: -------------------------------------------------------------------------------- 1 | // Copyright 2009 FriendFeed 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); you may 4 | // not use this file except in compliance with the License. You may obtain 5 | // a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | // License for the specific language governing permissions and limitations 13 | // under the License. 14 | 15 | $(document).ready(function() { 16 | if (!window.console) window.console = {}; 17 | if (!window.console.log) window.console.log = function() {}; 18 | 19 | $("#messageform").live("submit", function() { 20 | newMessage($(this)); 21 | return false; 22 | }); 23 | $("#messageform").live("keypress", function(e) { 24 | if (e.keyCode == 13) { 25 | newMessage($(this)); 26 | return false; 27 | } 28 | }); 29 | $("#message").select(); 30 | updater.start(); 31 | }); 32 | 33 | function newMessage(form) { 34 | var message = form.formToDict(); 35 | updater.socket.send(JSON.stringify(message)); 36 | form.find("input[type=text]").val("").select(); 37 | } 38 | 39 | jQuery.fn.formToDict = function() { 40 | var fields = this.serializeArray(); 41 | var json = {} 42 | for (var i = 0; i < fields.length; i++) { 43 | json[fields[i].name] = fields[i].value; 44 | } 45 | if (json.next) delete json.next; 46 | return json; 47 | }; 48 | 49 | var updater = { 50 | socket: null, 51 | 52 | start: function() { 53 | var url = "ws://" + location.host + "/chatsocket"; 54 | updater.socket = new WebSocket(url); 55 | updater.socket.onmessage = function(event) { 56 | updater.showMessage(JSON.parse(event.data)); 57 | } 58 | }, 59 | 60 | showMessage: function(message) { 61 | var existing = $("#m" + message.id); 62 | if (existing.length > 0) return; 63 | var node = $(message.html); 64 | node.hide(); 65 | $("#inbox").append(node); 66 | node.slideDown(); 67 | } 68 | }; 69 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/websocket/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Tornado Chat Demo 6 | 7 | 8 | 9 |
10 |
11 | {% for message in messages %} 12 | {% include "message.html" %} 13 | {% end %} 14 |
15 |
16 |
17 | 18 | 19 | 20 | 25 | 26 |
21 | 22 | 23 | {% module xsrf_form_html() %} 24 |
27 |
28 |
29 |
30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/websocket/templates/message.html: -------------------------------------------------------------------------------- 1 |
{% module linkify(message["body"]) %}
2 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/demos/webspider/webspider.py: -------------------------------------------------------------------------------- 1 | import HTMLParser 2 | import time 3 | import urlparse 4 | from datetime import timedelta 5 | 6 | from tornado import httpclient, gen, ioloop, queues 7 | 8 | base_url = 'http://www.tornadoweb.org/en/stable/' 9 | concurrency = 10 10 | 11 | 12 | @gen.coroutine 13 | def get_links_from_url(url): 14 | """Download the page at `url` and parse it for links. 15 | 16 | Returned links have had the fragment after `#` removed, and have been made 17 | absolute so, e.g. the URL 'gen.html#tornado.gen.coroutine' becomes 18 | 'http://www.tornadoweb.org/en/stable/gen.html'. 19 | """ 20 | try: 21 | response = yield httpclient.AsyncHTTPClient().fetch(url) 22 | print('fetched %s' % url) 23 | urls = [urlparse.urljoin(url, remove_fragment(new_url)) 24 | for new_url in get_links(response.body)] 25 | except Exception as e: 26 | print('Exception: %s %s' % (e, url)) 27 | raise gen.Return([]) 28 | 29 | raise gen.Return(urls) 30 | 31 | 32 | def remove_fragment(url): 33 | scheme, netloc, url, params, query, fragment = urlparse.urlparse(url) 34 | return urlparse.urlunparse((scheme, netloc, url, params, query, '')) 35 | 36 | 37 | def get_links(html): 38 | class URLSeeker(HTMLParser.HTMLParser): 39 | def __init__(self): 40 | HTMLParser.HTMLParser.__init__(self) 41 | self.urls = [] 42 | 43 | def handle_starttag(self, tag, attrs): 44 | href = dict(attrs).get('href') 45 | if href and tag == 'a': 46 | self.urls.append(href) 47 | 48 | url_seeker = URLSeeker() 49 | url_seeker.feed(html) 50 | return url_seeker.urls 51 | 52 | 53 | @gen.coroutine 54 | def main(): 55 | q = queues.Queue() 56 | start = time.time() 57 | fetching, fetched = set(), set() 58 | 59 | @gen.coroutine 60 | def fetch_url(): 61 | current_url = yield q.get() 62 | try: 63 | if current_url in fetching: 64 | return 65 | 66 | print('fetching %s' % current_url) 67 | fetching.add(current_url) 68 | urls = yield get_links_from_url(current_url) 69 | fetched.add(current_url) 70 | 71 | for new_url in urls: 72 | # Only follow links beneath the base URL 73 | if new_url.startswith(base_url): 74 | yield q.put(new_url) 75 | 76 | finally: 77 | q.task_done() 78 | 79 | @gen.coroutine 80 | def worker(): 81 | while True: 82 | yield fetch_url() 83 | 84 | q.put(base_url) 85 | 86 | # Start workers, then wait for the work queue to be empty. 87 | for _ in range(concurrency): 88 | worker() 89 | yield q.join(timeout=timedelta(seconds=300)) 90 | assert fetching == fetched 91 | print('Done in %d seconds, fetched %s URLs.' % ( 92 | time.time() - start, len(fetched))) 93 | 94 | 95 | if __name__ == '__main__': 96 | import logging 97 | logging.basicConfig() 98 | io_loop = ioloop.IOLoop.current() 99 | io_loop.run_sync(main) 100 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/README: -------------------------------------------------------------------------------- 1 | This directory contains tools and scripts that are used in the development 2 | and maintainance of Tornado itself, but are probably not of interest to 3 | Tornado users. 4 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/requirements.txt: -------------------------------------------------------------------------------- 1 | # Frozen pip requirements for tools used in the development of tornado. 2 | # This list is for python 3.4; for 2.7 add: 3 | # - backports.ssl-match-hostname 4 | # - futures 5 | # - mock 6 | # 7 | # Use virtualenv instead of venv; tox seems to get confused otherwise. 8 | 9 | # Tornado's required dependencies 10 | certifi==14.5.14 11 | 12 | # Tornado's optional dependencies 13 | Twisted==15.0.0 14 | # pip on python 3.4 currently has trouble installing pycares. 15 | #pycares==0.6.1 16 | pycurl==7.19.5.1 17 | 18 | # Other useful tools 19 | Sphinx==1.2.3 20 | autopep8==1.1 21 | coverage==3.7.1 22 | flake8==2.3.0 23 | pep8==1.6.0 24 | pyflakes==0.8.1 25 | sphinx-rtd-theme==0.1.6 26 | tox==1.8.1 27 | twine==1.4.0 28 | virtualenv==12.0.7 29 | 30 | # Indirect dependencies 31 | Jinja2==2.7.3 32 | MarkupSafe==0.23 33 | Pygments==2.0.2 34 | docutils==0.12 35 | mccabe==0.3 36 | pkginfo==1.2.1 37 | py==1.4.26 38 | requests==2.5.1 39 | zope.interface==4.1.2 40 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/scripts/custom_fixers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/better-py/annotated-py-tornado/78fa3ab3b87a559c1db9ec11d86d79f6bf47853c/src/tornado-4.2.0/maint/scripts/custom_fixers/__init__.py -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/scripts/custom_fixers/fix_future_imports.py: -------------------------------------------------------------------------------- 1 | """Updates all source files to import the same set of __future__ directives. 2 | """ 3 | from lib2to3 import fixer_base 4 | from lib2to3 import pytree 5 | from lib2to3.pgen2 import token 6 | from lib2to3.fixer_util import FromImport, Name, Comma, Newline 7 | 8 | # copied from fix_tuple_params.py 9 | def is_docstring(stmt): 10 | return isinstance(stmt, pytree.Node) and \ 11 | stmt.children[0].type == token.STRING 12 | 13 | class FixFutureImports(fixer_base.BaseFix): 14 | BM_compatible = True 15 | 16 | PATTERN = """import_from< 'from' module_name="__future__" 'import' any >""" 17 | 18 | def start_tree(self, tree, filename): 19 | self.found_future_import = False 20 | 21 | def new_future_import(self, old): 22 | new = FromImport("__future__", 23 | [Name("absolute_import", prefix=" "), Comma(), 24 | Name("division", prefix=" "), Comma(), 25 | Name("print_function", prefix=" "), Comma(), 26 | Name("with_statement", prefix=" ")]) 27 | if old is not None: 28 | new.prefix = old.prefix 29 | return new 30 | 31 | def transform(self, node, results): 32 | self.found_future_import = True 33 | return self.new_future_import(node) 34 | 35 | def finish_tree(self, tree, filename): 36 | if self.found_future_import: 37 | return 38 | if not isinstance(tree, pytree.Node): 39 | # Empty files (usually __init__.py) show up as a single Leaf 40 | # instead of a Node, so leave them alone 41 | return 42 | first_stmt = tree.children[0] 43 | if is_docstring(first_stmt): 44 | # Skip a line and add the import after the docstring 45 | tree.insert_child(1, Newline()) 46 | pos = 2 47 | elif first_stmt.prefix: 48 | # No docstring, but an initial comment (perhaps a #! line). 49 | # Transfer the initial comment to a new blank line. 50 | newline = Newline() 51 | newline.prefix = first_stmt.prefix 52 | first_stmt.prefix = "" 53 | tree.insert_child(0, newline) 54 | pos = 1 55 | else: 56 | # No comments or docstring, just insert at the start 57 | pos = 0 58 | tree.insert_child(pos, self.new_future_import(None)) 59 | tree.insert_child(pos+1, Newline()) # terminates the import stmt 60 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/scripts/custom_fixers/fix_unicode_literal.py: -------------------------------------------------------------------------------- 1 | import re 2 | from lib2to3.pgen2 import token 3 | from lib2to3 import fixer_base 4 | from lib2to3.fixer_util import Name, Call 5 | 6 | _literal_re = re.compile(ur"[uU][rR]?[\'\"]") 7 | 8 | class FixUnicodeLiteral(fixer_base.BaseFix): 9 | BM_compatible = True 10 | PATTERN = """STRING""" 11 | 12 | def transform(self, node, results): 13 | if node.type == token.STRING and _literal_re.match(node.value): 14 | new = node.clone() 15 | new.value = new.value[1:] 16 | new.prefix = '' 17 | node.replace(Call(Name(u'u', prefix=node.prefix), [new])) 18 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/scripts/run_autopep8.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Runs autopep8 in the configuration used for tornado. 4 | # 5 | # W602 is "deprecated form of raising exception", but the fix is incorrect 6 | # (and I'm not sure if the three-argument form of raise is really deprecated 7 | # in the first place) 8 | # E501 is "line longer than 80 chars" but the automated fix is ugly. 9 | # E301 adds a blank line between docstring and first method 10 | # E309 adds a blank line between class declaration and docstring (?) 11 | autopep8 --ignore=W602,E501,E301,E309 -i tornado/*.py tornado/platform/*.py tornado/test/*.py 12 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/scripts/run_fixers.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Usage is like 2to3: 3 | # $ maint/scripts/run_fixers.py -wn --no-diffs tornado 4 | 5 | import sys 6 | from lib2to3.main import main 7 | 8 | sys.exit(main("custom_fixers")) 9 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/scripts/test_resolvers.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from __future__ import print_function 3 | 4 | import pprint 5 | import socket 6 | 7 | from tornado import gen 8 | from tornado.ioloop import IOLoop 9 | from tornado.netutil import Resolver, ThreadedResolver 10 | from tornado.options import parse_command_line, define, options 11 | 12 | try: 13 | import twisted 14 | except ImportError: 15 | twisted = None 16 | 17 | try: 18 | import pycares 19 | except ImportError: 20 | pycares = None 21 | 22 | define('family', default='unspec', 23 | help='Address family to query: unspec, inet, or inet6') 24 | 25 | @gen.coroutine 26 | def main(): 27 | args = parse_command_line() 28 | 29 | if not args: 30 | args = ['localhost', 'www.google.com', 31 | 'www.facebook.com', 'www.dropbox.com'] 32 | 33 | resolvers = [Resolver(), ThreadedResolver()] 34 | 35 | if twisted is not None: 36 | from tornado.platform.twisted import TwistedResolver 37 | resolvers.append(TwistedResolver()) 38 | 39 | if pycares is not None: 40 | from tornado.platform.caresresolver import CaresResolver 41 | resolvers.append(CaresResolver()) 42 | 43 | family = { 44 | 'unspec': socket.AF_UNSPEC, 45 | 'inet': socket.AF_INET, 46 | 'inet6': socket.AF_INET6, 47 | }[options.family] 48 | 49 | for host in args: 50 | print('Resolving %s' % host) 51 | for resolver in resolvers: 52 | addrinfo = yield resolver.resolve(host, 80, family) 53 | print('%s: %s' % (resolver.__class__.__name__, 54 | pprint.pformat(addrinfo))) 55 | print() 56 | 57 | if __name__ == '__main__': 58 | IOLoop.instance().run_sync(main) 59 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/test/README: -------------------------------------------------------------------------------- 1 | This directory contains additional tests that are not included in the main 2 | suite (because e.g. they have extra dependencies, run slowly, or produce 3 | more output than a simple pass/fail) 4 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/test/appengine/README: -------------------------------------------------------------------------------- 1 | Unit test support for app engine. Currently very limited as most of 2 | our tests depend on direct network access, but these tests ensure that the 3 | modules that are supposed to work on app engine don't depend on any 4 | forbidden modules. 5 | 6 | The code lives in maint/appengine/common, but should be run from the py25 7 | or py27 subdirectories (which contain an app.yaml and a bunch of symlinks). 8 | runtests.py is the entry point; cgi_runtests.py is used internally. 9 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/test/appengine/common/cgi_runtests.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys 3 | import unittest 4 | 5 | # Most of our tests depend on IOLoop, which is not usable on app engine. 6 | # Run the tests that work, and check that everything else is at least 7 | # importable (via tornado.test.import_test) 8 | TEST_MODULES = [ 9 | 'tornado.httputil.doctests', 10 | 'tornado.iostream.doctests', 11 | 'tornado.util.doctests', 12 | #'tornado.test.auth_test', 13 | #'tornado.test.concurrent_test', 14 | #'tornado.test.curl_httpclient_test', 15 | 'tornado.test.escape_test', 16 | #'tornado.test.gen_test', 17 | #'tornado.test.httpclient_test', 18 | #'tornado.test.httpserver_test', 19 | 'tornado.test.httputil_test', 20 | 'tornado.test.import_test', 21 | #'tornado.test.ioloop_test', 22 | #'tornado.test.iostream_test', 23 | 'tornado.test.locale_test', 24 | #'tornado.test.netutil_test', 25 | #'tornado.test.log_test', 26 | 'tornado.test.options_test', 27 | #'tornado.test.process_test', 28 | #'tornado.test.simple_httpclient_test', 29 | #'tornado.test.stack_context_test', 30 | 'tornado.test.template_test', 31 | #'tornado.test.testing_test', 32 | #'tornado.test.twisted_test', 33 | 'tornado.test.util_test', 34 | #'tornado.test.web_test', 35 | #'tornado.test.websocket_test', 36 | #'tornado.test.wsgi_test', 37 | ] 38 | 39 | def all(): 40 | return unittest.defaultTestLoader.loadTestsFromNames(TEST_MODULES) 41 | 42 | def main(): 43 | print "Content-Type: text/plain\r\n\r\n", 44 | 45 | try: 46 | unittest.main(defaultTest='all', argv=sys.argv[:1]) 47 | except SystemExit, e: 48 | if e.code == 0: 49 | print "PASS" 50 | else: 51 | raise 52 | 53 | if __name__ == '__main__': 54 | main() 55 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/test/appengine/common/runtests.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from __future__ import with_statement 3 | 4 | import contextlib 5 | import errno 6 | import os 7 | import random 8 | import signal 9 | import socket 10 | import subprocess 11 | import sys 12 | import time 13 | import urllib2 14 | 15 | if __name__ == "__main__": 16 | tornado_root = os.path.abspath(os.path.join(os.path.dirname(__file__), 17 | '../../..')) 18 | # dev_appserver doesn't seem to set SO_REUSEADDR 19 | port = random.randrange(10000, 11000) 20 | # does dev_appserver.py ever live anywhere but /usr/local/bin? 21 | proc = subprocess.Popen([sys.executable, 22 | "/usr/local/bin/dev_appserver.py", 23 | os.path.dirname(os.path.abspath(__file__)), 24 | "--port=%d" % port, 25 | "--skip_sdk_update_check", 26 | ], 27 | cwd=tornado_root) 28 | 29 | try: 30 | for i in xrange(50): 31 | with contextlib.closing(socket.socket()) as sock: 32 | err = sock.connect_ex(('localhost', port)) 33 | if err == 0: 34 | break 35 | elif err != errno.ECONNREFUSED: 36 | raise Exception("Got unexpected socket error %d" % err) 37 | time.sleep(0.1) 38 | else: 39 | raise Exception("Server didn't start listening") 40 | 41 | resp = urllib2.urlopen("http://localhost:%d/" % port) 42 | print resp.read() 43 | finally: 44 | # dev_appserver sometimes ignores SIGTERM (especially on 2.5), 45 | # so try a few times to kill it. 46 | for sig in [signal.SIGTERM, signal.SIGTERM, signal.SIGKILL]: 47 | os.kill(proc.pid, sig) 48 | res = os.waitpid(proc.pid, os.WNOHANG) 49 | if res != (0,0): 50 | break 51 | time.sleep(0.1) 52 | else: 53 | os.waitpid(proc.pid, 0) 54 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/test/appengine/py27/app.yaml: -------------------------------------------------------------------------------- 1 | application: tornado-tests-appengine27 2 | version: 1 3 | runtime: python27 4 | threadsafe: false 5 | api_version: 1 6 | 7 | handlers: 8 | - url: / 9 | script: cgi_runtests.py -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/test/appengine/py27/cgi_runtests.py: -------------------------------------------------------------------------------- 1 | ../common/cgi_runtests.py -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/test/appengine/py27/runtests.py: -------------------------------------------------------------------------------- 1 | ../common/runtests.py -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/test/appengine/py27/tornado: -------------------------------------------------------------------------------- 1 | ../../../../tornado -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/test/appengine/setup.py: -------------------------------------------------------------------------------- 1 | # Dummy setup file to make tox happy. In the appengine world things aren't 2 | # installed through setup.py 3 | import distutils.core 4 | distutils.core.setup() 5 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/test/appengine/tox.ini: -------------------------------------------------------------------------------- 1 | # App Engine tests require the SDK to be installed separately. 2 | # Version 1.6.1 or newer is required (older versions don't work when 3 | # python is run from a virtualenv) 4 | # 5 | # These are currently excluded from the main tox.ini because their 6 | # logs are spammy and they're a little flaky. 7 | [tox] 8 | envlist = py27-appengine 9 | 10 | [testenv] 11 | changedir = {toxworkdir} 12 | 13 | [testenv:py27-appengine] 14 | basepython = python2.7 15 | commands = python {toxinidir}/py27/runtests.py {posargs:} 16 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/test/pyuv/tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = py27 3 | setupdir = ../../.. 4 | 5 | [testenv] 6 | commands = 7 | python -m tornado.test.runtests --ioloop=tornado_pyuv.UVLoop {posargs:} 8 | # twisted tests don't work on pyuv IOLoop currently. 9 | deps = 10 | pyuv 11 | git+https://github.com/saghul/tornado-pyuv.git 12 | futures 13 | mock 14 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/test/redbot/README: -------------------------------------------------------------------------------- 1 | Redbot is an HTTP validator that checks for common problems, especially 2 | related to cacheability. These tests ensure that Tornado's default behavior 3 | is correct (but note that this guarantee does not automatically extend 4 | to applications built on Tornado since application behavior can impact 5 | cacheability. 6 | 7 | http://redbot.org/about -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/test/redbot/tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = py27 3 | setupdir=../../.. 4 | 5 | [testenv] 6 | commands = python red_test.py 7 | deps = 8 | # Newer versions of thor have a bug with redbot (5/18/13) 9 | thor==0.2.0 10 | git+https://github.com/mnot/redbot.git 11 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/test/websocket/.gitignore: -------------------------------------------------------------------------------- 1 | reports/ 2 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/test/websocket/client.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import logging 4 | 5 | from tornado import gen 6 | from tornado.ioloop import IOLoop 7 | from tornado.options import define, options, parse_command_line 8 | from tornado.websocket import websocket_connect 9 | 10 | define('url', default='ws://localhost:9001') 11 | define('name', default='Tornado') 12 | 13 | @gen.engine 14 | def run_tests(): 15 | url = options.url + '/getCaseCount' 16 | control_ws = yield websocket_connect(url, None) 17 | num_tests = int((yield control_ws.read_message())) 18 | logging.info('running %d cases', num_tests) 19 | msg = yield control_ws.read_message() 20 | assert msg is None 21 | 22 | for i in range(1, num_tests + 1): 23 | logging.info('running test case %d', i) 24 | url = options.url + '/runCase?case=%d&agent=%s' % (i, options.name) 25 | test_ws = yield websocket_connect(url, None, compression_options={}) 26 | while True: 27 | message = yield test_ws.read_message() 28 | if message is None: 29 | break 30 | test_ws.write_message(message, binary=isinstance(message, bytes)) 31 | 32 | url = options.url + '/updateReports?agent=%s' % options.name 33 | update_ws = yield websocket_connect(url, None) 34 | msg = yield update_ws.read_message() 35 | assert msg is None 36 | IOLoop.instance().stop() 37 | 38 | def main(): 39 | parse_command_line() 40 | 41 | IOLoop.instance().add_callback(run_tests) 42 | 43 | IOLoop.instance().start() 44 | 45 | if __name__ == '__main__': 46 | main() 47 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/test/websocket/fuzzingclient.json: -------------------------------------------------------------------------------- 1 | { 2 | "options": {"failByDrop": false}, 3 | "outdir": "./reports/servers", 4 | 5 | "servers": [ 6 | {"agent": "Tornado/py26", "url": "ws://localhost:9001", 7 | "options": {"version": 18}}, 8 | {"agent": "Tornado/py27", "url": "ws://localhost:9002", 9 | "options": {"version": 18}}, 10 | {"agent": "Tornado/py32", "url": "ws://localhost:9003", 11 | "options": {"version": 18}}, 12 | {"agent": "Tornado/pypy", "url": "ws://localhost:9004", 13 | "options": {"version": 18}} 14 | ], 15 | 16 | "cases": ["*"], 17 | "exclude-cases": ["9.*", "12.*.1","12.2.*", "12.3.*", "12.4.*", "12.5.*", "13.*.1"], 18 | "exclude-agent-cases": {} 19 | } 20 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/test/websocket/fuzzingserver.json: -------------------------------------------------------------------------------- 1 | 2 | { 3 | "url": "ws://localhost:9001", 4 | 5 | "options": {"failByDrop": false}, 6 | "outdir": "./reports/clients", 7 | "webport": 8080, 8 | 9 | "cases": ["*"], 10 | "exclude-cases": ["9.*", "12.*.1","12.2.*", "12.3.*", "12.4.*", "12.5.*", "13.*.1"], 11 | "exclude-agent-cases": {} 12 | } 13 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/test/websocket/run-client.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | tox 6 | 7 | .tox/py27/bin/wstest -m fuzzingserver & 8 | FUZZING_SERVER_PID=$! 9 | 10 | sleep 1 11 | 12 | .tox/py26/bin/python client.py --name='Tornado/py26' 13 | .tox/py27/bin/python client.py --name='Tornado/py27' 14 | .tox/py32/bin/python client.py --name='Tornado/py32' 15 | .tox/pypy/bin/python client.py --name='Tornado/pypy' 16 | 17 | kill $FUZZING_SERVER_PID 18 | wait 19 | 20 | echo "Tests complete. Output is in ./reports/clients/index.html" 21 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/test/websocket/run-server.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Runs the autobahn websocket conformance test against tornado in both 4 | # python2 and python3. Output goes in ./reports/servers/index.html. 5 | # 6 | # The --cases and --exclude arguments can be used to run only part of 7 | # the suite. The default is --exclude="9.*" to skip the relatively slow 8 | # performance tests; pass --exclude="" to override and include them. 9 | 10 | set -e 11 | 12 | # build/update the virtualenvs 13 | tox 14 | 15 | .tox/py26/bin/python server.py --port=9001 & 16 | PY26_SERVER_PID=$! 17 | 18 | .tox/py27/bin/python server.py --port=9002 & 19 | PY27_SERVER_PID=$! 20 | 21 | .tox/py32/bin/python server.py --port=9003 & 22 | PY32_SERVER_PID=$! 23 | 24 | .tox/pypy/bin/python server.py --port=9004 & 25 | PYPY_SERVER_PID=$! 26 | 27 | sleep 1 28 | 29 | .tox/py27/bin/wstest -m fuzzingclient 30 | 31 | kill $PY26_SERVER_PID 32 | kill $PY27_SERVER_PID 33 | kill $PY32_SERVER_PID 34 | kill $PYPY_SERVER_PID 35 | wait 36 | 37 | echo "Tests complete. Output is in ./reports/servers/index.html" 38 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/test/websocket/server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from tornado.ioloop import IOLoop 4 | from tornado.options import define, options, parse_command_line 5 | from tornado.websocket import WebSocketHandler 6 | from tornado.web import Application 7 | 8 | define('port', default=9000) 9 | 10 | class EchoHandler(WebSocketHandler): 11 | def on_message(self, message): 12 | self.write_message(message, binary=isinstance(message, bytes)) 13 | 14 | def get_compression_options(self): 15 | return {} 16 | 17 | if __name__ == '__main__': 18 | parse_command_line() 19 | app = Application([ 20 | ('/', EchoHandler), 21 | ]) 22 | app.listen(options.port, address='127.0.0.1') 23 | IOLoop.instance().start() 24 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/test/websocket/tox.ini: -------------------------------------------------------------------------------- 1 | # We don't actually use tox to run this test, but it's the easiest way 2 | # to install autobahn and build the speedups module. 3 | # See run.sh for the real test runner. 4 | [tox] 5 | envlist = py27, py32, py26, pypy 6 | setupdir=../../.. 7 | 8 | [testenv] 9 | commands = python -c pass 10 | 11 | [testenv:py27] 12 | deps = autobahntestsuite 13 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/vm/README: -------------------------------------------------------------------------------- 1 | This directory contains virtual machine setup scripts for testing Tornado. 2 | 3 | Requirements: 4 | 5 | Vagrant (http://vagrantup.com) and VirtualBox (http://virtualbox.org). 6 | Vagrant provides an easy download for Ubuntu 10.04 (aka lucid64); base 7 | images for other platforms are harder to find and can be built with 8 | VeeWee (https://github.com/jedi4ever/veewee). 9 | 10 | Usage: 11 | 12 | cd to the appropriate directory and run `vagrant up`, then `vagrant ssh`. 13 | From there, simply run `tox` to run the full test suite, or cd to /tornado 14 | and test manually. Afterwards, use `vagrant suspend` or `vagrant destroy` 15 | to clean up. 16 | 17 | Notes: 18 | 19 | Python distutils (and therefore tox) assume that if the platform 20 | supports hard links, they can be used in the Tornado source directory. 21 | VirtualBox's shared folder filesystem does not support hard links (or 22 | symlinks), so we have to use NFS shared folders instead. (which has 23 | the unfortunate side effect of requiring sudo on the host machine) 24 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/vm/freebsd/Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | # Vagrantfile API/syntax version. Don't touch unless you know what you're doing! 5 | VAGRANTFILE_API_VERSION = "2" 6 | 7 | Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| 8 | config.vm.box = "chef/freebsd-10.0" 9 | 10 | config.vm.network "private_network", type: "dhcp" 11 | 12 | # Share an additional folder to the guest VM. The first argument is 13 | # the path on the host to the actual folder. The second argument is 14 | # the path on the guest to mount the folder. And the optional third 15 | # argument is a set of non-required options. 16 | config.vm.synced_folder "../../..", "/tornado", type: "nfs" 17 | 18 | # Override the default /vagrant mapping to use nfs, since freebsd doesn't 19 | # support other folder types. 20 | config.vm.synced_folder ".", "/vagrant", type: "nfs" 21 | 22 | config.ssh.shell = "/bin/sh" 23 | 24 | config.vm.provision :shell, :path => "setup.sh" 25 | end 26 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/vm/freebsd/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | chsh -s bash vagrant 4 | 5 | PACKAGES=" 6 | curl 7 | python 8 | python34 9 | py27-pip 10 | py27-virtualenv 11 | " 12 | 13 | PIP_PACKAGES=" 14 | futures 15 | pycurl 16 | tox 17 | " 18 | 19 | ASSUME_ALWAYS_YES=true pkg install $PACKAGES 20 | 21 | pip install $PIP_PACKAGES 22 | 23 | /tornado/maint/vm/shared-setup.sh 24 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/vm/freebsd/tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist=py27-full, py27, py34 3 | setupdir=/tornado 4 | # /home is a symlink to /usr/home, but tox doesn't like symlinks here 5 | toxworkdir=/usr/home/vagrant/tox-tornado 6 | 7 | [testenv] 8 | commands = python -m tornado.test.runtests {posargs:} 9 | 10 | [testenv:py27-full] 11 | # twisted's tests fail on freebsd 12 | deps = 13 | futures 14 | pycurl 15 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/vm/shared-setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Run at the end of each vm's provisioning script 3 | 4 | set -e 5 | 6 | # Link tox.ini into the home directory so you can run tox immediately 7 | # after ssh'ing in without cd'ing to /vagrant (since cd'ing to /tornado 8 | # gets the wrong config) 9 | ln -sf /vagrant/tox.ini ~vagrant/tox.ini 10 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/vm/ubuntu10.04/Vagrantfile: -------------------------------------------------------------------------------- 1 | Vagrant::Config.run do |config| 2 | config.vm.box = "lucid64" 3 | config.vm.box_url = "http://files.vagrantup.com/lucid64.box" 4 | 5 | config.vm.network :hostonly, "172.19.1.2" 6 | config.vm.share_folder("tornado", "/tornado", "../../..", :nfs=> true) 7 | 8 | config.vm.provision :shell, :path => "setup.sh" 9 | end -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/vm/ubuntu10.04/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | apt-get update 6 | 7 | # libcurl4-gnutls-dev is the default if you ask for libcurl4-dev, but it 8 | # has bugs that make our tests deadlock (the relevant tests detect this and 9 | # disable themselves, but it means that to get full coverage we have to use 10 | # the openssl version). 11 | # The oddly-named python-software-properties includes add-apt-repository. 12 | APT_PACKAGES=" 13 | python-pip 14 | python-dev 15 | libcurl4-openssl-dev 16 | python-software-properties 17 | " 18 | 19 | apt-get -y install $APT_PACKAGES 20 | 21 | 22 | # Ubuntu 10.04 has python 2.6 as default; install more from here. 23 | add-apt-repository ppa:fkrull/deadsnakes 24 | apt-get update 25 | 26 | DEADSNAKES_PACKAGES=" 27 | python2.7 28 | python2.7-dev 29 | python3.2 30 | python3.2-dev 31 | " 32 | apt-get -y install $DEADSNAKES_PACKAGES 33 | 34 | 35 | PIP_PACKAGES=" 36 | futures 37 | pycurl 38 | tox 39 | twisted 40 | virtualenv 41 | " 42 | 43 | pip install $PIP_PACKAGES 44 | 45 | /tornado/maint/vm/shared-setup.sh 46 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/vm/ubuntu10.04/tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = py27-full, py32, py26, py26-full, py27 3 | setupdir=/tornado 4 | toxworkdir=/home/vagrant/tox-tornado 5 | 6 | [testenv] 7 | commands = python -m tornado.test.runtests {posargs:} 8 | 9 | [testenv:py26] 10 | deps = unittest2 11 | 12 | [testenv:py26-full] 13 | deps = 14 | futures 15 | pycurl 16 | twisted==11.0.0 17 | unittest2 18 | 19 | [testenv:py27-full] 20 | basepython = python2.7 21 | deps = 22 | futures 23 | pycurl 24 | twisted==11.0.0 25 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/vm/ubuntu12.04/Vagrantfile: -------------------------------------------------------------------------------- 1 | Vagrant::Config.run do |config| 2 | config.vm.box = "precise64" 3 | config.vm.box_url = "http://files.vagrantup.com/precise64.box" 4 | 5 | config.vm.network :hostonly, "172.19.1.5" 6 | config.vm.share_folder("tornado", "/tornado", "../../..", :nfs=> true) 7 | 8 | config.vm.provision :shell, :path => "setup.sh" 9 | end -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/vm/ubuntu12.04/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | apt-get update 6 | 7 | # libcurl4-gnutls-dev is the default if you ask for libcurl4-dev, but it 8 | # has bugs that make our tests deadlock (the relevant tests detect this and 9 | # disable themselves, but it means that to get full coverage we have to use 10 | # the openssl version). 11 | # The oddly-named python-software-properties includes add-apt-repository. 12 | APT_PACKAGES=" 13 | python-pip 14 | python-dev 15 | libcurl4-openssl-dev 16 | python-software-properties 17 | " 18 | 19 | apt-get -y install $APT_PACKAGES 20 | 21 | 22 | # Ubuntu 12.04 has python 2.7 as default; install more from here. 23 | add-apt-repository ppa:fkrull/deadsnakes 24 | apt-get update 25 | 26 | DEADSNAKES_PACKAGES=" 27 | python3.2 28 | python3.2-dev 29 | " 30 | apt-get -y install $DEADSNAKES_PACKAGES 31 | 32 | 33 | PIP_PACKAGES=" 34 | futures 35 | pycurl 36 | tox 37 | twisted 38 | virtualenv 39 | " 40 | 41 | pip install $PIP_PACKAGES 42 | 43 | /tornado/maint/vm/shared-setup.sh 44 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/vm/ubuntu12.04/tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = py27-full, py32, py27, py27-select, py27-twisted 3 | setupdir=/tornado 4 | toxworkdir=/home/vagrant/tox-tornado 5 | 6 | [testenv] 7 | commands = python -m tornado.test.runtests {posargs:} 8 | 9 | [testenv:py27-full] 10 | basepython = python2.7 11 | deps = 12 | futures 13 | pycurl 14 | twisted==12.2.0 15 | 16 | [testenv:py27-select] 17 | basepython = python2.7 18 | deps = 19 | futures 20 | pycurl 21 | twisted==12.2.0 22 | commands = python -m tornado.test.runtests --ioloop=tornado.platform.select.SelectIOLoop {posargs:} 23 | 24 | [testenv:py27-twisted] 25 | basepython = python2.7 26 | deps = 27 | futures 28 | pycurl 29 | twisted==12.2.0 30 | commands = python -m tornado.test.runtests --ioloop=tornado.platform.twisted.TwistedIOLoop {posargs:} 31 | 32 | [testenv:py32] 33 | basepython = python3.2 34 | commands = python -bb -m tornado.test.runtests {posargs:} -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/vm/ubuntu14.04/Vagrantfile: -------------------------------------------------------------------------------- 1 | Vagrant::Config.run do |config| 2 | config.vm.box = "ubuntu/trusty64" 3 | 4 | config.vm.network :hostonly, "172.19.1.8" 5 | config.vm.share_folder("tornado", "/tornado", "../../..", :nfs=> true) 6 | 7 | config.vm.provision :shell, :path => "setup.sh" 8 | end -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/vm/ubuntu14.04/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | apt-get update 6 | 7 | # libcurl4-gnutls-dev is the default if you ask for libcurl4-dev, but it 8 | # has bugs that make our tests deadlock (the relevant tests detect this and 9 | # disable themselves, but it means that to get full coverage we have to use 10 | # the openssl version). 11 | APT_PACKAGES=" 12 | python-pip 13 | python-dev 14 | python3-pycurl 15 | libcurl4-openssl-dev 16 | " 17 | 18 | apt-get -y install $APT_PACKAGES 19 | 20 | # Ubuntu 14.04 includes python 2.7 and 3.4. 21 | 22 | PIP_PACKAGES=" 23 | futures 24 | pycurl 25 | tox 26 | twisted 27 | virtualenv 28 | " 29 | 30 | pip install $PIP_PACKAGES 31 | 32 | /tornado/maint/vm/shared-setup.sh 33 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/vm/ubuntu14.04/tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = py27-full, py34, py27, py27-select, py27-twisted 3 | setupdir=/tornado 4 | toxworkdir=/home/vagrant/tox-tornado 5 | 6 | [testenv] 7 | commands = python -m tornado.test.runtests {posargs:} 8 | 9 | [testenv:py27-full] 10 | basepython = python2.7 11 | deps = 12 | futures 13 | mock 14 | pycurl 15 | twisted==14.0.0 16 | 17 | [testenv:py27-select] 18 | basepython = python2.7 19 | deps = 20 | futures 21 | mock 22 | pycurl 23 | twisted==14.0.0 24 | commands = python -m tornado.test.runtests --ioloop=tornado.platform.select.SelectIOLoop {posargs:} 25 | 26 | [testenv:py27-twisted] 27 | basepython = python2.7 28 | deps = 29 | futures 30 | mock 31 | pycurl 32 | twisted==14.0.0 33 | commands = python -m tornado.test.runtests --ioloop=tornado.platform.twisted.TwistedIOLoop {posargs:} 34 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/maint/vm/windows/tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = py27-full, py32-full, py26, py26-full, py27, py32, py33, py27-opt, py33-monotonic 3 | setupdir = e:\ 4 | toxworkdir = c:\tox-tornado 5 | 6 | [testenv] 7 | commands = python -m tornado.test.runtests {posargs:} 8 | 9 | [testenv:py26] 10 | deps = unittest2 11 | 12 | [testenv:py26-full] 13 | basepython = python2.6 14 | deps = 15 | futures 16 | mock 17 | unittest2 18 | 19 | [testenv:py27-full] 20 | basepython = python2.7 21 | deps = 22 | futures 23 | mock 24 | 25 | [testenv:py32-full] 26 | basepython = python3.2 27 | deps = 28 | mock 29 | 30 | [testenv:py33] 31 | # tox's path mappings haven't been updated for py33 yet. 32 | basepython = c:\python33\python.exe 33 | 34 | [testenv:py33-monotonic] 35 | basepython = c:\python33\python.exe 36 | commands = python -m tornado.test.runtests --ioloop_time_monotonic {posargs:} 37 | 38 | [testenv:py27-opt] 39 | basepython = python2.7 40 | deps = 41 | futures 42 | mock 43 | commands = python -O -m tornado.test.runtests {posargs:} 44 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/runtests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Run the Tornado test suite. 3 | # 4 | # Also consider using tox, which uses virtualenv to run the test suite 5 | # under multiple versions of python. 6 | 7 | cd $(dirname $0) 8 | 9 | # "python -m" differs from "python tornado/test/runtests.py" in how it sets 10 | # up the default python path. "python -m" uses the current directory, 11 | # while "python file.py" uses the directory containing "file.py" (which is 12 | # not what you want if file.py appears within a package you want to import 13 | # from) 14 | python -m tornado.test.runtests "$@" 15 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/tornado/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2009 Facebook 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | 17 | """The Tornado web server and tools.""" 18 | 19 | from __future__ import absolute_import, division, print_function, with_statement 20 | 21 | # version is a human-readable version number. 22 | 23 | # version_info is a four-tuple for programmatic comparison. The first 24 | # three numbers are the components of the version number. The fourth 25 | # is zero for an official release, positive for a development branch, 26 | # or negative for a release candidate or beta (after the base version 27 | # number has been incremented) 28 | version = "4.2" 29 | version_info = (4, 2, 0, 0) 30 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/tornado/platform/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/better-py/annotated-py-tornado/78fa3ab3b87a559c1db9ec11d86d79f6bf47853c/src/tornado-4.2.0/tornado/platform/__init__.py -------------------------------------------------------------------------------- /src/tornado-4.2.0/tornado/platform/auto.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2011 Facebook 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | 17 | """Implementation of platform-specific functionality. 18 | 19 | For each function or class described in `tornado.platform.interface`, 20 | the appropriate platform-specific implementation exists in this module. 21 | Most code that needs access to this functionality should do e.g.:: 22 | 23 | from tornado.platform.auto import set_close_exec 24 | """ 25 | 26 | from __future__ import absolute_import, division, print_function, with_statement 27 | 28 | import os 29 | 30 | if 'APPENGINE_RUNTIME' in os.environ: 31 | from tornado.platform.common import Waker 32 | 33 | def set_close_exec(fd): 34 | pass 35 | elif os.name == 'nt': 36 | from tornado.platform.common import Waker 37 | from tornado.platform.windows import set_close_exec 38 | else: 39 | from tornado.platform.posix import set_close_exec, Waker 40 | 41 | try: 42 | # monotime monkey-patches the time module to have a monotonic function 43 | # in versions of python before 3.3. 44 | import monotime 45 | # Silence pyflakes warning about this unused import 46 | monotime 47 | except ImportError: 48 | pass 49 | try: 50 | from time import monotonic as monotonic_time 51 | except ImportError: 52 | monotonic_time = None 53 | 54 | __all__ = ['Waker', 'set_close_exec', 'monotonic_time'] 55 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/tornado/platform/caresresolver.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import, division, print_function, with_statement 2 | import pycares 3 | import socket 4 | 5 | from tornado import gen 6 | from tornado.ioloop import IOLoop 7 | from tornado.netutil import Resolver, is_valid_ip 8 | 9 | 10 | class CaresResolver(Resolver): 11 | """Name resolver based on the c-ares library. 12 | 13 | This is a non-blocking and non-threaded resolver. It may not produce 14 | the same results as the system resolver, but can be used for non-blocking 15 | resolution when threads cannot be used. 16 | 17 | c-ares fails to resolve some names when ``family`` is ``AF_UNSPEC``, 18 | so it is only recommended for use in ``AF_INET`` (i.e. IPv4). This is 19 | the default for ``tornado.simple_httpclient``, but other libraries 20 | may default to ``AF_UNSPEC``. 21 | 22 | .. versionchanged:: 4.1 23 | The ``io_loop`` argument is deprecated. 24 | """ 25 | def initialize(self, io_loop=None): 26 | self.io_loop = io_loop or IOLoop.current() 27 | self.channel = pycares.Channel(sock_state_cb=self._sock_state_cb) 28 | self.fds = {} 29 | 30 | def _sock_state_cb(self, fd, readable, writable): 31 | state = ((IOLoop.READ if readable else 0) | 32 | (IOLoop.WRITE if writable else 0)) 33 | if not state: 34 | self.io_loop.remove_handler(fd) 35 | del self.fds[fd] 36 | elif fd in self.fds: 37 | self.io_loop.update_handler(fd, state) 38 | self.fds[fd] = state 39 | else: 40 | self.io_loop.add_handler(fd, self._handle_events, state) 41 | self.fds[fd] = state 42 | 43 | def _handle_events(self, fd, events): 44 | read_fd = pycares.ARES_SOCKET_BAD 45 | write_fd = pycares.ARES_SOCKET_BAD 46 | if events & IOLoop.READ: 47 | read_fd = fd 48 | if events & IOLoop.WRITE: 49 | write_fd = fd 50 | self.channel.process_fd(read_fd, write_fd) 51 | 52 | @gen.coroutine 53 | def resolve(self, host, port, family=0): 54 | if is_valid_ip(host): 55 | addresses = [host] 56 | else: 57 | # gethostbyname doesn't take callback as a kwarg 58 | self.channel.gethostbyname(host, family, (yield gen.Callback(1))) 59 | callback_args = yield gen.Wait(1) 60 | assert isinstance(callback_args, gen.Arguments) 61 | assert not callback_args.kwargs 62 | result, error = callback_args.args 63 | if error: 64 | raise Exception('C-Ares returned error %s: %s while resolving %s' % 65 | (error, pycares.errno.strerror(error), host)) 66 | addresses = result.addresses 67 | addrinfo = [] 68 | for address in addresses: 69 | if '.' in address: 70 | address_family = socket.AF_INET 71 | elif ':' in address: 72 | address_family = socket.AF_INET6 73 | else: 74 | address_family = socket.AF_UNSPEC 75 | if family != socket.AF_UNSPEC and family != address_family: 76 | raise Exception('Requested socket family %d but got %d' % 77 | (family, address_family)) 78 | addrinfo.append((address_family, (address, port))) 79 | raise gen.Return(addrinfo) 80 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/tornado/platform/epoll.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2012 Facebook 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | """EPoll-based IOLoop implementation for Linux systems.""" 17 | from __future__ import absolute_import, division, print_function, with_statement 18 | 19 | import select 20 | 21 | from tornado.ioloop import PollIOLoop 22 | 23 | 24 | class EPollIOLoop(PollIOLoop): 25 | def initialize(self, **kwargs): 26 | super(EPollIOLoop, self).initialize(impl=select.epoll(), **kwargs) 27 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/tornado/platform/interface.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2011 Facebook 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | 17 | """Interfaces for platform-specific functionality. 18 | 19 | This module exists primarily for documentation purposes and as base classes 20 | for other tornado.platform modules. Most code should import the appropriate 21 | implementation from `tornado.platform.auto`. 22 | """ 23 | 24 | from __future__ import absolute_import, division, print_function, with_statement 25 | 26 | 27 | def set_close_exec(fd): 28 | """Sets the close-on-exec bit (``FD_CLOEXEC``)for a file descriptor.""" 29 | raise NotImplementedError() 30 | 31 | 32 | class Waker(object): 33 | """A socket-like object that can wake another thread from ``select()``. 34 | 35 | The `~tornado.ioloop.IOLoop` will add the Waker's `fileno()` to 36 | its ``select`` (or ``epoll`` or ``kqueue``) calls. When another 37 | thread wants to wake up the loop, it calls `wake`. Once it has woken 38 | up, it will call `consume` to do any necessary per-wake cleanup. When 39 | the ``IOLoop`` is closed, it closes its waker too. 40 | """ 41 | def fileno(self): 42 | """Returns the read file descriptor for this waker. 43 | 44 | Must be suitable for use with ``select()`` or equivalent on the 45 | local platform. 46 | """ 47 | raise NotImplementedError() 48 | 49 | def write_fileno(self): 50 | """Returns the write file descriptor for this waker.""" 51 | raise NotImplementedError() 52 | 53 | def wake(self): 54 | """Triggers activity on the waker's file descriptor.""" 55 | raise NotImplementedError() 56 | 57 | def consume(self): 58 | """Called after the listen has woken up to do any necessary cleanup.""" 59 | raise NotImplementedError() 60 | 61 | def close(self): 62 | """Closes the waker's file descriptor(s).""" 63 | raise NotImplementedError() 64 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/tornado/platform/posix.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2011 Facebook 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | 17 | """Posix implementations of platform-specific functionality.""" 18 | 19 | from __future__ import absolute_import, division, print_function, with_statement 20 | 21 | import fcntl 22 | import os 23 | 24 | from tornado.platform import interface 25 | 26 | 27 | def set_close_exec(fd): 28 | flags = fcntl.fcntl(fd, fcntl.F_GETFD) 29 | fcntl.fcntl(fd, fcntl.F_SETFD, flags | fcntl.FD_CLOEXEC) 30 | 31 | 32 | def _set_nonblocking(fd): 33 | flags = fcntl.fcntl(fd, fcntl.F_GETFL) 34 | fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK) 35 | 36 | 37 | class Waker(interface.Waker): 38 | def __init__(self): 39 | r, w = os.pipe() 40 | _set_nonblocking(r) 41 | _set_nonblocking(w) 42 | set_close_exec(r) 43 | set_close_exec(w) 44 | self.reader = os.fdopen(r, "rb", 0) 45 | self.writer = os.fdopen(w, "wb", 0) 46 | 47 | def fileno(self): 48 | return self.reader.fileno() 49 | 50 | def write_fileno(self): 51 | return self.writer.fileno() 52 | 53 | def wake(self): 54 | try: 55 | self.writer.write(b"x") 56 | except IOError: 57 | pass 58 | 59 | def consume(self): 60 | try: 61 | while True: 62 | result = self.reader.read() 63 | if not result: 64 | break 65 | except IOError: 66 | pass 67 | 68 | def close(self): 69 | self.reader.close() 70 | self.writer.close() 71 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/tornado/platform/select.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2012 Facebook 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 6 | # not use this file except in compliance with the License. You may obtain 7 | # a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 | # License for the specific language governing permissions and limitations 15 | # under the License. 16 | """Select-based IOLoop implementation. 17 | 18 | Used as a fallback for systems that don't support epoll or kqueue. 19 | """ 20 | from __future__ import absolute_import, division, print_function, with_statement 21 | 22 | import select 23 | 24 | from tornado.ioloop import IOLoop, PollIOLoop 25 | 26 | 27 | class _Select(object): 28 | """A simple, select()-based IOLoop implementation for non-Linux systems""" 29 | def __init__(self): 30 | self.read_fds = set() 31 | self.write_fds = set() 32 | self.error_fds = set() 33 | self.fd_sets = (self.read_fds, self.write_fds, self.error_fds) 34 | 35 | def close(self): 36 | pass 37 | 38 | def register(self, fd, events): 39 | if fd in self.read_fds or fd in self.write_fds or fd in self.error_fds: 40 | raise IOError("fd %s already registered" % fd) 41 | if events & IOLoop.READ: 42 | self.read_fds.add(fd) 43 | if events & IOLoop.WRITE: 44 | self.write_fds.add(fd) 45 | if events & IOLoop.ERROR: 46 | self.error_fds.add(fd) 47 | # Closed connections are reported as errors by epoll and kqueue, 48 | # but as zero-byte reads by select, so when errors are requested 49 | # we need to listen for both read and error. 50 | # self.read_fds.add(fd) 51 | 52 | def modify(self, fd, events): 53 | self.unregister(fd) 54 | self.register(fd, events) 55 | 56 | def unregister(self, fd): 57 | self.read_fds.discard(fd) 58 | self.write_fds.discard(fd) 59 | self.error_fds.discard(fd) 60 | 61 | def poll(self, timeout): 62 | readable, writeable, errors = select.select( 63 | self.read_fds, self.write_fds, self.error_fds, timeout) 64 | events = {} 65 | for fd in readable: 66 | events[fd] = events.get(fd, 0) | IOLoop.READ 67 | for fd in writeable: 68 | events[fd] = events.get(fd, 0) | IOLoop.WRITE 69 | for fd in errors: 70 | events[fd] = events.get(fd, 0) | IOLoop.ERROR 71 | return events.items() 72 | 73 | 74 | class SelectIOLoop(PollIOLoop): 75 | def initialize(self, **kwargs): 76 | super(SelectIOLoop, self).initialize(impl=_Select(), **kwargs) 77 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/tornado/platform/windows.py: -------------------------------------------------------------------------------- 1 | # NOTE: win32 support is currently experimental, and not recommended 2 | # for production use. 3 | 4 | 5 | from __future__ import absolute_import, division, print_function, with_statement 6 | import ctypes 7 | import ctypes.wintypes 8 | 9 | # See: http://msdn.microsoft.com/en-us/library/ms724935(VS.85).aspx 10 | SetHandleInformation = ctypes.windll.kernel32.SetHandleInformation 11 | SetHandleInformation.argtypes = (ctypes.wintypes.HANDLE, ctypes.wintypes.DWORD, ctypes.wintypes.DWORD) 12 | SetHandleInformation.restype = ctypes.wintypes.BOOL 13 | 14 | HANDLE_FLAG_INHERIT = 0x00000001 15 | 16 | 17 | def set_close_exec(fd): 18 | success = SetHandleInformation(fd, HANDLE_FLAG_INHERIT, 0) 19 | if not success: 20 | raise ctypes.GetLastError() 21 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/tornado/speedups.c: -------------------------------------------------------------------------------- 1 | #define PY_SSIZE_T_CLEAN 2 | #include 3 | 4 | static PyObject* websocket_mask(PyObject* self, PyObject* args) { 5 | const char* mask; 6 | Py_ssize_t mask_len; 7 | const char* data; 8 | Py_ssize_t data_len; 9 | Py_ssize_t i; 10 | PyObject* result; 11 | char* buf; 12 | 13 | if (!PyArg_ParseTuple(args, "s#s#", &mask, &mask_len, &data, &data_len)) { 14 | return NULL; 15 | } 16 | 17 | result = PyBytes_FromStringAndSize(NULL, data_len); 18 | if (!result) { 19 | return NULL; 20 | } 21 | buf = PyBytes_AsString(result); 22 | for (i = 0; i < data_len; i++) { 23 | buf[i] = data[i] ^ mask[i % 4]; 24 | } 25 | 26 | return result; 27 | } 28 | 29 | static PyMethodDef methods[] = { 30 | {"websocket_mask", websocket_mask, METH_VARARGS, ""}, 31 | {NULL, NULL, 0, NULL} 32 | }; 33 | 34 | #if PY_MAJOR_VERSION >= 3 35 | static struct PyModuleDef speedupsmodule = { 36 | PyModuleDef_HEAD_INIT, 37 | "speedups", 38 | NULL, 39 | -1, 40 | methods 41 | }; 42 | 43 | PyMODINIT_FUNC 44 | PyInit_speedups() { 45 | return PyModule_Create(&speedupsmodule); 46 | } 47 | #else // Python 2.x 48 | PyMODINIT_FUNC 49 | initspeedups() { 50 | Py_InitModule("tornado.speedups", methods); 51 | } 52 | #endif 53 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/tornado/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/better-py/annotated-py-tornado/78fa3ab3b87a559c1db9ec11d86d79f6bf47853c/src/tornado-4.2.0/tornado/test/__init__.py -------------------------------------------------------------------------------- /src/tornado-4.2.0/tornado/test/__main__.py: -------------------------------------------------------------------------------- 1 | """Shim to allow python -m tornado.test. 2 | 3 | This only works in python 2.7+. 4 | """ 5 | from __future__ import absolute_import, division, print_function, with_statement 6 | 7 | from tornado.test.runtests import all, main 8 | 9 | # tornado.testing.main autodiscovery relies on 'all' being present in 10 | # the main module, so import it here even though it is not used directly. 11 | # The following line prevents a pyflakes warning. 12 | all = all 13 | 14 | main() 15 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/tornado/test/asyncio_test.py: -------------------------------------------------------------------------------- 1 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 2 | # not use this file except in compliance with the License. You may obtain 3 | # a copy of the License at 4 | # 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | # License for the specific language governing permissions and limitations 11 | # under the License. 12 | 13 | from __future__ import absolute_import, division, print_function, with_statement 14 | 15 | import sys 16 | import textwrap 17 | 18 | from tornado import gen 19 | from tornado.testing import AsyncTestCase, gen_test 20 | from tornado.test.util import unittest 21 | 22 | try: 23 | from tornado.platform.asyncio import asyncio, AsyncIOLoop 24 | except ImportError: 25 | asyncio = None 26 | 27 | skipIfNoSingleDispatch = unittest.skipIf( 28 | gen.singledispatch is None, "singledispatch module not present") 29 | 30 | 31 | @unittest.skipIf(asyncio is None, "asyncio module not present") 32 | class AsyncIOLoopTest(AsyncTestCase): 33 | def get_new_ioloop(self): 34 | io_loop = AsyncIOLoop() 35 | asyncio.set_event_loop(io_loop.asyncio_loop) 36 | return io_loop 37 | 38 | def test_asyncio_callback(self): 39 | # Basic test that the asyncio loop is set up correctly. 40 | asyncio.get_event_loop().call_soon(self.stop) 41 | self.wait() 42 | 43 | @skipIfNoSingleDispatch 44 | @gen_test 45 | def test_asyncio_future(self): 46 | # Test that we can yield an asyncio future from a tornado coroutine. 47 | # Without 'yield from', we must wrap coroutines in asyncio.async. 48 | x = yield asyncio.async( 49 | asyncio.get_event_loop().run_in_executor(None, lambda: 42)) 50 | self.assertEqual(x, 42) 51 | 52 | @unittest.skipIf(sys.version_info < (3, 3), 53 | 'PEP 380 not available') 54 | @skipIfNoSingleDispatch 55 | @gen_test 56 | def test_asyncio_yield_from(self): 57 | # Test that we can use asyncio coroutines with 'yield from' 58 | # instead of asyncio.async(). This requires python 3.3 syntax. 59 | global_namespace = dict(globals(), **locals()) 60 | local_namespace = {} 61 | exec(textwrap.dedent(""" 62 | @gen.coroutine 63 | def f(): 64 | event_loop = asyncio.get_event_loop() 65 | x = yield from event_loop.run_in_executor(None, lambda: 42) 66 | return x 67 | """), global_namespace, local_namespace) 68 | result = yield local_namespace['f']() 69 | self.assertEqual(result, 42) 70 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/tornado/test/csv_translations/fr_FR.csv: -------------------------------------------------------------------------------- 1 | "school","école" 2 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/tornado/test/gettext_translations/extract_me.py: -------------------------------------------------------------------------------- 1 | # flake8: noqa 2 | # Dummy source file to allow creation of the initial .po file in the 3 | # same way as a real project. I'm not entirely sure about the real 4 | # workflow here, but this seems to work. 5 | # 6 | # 1) xgettext --language=Python --keyword=_:1,2 --keyword=pgettext:1c,2 --keyword=pgettext:1c,2,3 extract_me.py -o tornado_test.po 7 | # 2) Edit tornado_test.po, setting CHARSET, Plural-Forms and setting msgstr 8 | # 3) msgfmt tornado_test.po -o tornado_test.mo 9 | # 4) Put the file in the proper location: $LANG/LC_MESSAGES 10 | 11 | from __future__ import absolute_import, division, print_function, with_statement 12 | _("school") 13 | pgettext("law", "right") 14 | pgettext("good", "right") 15 | pgettext("organization", "club", "clubs", 1) 16 | pgettext("stick", "club", "clubs", 1) 17 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/tornado/test/gettext_translations/fr_FR/LC_MESSAGES/tornado_test.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: PACKAGE VERSION\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2015-01-27 11:05+0300\n" 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 13 | "Last-Translator: FULL NAME \n" 14 | "Language-Team: LANGUAGE \n" 15 | "Language: \n" 16 | "MIME-Version: 1.0\n" 17 | "Content-Type: text/plain; charset=utf-8\n" 18 | "Content-Transfer-Encoding: 8bit\n" 19 | "Plural-Forms: nplurals=2; plural=(n > 1);\n" 20 | 21 | #: extract_me.py:11 22 | msgid "school" 23 | msgstr "école" 24 | 25 | #: extract_me.py:12 26 | msgctxt "law" 27 | msgid "right" 28 | msgstr "le droit" 29 | 30 | #: extract_me.py:13 31 | msgctxt "good" 32 | msgid "right" 33 | msgstr "le bien" 34 | 35 | #: extract_me.py:14 36 | msgctxt "organization" 37 | msgid "club" 38 | msgid_plural "clubs" 39 | msgstr[0] "le club" 40 | msgstr[1] "les clubs" 41 | 42 | #: extract_me.py:15 43 | msgctxt "stick" 44 | msgid "club" 45 | msgid_plural "clubs" 46 | msgstr[0] "le bâton" 47 | msgstr[1] "les bâtons" 48 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/tornado/test/import_test.py: -------------------------------------------------------------------------------- 1 | # flake8: noqa 2 | from __future__ import absolute_import, division, print_function, with_statement 3 | from tornado.test.util import unittest 4 | 5 | 6 | class ImportTest(unittest.TestCase): 7 | def test_import_everything(self): 8 | # Some of our modules are not otherwise tested. Import them 9 | # all (unless they have external dependencies) here to at 10 | # least ensure that there are no syntax errors. 11 | import tornado.auth 12 | import tornado.autoreload 13 | import tornado.concurrent 14 | # import tornado.curl_httpclient # depends on pycurl 15 | import tornado.escape 16 | import tornado.gen 17 | import tornado.http1connection 18 | import tornado.httpclient 19 | import tornado.httpserver 20 | import tornado.httputil 21 | import tornado.ioloop 22 | import tornado.iostream 23 | import tornado.locale 24 | import tornado.log 25 | import tornado.netutil 26 | import tornado.options 27 | import tornado.process 28 | import tornado.simple_httpclient 29 | import tornado.stack_context 30 | import tornado.tcpserver 31 | import tornado.template 32 | import tornado.testing 33 | import tornado.util 34 | import tornado.web 35 | import tornado.websocket 36 | import tornado.wsgi 37 | 38 | # for modules with dependencies, if those dependencies can be loaded, 39 | # load them too. 40 | 41 | def test_import_pycurl(self): 42 | try: 43 | import pycurl 44 | except ImportError: 45 | pass 46 | else: 47 | import tornado.curl_httpclient 48 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/tornado/test/options_test.cfg: -------------------------------------------------------------------------------- 1 | port=443 2 | port=443 3 | username='李康' -------------------------------------------------------------------------------- /src/tornado-4.2.0/tornado/test/resolve_test_helper.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import, division, print_function, with_statement 2 | from tornado.ioloop import IOLoop 3 | from tornado.netutil import ThreadedResolver 4 | from tornado.util import u 5 | 6 | # When this module is imported, it runs getaddrinfo on a thread. Since 7 | # the hostname is unicode, getaddrinfo attempts to import encodings.idna 8 | # but blocks on the import lock. Verify that ThreadedResolver avoids 9 | # this deadlock. 10 | 11 | resolver = ThreadedResolver() 12 | IOLoop.current().run_sync(lambda: resolver.resolve(u('localhost'), 80)) 13 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/tornado/test/static/dir/index.html: -------------------------------------------------------------------------------- 1 | this is the index 2 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/tornado/test/static/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: / 3 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/tornado/test/tcpserver_test.py: -------------------------------------------------------------------------------- 1 | import socket 2 | 3 | from tornado import gen 4 | from tornado.iostream import IOStream 5 | from tornado.log import app_log 6 | from tornado.stack_context import NullContext 7 | from tornado.tcpserver import TCPServer 8 | from tornado.testing import AsyncTestCase, ExpectLog, bind_unused_port, gen_test 9 | 10 | 11 | class TCPServerTest(AsyncTestCase): 12 | @gen_test 13 | def test_handle_stream_coroutine_logging(self): 14 | # handle_stream may be a coroutine and any exception in its 15 | # Future will be logged. 16 | class TestServer(TCPServer): 17 | @gen.coroutine 18 | def handle_stream(self, stream, address): 19 | yield gen.moment 20 | stream.close() 21 | 1/0 22 | 23 | server = client = None 24 | try: 25 | sock, port = bind_unused_port() 26 | with NullContext(): 27 | server = TestServer() 28 | server.add_socket(sock) 29 | client = IOStream(socket.socket()) 30 | with ExpectLog(app_log, "Exception in callback"): 31 | yield client.connect(('localhost', port)) 32 | yield client.read_until_close() 33 | yield gen.moment 34 | finally: 35 | if server is not None: 36 | server.stop() 37 | if client is not None: 38 | client.close() 39 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/tornado/test/templates/utf8.html: -------------------------------------------------------------------------------- 1 | Héllo 2 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/tornado/test/test.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICSDCCAbGgAwIBAgIJAN1oTowzMbkzMA0GCSqGSIb3DQEBBQUAMD0xCzAJBgNV 3 | BAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRkwFwYDVQQKDBBUb3JuYWRvIFdl 4 | YiBUZXN0MB4XDTEwMDgyNTE4MjQ0NFoXDTIwMDgyMjE4MjQ0NFowPTELMAkGA1UE 5 | BhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExGTAXBgNVBAoMEFRvcm5hZG8gV2Vi 6 | IFRlc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALirW3mX4jbdFse2aZwW 7 | zszCJ1IsRDrzALpbvMYLLbIZqo+Z8v5aERKTRQpXFqGaZyY+tdwYy7X7YXcLtKqv 8 | jnw/MSeIaqkw5pROKz5aR0nkPLvcTmhJVLVPCLc8dFnIlu8aC9TrDhr90P+PzU39 9 | UG7zLweA9zXKBuW3Tjo5dMP3AgMBAAGjUDBOMB0GA1UdDgQWBBRhJjMBYrzddCFr 10 | /0vvPyHMeqgo0TAfBgNVHSMEGDAWgBRhJjMBYrzddCFr/0vvPyHMeqgo0TAMBgNV 11 | HRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAGP6GaxSfb21bikcqaK3ZKCC1sRJ 12 | tiCuvJZbBUFUCAzl05dYUfJZim/oWK+GqyUkUB8ciYivUNnn9OtS7DnlTgT2ws2e 13 | lNgn5cuFXoAGcHXzVlHG3yoywYBf3y0Dn20uzrlLXUWJAzoSLOt2LTaXvwlgm7hF 14 | W1q8SQ6UBshRw2X0 15 | -----END CERTIFICATE----- 16 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/tornado/test/test.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBALirW3mX4jbdFse2 3 | aZwWzszCJ1IsRDrzALpbvMYLLbIZqo+Z8v5aERKTRQpXFqGaZyY+tdwYy7X7YXcL 4 | tKqvjnw/MSeIaqkw5pROKz5aR0nkPLvcTmhJVLVPCLc8dFnIlu8aC9TrDhr90P+P 5 | zU39UG7zLweA9zXKBuW3Tjo5dMP3AgMBAAECgYEAiygNaWYrf95AcUQi9w00zpUr 6 | nj9fNvCwxr2kVbRMvd2balS/CC4EmXPCXdVcZ3B7dBVjYzSIJV0Fh/iZLtnVysD9 7 | fcNMZ+Cz71b/T0ItsNYOsJk0qUVyP52uqsqkNppIPJsD19C+ZeMLZj6iEiylZyl8 8 | 2U16c/kVIjER63mUEGkCQQDayQOTGPJrKHqPAkUqzeJkfvHH2yCf+cySU+w6ezyr 9 | j9yxcq8aZoLusCebDVT+kz7RqnD5JePFvB38cMuepYBLAkEA2BTFdZx30f4moPNv 10 | JlXlPNJMUTUzsXG7n4vNc+18O5ous0NGQII8jZWrIcTrP8wiP9fF3JwUsKrJhcBn 11 | xRs3hQJBAIDUgz1YIE+HW3vgi1gkOh6RPdBAsVpiXtr/fggFz3j60qrO7FswaAMj 12 | SX8c/6KUlBYkNjgP3qruFf4zcUNvEzcCQQCaioCPFVE9ByBpjLG6IUTKsz2R9xL5 13 | nfYqrbpLZ1aq6iLsYvkjugHE4X57sHLwNfdo4dHJbnf9wqhO2MVe25BhAkBdKYpY 14 | 7OKc/2mmMbJDhVBgoixz/muN/5VjdfbvVY48naZkJF1p1tmogqPC5F1jPCS4rM+S 15 | FfPJIHRNEn2oktw5 16 | -----END PRIVATE KEY----- 17 | -------------------------------------------------------------------------------- /src/tornado-4.2.0/tornado/test/util.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import, division, print_function, with_statement 2 | 3 | import os 4 | import socket 5 | import sys 6 | 7 | from tornado.testing import bind_unused_port 8 | 9 | # Encapsulate the choice of unittest or unittest2 here. 10 | # To be used as 'from tornado.test.util import unittest'. 11 | if sys.version_info < (2, 7): 12 | # In py26, we must always use unittest2. 13 | import unittest2 as unittest 14 | else: 15 | # Otherwise, use whichever version of unittest was imported in 16 | # tornado.testing. 17 | from tornado.testing import unittest 18 | 19 | skipIfNonUnix = unittest.skipIf(os.name != 'posix' or sys.platform == 'cygwin', 20 | "non-unix platform") 21 | 22 | # travis-ci.org runs our tests in an overworked virtual machine, which makes 23 | # timing-related tests unreliable. 24 | skipOnTravis = unittest.skipIf('TRAVIS' in os.environ, 25 | 'timing tests unreliable on travis') 26 | 27 | # Set the environment variable NO_NETWORK=1 to disable any tests that 28 | # depend on an external network. 29 | skipIfNoNetwork = unittest.skipIf('NO_NETWORK' in os.environ, 30 | 'network access disabled') 31 | 32 | skipIfNoIPv6 = unittest.skipIf(not socket.has_ipv6, 'ipv6 support not present') 33 | 34 | 35 | def refusing_port(): 36 | """Returns a local port number that will refuse all connections. 37 | 38 | Return value is (cleanup_func, port); the cleanup function 39 | must be called to free the port to be reused. 40 | """ 41 | # On travis-ci, port numbers are reassigned frequently. To avoid 42 | # collisions with other tests, we use an open client-side socket's 43 | # ephemeral port number to ensure that nothing can listen on that 44 | # port. 45 | server_socket, port = bind_unused_port() 46 | server_socket.setblocking(1) 47 | client_socket = socket.socket() 48 | client_socket.connect(("127.0.0.1", port)) 49 | conn, client_addr = server_socket.accept() 50 | conn.close() 51 | server_socket.close() 52 | return (client_socket.close, client_addr[1]) 53 | --------------------------------------------------------------------------------