Skip to content

Commit

Permalink
Merge fc3ddcf into a74f586
Browse files Browse the repository at this point in the history
  • Loading branch information
helloqiu committed Jun 21, 2016
2 parents a74f586 + fc3ddcf commit 289e4a2
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 52 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -5,6 +5,7 @@

# Packages
*.egg
.egg
*.egg-info
dist
build
Expand Down Expand Up @@ -56,3 +57,4 @@ werobot_session*
pip-selfcheck.json
venv

venv
137 changes: 85 additions & 52 deletions werobot/messages.py
@@ -1,91 +1,124 @@
# -*- coding: utf-8 -*-

import six

MESSAGE_TYPES = {}


def handle_for_type(type):
def register(f):
MESSAGE_TYPES[type] = f
return f
return register
class MessageMetaClass(type):
def __new__(mcs, name, bases, attrs):
return type.__new__(mcs, name, bases, attrs)

def __init__(cls, name, bases, attrs):
if '__type__' in attrs:
if isinstance(attrs['__type__'], list):
for _type in attrs['__type__']:
MESSAGE_TYPES[_type] = cls
else:
MESSAGE_TYPES[attrs['__type__']] = cls
type.__init__(cls, name, bases, attrs)


class BaseEntry(object):
INT = 0
FLOAT = 1
STRING = 2

def __init__(self, entry, type, default=None):
self.entry = entry
self.default = default
self.type = type

def __get__(self, instance, owner):
result = {
self.INT: lambda v: int(v),
self.FLOAT: lambda v: float(v),
self.STRING: lambda v: v,
}
return result[self.type](instance.__dict__.get(self.entry, self.default))


class TupleEntry(object):
FLOAT = 3

def __init__(self, entry, type):
self.entry1 = entry[0]
self.entry2 = entry[1]
self.type = type

def __get__(self, instance, owner):
result = {
self.FLOAT: lambda v: float(v),
}
return result[self.type](instance.__dict__.get(self.entry1)), result[self.type](
instance.__dict__.get(self.entry2))


@six.add_metaclass(MessageMetaClass)
class WeChatMessage(object):
id = BaseEntry('MsgId', BaseEntry.INT, 0)
target = BaseEntry('ToUserName', BaseEntry.STRING)
source = BaseEntry('FromUserName', BaseEntry.STRING)
time = BaseEntry('CreateTime', BaseEntry.INT, 0)

def __init__(self, message):
self.id = int(message.pop("MsgId", 0))
self.target = message.pop("ToUserName", None)
self.source = message.pop('FromUserName', None)
self.time = int(message.get('CreateTime', 0))
self.__dict__.update(message)


@handle_for_type("text")
class TextMessage(WeChatMessage):
def __init__(self, message):
self.content = message.pop("Content")
super(TextMessage, self).__init__(message)
__type__ = 'text'
content = BaseEntry('Content', BaseEntry.STRING)


@handle_for_type("image")
class ImageMessage(WeChatMessage):
def __init__(self, message):
self.img = message.pop("PicUrl")
super(ImageMessage, self).__init__(message)
__type__ = 'image'
img = BaseEntry('PicUrl', BaseEntry.STRING)


@handle_for_type("location")
class LocationMessage(WeChatMessage):
def __init__(self, message):
location_x = message.pop('Location_X')
location_y = message.pop('Location_Y')
self.location = (float(location_x), float(location_y))
self.scale = int(message.pop('Scale'))
self.label = message.pop('Label')
super(LocationMessage, self).__init__(message)
__type__ = 'location'
location_x = BaseEntry('Location_X', BaseEntry.FLOAT)
location_y = BaseEntry('Location_Y', BaseEntry.FLOAT)
label = BaseEntry('Label', BaseEntry.STRING)
scale = BaseEntry('Scale', BaseEntry.INT)
location = TupleEntry(['Location_X', 'Location_Y'], TupleEntry.FLOAT)


@handle_for_type("link")
class LinkMessage(WeChatMessage):
def __init__(self, message):
self.title = message.pop('Title')
self.description = message.pop('Description')
self.url = message.pop('Url')
super(LinkMessage, self).__init__(message)
__type__ = 'link'
title = BaseEntry('Title', BaseEntry.STRING)
description = BaseEntry('Description', BaseEntry.STRING)
url = BaseEntry('Url', BaseEntry.STRING)


@handle_for_type("event")
class EventMessage(WeChatMessage):
__type__ = ['event']

def __init__(self, message):
message.pop("type")
self.type = message.pop("Event").lower()
self.type = message.pop('Event')
self.type = str(self.type).lower()
if self.type == "click":
self.key = message.pop('EventKey')
self.__class__.key = BaseEntry('EventKey', BaseEntry.STRING)
elif self.type == "location":
self.latitude = float(message.pop("Latitude"))
self.longitude = float(message.pop("Longitude"))
self.precision = float(message.pop("Precision"))
self.__class__.latitude = BaseEntry('Latitude', BaseEntry.FLOAT)
self.__class__.longitude = BaseEntry('Longitude', BaseEntry.FLOAT)
self.__class__.precision = BaseEntry('Precision', BaseEntry.FLOAT)
super(EventMessage, self).__init__(message)


@handle_for_type("voice")
class VoiceMessage(WeChatMessage):
def __init__(self, message):
self.media_id = message.pop('MediaId')
self.format = message.pop('Format')
self.recognition = message.pop('Recognition')
super(VoiceMessage, self).__init__(message)
__type__ = 'voice'
media_id = BaseEntry('MediaId', BaseEntry.STRING)
format = BaseEntry('Format', BaseEntry.STRING)
recognition = BaseEntry('Recognition', BaseEntry.STRING)


@handle_for_type("video")
@handle_for_type("shortvideo")
class VideoMessage(WeChatMessage):
def __init__(self, message):
self.media_id = message.pop('MediaId')
self.thumb_media_id = message.pop('ThumbMediaId')
super(VideoMessage, self).__init__(message)
__type__ = ['video', 'shortvideo']
media_id = BaseEntry('MediaId', BaseEntry.STRING)
thumb_media_id = BaseEntry('ThumbMediaId', BaseEntry.STRING)


class UnknownMessage(WeChatMessage):
def __init__(self, message):
self.type = 'unknown'
super(UnknownMessage, self).__init__(message)
__type__ = 'unknown'

0 comments on commit 289e4a2

Please sign in to comment.