Skip to content

Commit

Permalink
Merge branch 'release/v0.3.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
whtsky committed Feb 14, 2013
2 parents 3109098 + 26b1f68 commit b7bcc3a
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 37 deletions.
7 changes: 4 additions & 3 deletions docs/conf.py
Expand Up @@ -16,7 +16,8 @@
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
sys.path.insert(0, os.path.abspath('..'))
import werobot

# -- General configuration -----------------------------------------------------

Expand Down Expand Up @@ -48,9 +49,9 @@
# built documents.
#
# The short X.Y version.
version = '0.3'
version = werobot.__version__
# The full version, including alpha/beta/rc tags.
release = '0.3.0'
release = werobot.__version__

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
134 changes: 120 additions & 14 deletions docs/index.rst
Expand Up @@ -160,7 +160,9 @@ WeRoBot 一共有5类 Message , 6种 type 。显然,一个 handler 不可能

robot.run()

你也可以使用 `robot.image` 修饰符来只接受图像信息; `robot.location` 修饰符来只接受位置信息;`robot.enter`修饰符来只接受进入会话信息。。
你也可以使用 ``robot.image`` 修饰符来只接受图像信息;
``robot.location`` 修饰符来只接受位置信息;
``robot.enter`` 修饰符来只接受进入会话信息。

.. note:: `robot.location` 修饰符会让你的 handler 接受到两类消息——位置信息和事件推送中的地理位置。

Expand Down Expand Up @@ -300,18 +302,18 @@ MusicReply

`MusicReply` 是音乐消息,构造函数的参数如下:

========= ===================================
name value
========= ===================================
target 信息的目标用户。通常是机器人用户。
source 信息的来源用户。通常是发送信息的用户。
time 信息发送的时间,一个UNIX时间戳。默认情况下会使用当前时间。
title 标题
description 描述
url 音乐链接
hq_url 高质量音乐链接,WIFI环境优先使用该链接播放音乐。可为空 [3]_
flag 如果是True, WeRoBot会对这条消息进行星标。你可以在公众平台后台看到所有的星标消息。
========= ===================================
============= ======================================================================
name value
============= ======================================================================
target 信息的目标用户。通常是机器人用户。
source 信息的来源用户。通常是发送信息的用户。
time 信息发送的时间,一个UNIX时间戳。默认情况下会使用当前时间。
title 标题
description 描述
url 音乐链接
hq_url 高质量音乐链接,WIFI环境优先使用该链接播放音乐。可为空 [3]_
flag 如果是True, WeRoBot会对这条消息进行星标。你可以在公众平台后台看到所有的星标消息。
============= ======================================================================

你也可以让你的 handler 返回一个长度为三或四的列表, [3]_
WeRoBot 会将其自动转为 MusicReply 。就像这样: ::
Expand Down Expand Up @@ -342,6 +344,106 @@ flag 如果是True, WeRoBot会对这条消息进行星标。你可以

.. [3] 如果你省略了高质量音乐链接的地址, WeRoBot 会自动将音乐链接的地址用于高质量音乐链接。
部署
---------------------
在独立服务器上部署
~~~~~~~~~~~~~~~~~~~~~~
当你运行 `werobot.run` 的时候,你可以通过传递 `server` 参数来手动指定使用的服务器 ::

import werobot

robot = werobot.WeRoBot(token='tokenhere')

@robot.handler
def echo(message):
return 'Hello World!'

robot.run(server='tornado')

server 支持以下几种:

+ cgi
+ flup
+ wsgiref
+ waitress
+ cherrypy
+ paste
+ fapws3
+ tornado
+ gae
+ twisted
+ diesel
+ meinheld
+ gunicorn
+ eventlet
+ gevent
+ rocket
+ bjoern
+ auto

当 server 为 auto 时, WeRoBot 会自动依次尝试以下几种服务器:

+ Waitress
+ Paste
+ Twisted
+ CherryPy
+ WSGIRef

所以,只要你安装了相应的服务器软件,就可以使用 ``werobot.run`` 直接跑在生产环境下。

.. note:: server 的默认值为 ``auto``

使用 Supervisor 管理守护进程
##################################

请注意, ``werobot.run`` 是跑在 **非守护进程模式下** 的——也就是说,一旦你关闭终端,进程就会自动退出。

我们建议您使用 `Supervisor <http://supervisord.org/>`_ 来管理 WeRoBot 的进程。

配置文件样例: ::

[program:wechat_robot]
command = python /home/whtsky/robot.py
user = whtsky
redirect_stderr = true
stdout_logfile = /home/whtsky/logs/robot.log

使用 Nginx 进行反向代理
################################

微信服务器只支持80端口的机器人——显然,你的服务器上不会只跑着一个微信机器人。对于这种情况,我们建议您使用 Nginx 来进行反向代理。

配置文件样例: ::

server {
server_name example.com;
listen 80;

location / {
proxy_pass_header Server;
proxy_redirect off;
proxy_pass http://127.0.0.1:8888;
}
}

.. note:: 在这个例子中, WeRoBot 的端口号为8888。你应该在微信管理后台中将服务器地址设为 ``http://example.com`` 。

在SAE上部署
~~~~~~~~~~~~~~~~~

``werobot.app`` 是一个标准的 WSGI Application 。 如果你想在 SAE 上部署 WeRoBot ,可以参考以下代码 ::

import werobot

robot = werobot.WeRoBot(token='tokenhere')

@robot.handler
def echo(message):
return 'Hello World!'

application = sae.create_wsgi_app(robot.app)


不知道该用什么Token?
----------------------
WeRoBot帮你准备了一个Token生成器: ::
Expand Down Expand Up @@ -371,7 +473,11 @@ Via Alipay(支付宝) ::
Changelog
-----------

Version 0.3.1
~~~~~~~~~~~~~~~~
+ Add `server` param in werobot.run

Version 0.3.0
~~~~~~~~~~~~~~~~

Add new messages and replies support for WeChat 4.5
+ Add new messages and replies support for WeChat 4.5
1 change: 0 additions & 1 deletion setup.py
Expand Up @@ -32,7 +32,6 @@
'Operating System :: POSIX',
'Operating System :: POSIX :: Linux',
'Programming Language :: Python',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.1',
'Programming Language :: Python :: 3.2',
Expand Down
2 changes: 1 addition & 1 deletion werobot/__init__.py
@@ -1,4 +1,4 @@
# -*- coding: utf-8 -*-
__version__ = '0.3.0'
__version__ = '0.3.1'

from .robot import WeRoBot
40 changes: 24 additions & 16 deletions werobot/parser.py
Expand Up @@ -11,36 +11,44 @@


def parse_user_msg(xml):
"""
Parse xml from wechat server and return an Message
:param xml: raw xml from wechat server.
:return: an Message object
"""
if not xml:
return None
parser = ElementTree.fromstring(xml)
msg_type = to_unicode(parser.find('MsgType').text)
touser = to_unicode(parser.find('ToUserName').text)
fromuser = to_unicode(parser.find('FromUserName').text)
create_at = int(parser.find('CreateTime').text)
return

_msg = dict((child.tag, to_unicode(child.text))
for child in ElementTree.fromstring(xml))

msg_type = _msg.get('MsgType')
touser = _msg.get('ToUserName')
fromuser = _msg.get('FromUserName')
create_at = int(_msg.get('CreateTime'))
msg = dict(
touser=touser,
fromuser=fromuser,
time=create_at
)
if msg_type == MSG_TYPE_TEXT:
msg["content"] = to_unicode(parser.find('Content').text)
msg["content"] = _msg.get('Content')
return TextMessage(**msg)
elif msg_type == MSG_TYPE_LOCATION:
msg["location_x"] = to_unicode(parser.find('Location_X').text)
msg["location_y"] = to_unicode(parser.find('Location_Y').text)
msg["scale"] = int(parser.find('Scale').text)
msg["label"] = to_unicode(parser.find('Label').text)
msg["location_x"] = _msg.get('Location_X')
msg["location_y"] = _msg.get('Location_Y')
msg["scale"] = int(_msg.get('Scale'))
msg["label"] = _msg.get('Label')
return LocationMessage(**msg)
elif msg_type == MSG_TYPE_IMAGE:
msg["img"] = to_unicode(parser.find('PicUrl').text)
msg["img"] = _msg.get('PicUrl')
return ImageMessage(**msg)
elif msg_type == MSG_TYPE_EVENT:
msg["type"] = to_unicode(parser.find('Event').text).lower()
msg["type"] = _msg.get('Event').lower()
if msg["type"] == "location":
msg["latitude"] = to_unicode(parser.find('Latitude').text)
msg["longitude"] = to_unicode(parser.find('Longitude').text)
msg["precision"] = to_unicode(parser.find('Precision').text)
msg["latitude"] = _msg.get('Latitude')
msg["longitude"] = _msg.get('Longitude')
msg["precision"] = _msg.get('Precision')
return EventMessage(**msg)
else:
return UnknownMessage(xml)
4 changes: 2 additions & 2 deletions werobot/robot.py
Expand Up @@ -118,6 +118,6 @@ def _get_reply(self, message):
if reply:
return reply

def run(self, port=8888):
def run(self, server='auto', port=8888):
enable_pretty_logging()
self.app.run(server='auto', host='0.0.0.0', port=port)
self.app.run(server=server, host='0.0.0.0', port=port)

0 comments on commit b7bcc3a

Please sign in to comment.