174 lines
4.2 KiB
Python
174 lines
4.2 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
wechatpy.messages
|
|
~~~~~~~~~~~~~~~~~~
|
|
|
|
This module defines all the messages you can get from WeChat server
|
|
|
|
:copyright: (c) 2014 by messense.
|
|
:license: MIT, see LICENSE for more details.
|
|
"""
|
|
from __future__ import absolute_import, unicode_literals
|
|
import copy
|
|
import six
|
|
|
|
from wechatpy.fields import (
|
|
BaseField,
|
|
StringField,
|
|
IntegerField,
|
|
DateTimeField,
|
|
FieldDescriptor
|
|
)
|
|
from wechatpy.utils import to_text, to_binary
|
|
|
|
|
|
MESSAGE_TYPES = {}
|
|
|
|
|
|
def register_message(msg_type):
|
|
def register(cls):
|
|
MESSAGE_TYPES[msg_type] = cls
|
|
return cls
|
|
return register
|
|
|
|
|
|
class MessageMetaClass(type):
|
|
"""Metaclass for all messages"""
|
|
def __new__(cls, name, bases, attrs):
|
|
for b in bases:
|
|
if not hasattr(b, '_fields'):
|
|
continue
|
|
|
|
for k, v in b.__dict__.items():
|
|
if k in attrs:
|
|
continue
|
|
if isinstance(v, FieldDescriptor):
|
|
attrs[k] = copy.deepcopy(v.field)
|
|
|
|
cls = super(MessageMetaClass, cls).__new__(cls, name, bases, attrs)
|
|
cls._fields = {}
|
|
|
|
for name, field in cls.__dict__.items():
|
|
if isinstance(field, BaseField):
|
|
field.add_to_class(cls, name)
|
|
return cls
|
|
|
|
|
|
class BaseMessage(six.with_metaclass(MessageMetaClass)):
|
|
"""Base class for all messages and events"""
|
|
type = 'unknown'
|
|
id = IntegerField('MsgId', 0)
|
|
source = StringField('FromUserName')
|
|
target = StringField('ToUserName')
|
|
create_time = DateTimeField('CreateTime')
|
|
time = IntegerField('CreateTime')
|
|
|
|
def __init__(self, message):
|
|
self._data = message
|
|
|
|
def __repr__(self):
|
|
_repr = "{klass}({msg})".format(
|
|
klass=self.__class__.__name__,
|
|
msg=repr(self._data)
|
|
)
|
|
if six.PY2:
|
|
return to_binary(_repr)
|
|
else:
|
|
return to_text(_repr)
|
|
|
|
|
|
@register_message('text')
|
|
class TextMessage(BaseMessage):
|
|
"""
|
|
文本消息
|
|
详情请参阅
|
|
http://mp.weixin.qq.com/wiki/10/79502792eef98d6e0c6e1739da387346.html
|
|
"""
|
|
type = 'text'
|
|
content = StringField('Content')
|
|
|
|
|
|
@register_message('image')
|
|
class ImageMessage(BaseMessage):
|
|
"""
|
|
图片消息
|
|
详情请参阅
|
|
http://mp.weixin.qq.com/wiki/10/79502792eef98d6e0c6e1739da387346.html
|
|
"""
|
|
type = 'image'
|
|
media_id = StringField('MediaId')
|
|
image = StringField('PicUrl')
|
|
|
|
|
|
@register_message('voice')
|
|
class VoiceMessage(BaseMessage):
|
|
"""
|
|
语音消息
|
|
详情请参阅
|
|
http://mp.weixin.qq.com/wiki/10/79502792eef98d6e0c6e1739da387346.html
|
|
"""
|
|
type = 'voice'
|
|
media_id = StringField('MediaId')
|
|
format = StringField('Format')
|
|
recognition = StringField('Recognition')
|
|
|
|
|
|
@register_message('shortvideo')
|
|
class ShortVideoMessage(BaseMessage):
|
|
"""
|
|
短视频消息
|
|
详情请参阅
|
|
http://mp.weixin.qq.com/wiki/10/79502792eef98d6e0c6e1739da387346.html
|
|
"""
|
|
type = 'shortvideo'
|
|
media_id = StringField('MediaId')
|
|
thumb_media_id = StringField('ThumbMediaId')
|
|
|
|
|
|
@register_message('video')
|
|
class VideoMessage(BaseMessage):
|
|
"""
|
|
视频消息
|
|
详情请参阅
|
|
http://mp.weixin.qq.com/wiki/10/79502792eef98d6e0c6e1739da387346.html
|
|
"""
|
|
type = 'video'
|
|
media_id = StringField('MediaId')
|
|
thumb_media_id = StringField('ThumbMediaId')
|
|
|
|
|
|
@register_message('location')
|
|
class LocationMessage(BaseMessage):
|
|
"""
|
|
地理位置消息
|
|
详情请参阅
|
|
http://mp.weixin.qq.com/wiki/10/79502792eef98d6e0c6e1739da387346.html
|
|
"""
|
|
type = 'location'
|
|
location_x = StringField('Location_X')
|
|
location_y = StringField('Location_Y')
|
|
scale = StringField('Scale')
|
|
label = StringField('Label')
|
|
|
|
@property
|
|
def location(self):
|
|
return self.location_x, self.location_y
|
|
|
|
|
|
@register_message('link')
|
|
class LinkMessage(BaseMessage):
|
|
"""
|
|
链接消息
|
|
详情请参阅
|
|
http://mp.weixin.qq.com/wiki/10/79502792eef98d6e0c6e1739da387346.html
|
|
"""
|
|
type = 'link'
|
|
title = StringField('Title')
|
|
description = StringField('Description')
|
|
url = StringField('Url')
|
|
|
|
|
|
class UnknownMessage(BaseMessage):
|
|
"""未知消息类型"""
|
|
pass
|