Completed
Pull Request — develop (#105)
by
unknown
01:21
created

MessageMetaClass.__new__()   A

Complexity

Conditions 1

Size

Total Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 2
rs 10
cc 1
1
# -*- coding: utf-8 -*-
2
3
import six
4
5
MESSAGE_TYPES = {}
6
7
8
class MessageMetaClass(type):
9
    def __new__(mcs, name, bases, attrs):
10
        return type.__new__(mcs, name, bases, attrs)
11
12
    def __init__(cls, name, bases, attrs):
13
        if '__type__' in attrs:
14
            if isinstance(attrs['__type__'], list):
15
                for _type in attrs['__type__']:
16
                    MESSAGE_TYPES[_type] = cls
17
            else:
18
                MESSAGE_TYPES[attrs['__type__']] = cls
19
        type.__init__(cls, name, bases, attrs)
20
21
22
class BaseEntry(object):
23
    INT = 0
24
    FLOAT = 1
25
    STRING = 2
26
27
    def __init__(self, entry, type, default=None):
28
        self.entry = entry
29
        self.default = default
30
        self.type = type
31
32
    def __get__(self, instance, owner):
33
        result = {
34
            self.INT: lambda v: int(v),
35
            self.FLOAT: lambda v: float(v),
36
            self.STRING: lambda v: v,
37
        }
38
        return result[self.type](instance.__dict__.get(self.entry, self.default))
39
40
41
class TupleEntry(object):
42
    FLOAT = 3
43
44
    def __init__(self, entry, type):
45
        self.entry1 = entry[0]
46
        self.entry2 = entry[1]
47
        self.type = type
48
49
    def __get__(self, instance, owner):
50
        result = {
51
            self.FLOAT: lambda v: float(v),
52
        }
53
        return result[self.type](instance.__dict__.get(self.entry1)), result[self.type](
54
            instance.__dict__.get(self.entry2))
55
56
57
@six.add_metaclass(MessageMetaClass)
58
class WeChatMessage(object):
59
    id = BaseEntry('MsgId', BaseEntry.INT, 0)
60
    target = BaseEntry('ToUserName', BaseEntry.STRING)
61
    source = BaseEntry('FromUserName', BaseEntry.STRING)
62
    time = BaseEntry('CreateTime', BaseEntry.INT, 0)
63
64
    def __init__(self, message):
65
        self.__dict__.update(message)
66
67
68
class TextMessage(WeChatMessage):
69
    __type__ = 'text'
70
    content = BaseEntry('Content', BaseEntry.STRING)
71
72
73
class ImageMessage(WeChatMessage):
74
    __type__ = 'image'
75
    img = BaseEntry('PicUrl', BaseEntry.STRING)
76
77
78
class LocationMessage(WeChatMessage):
79
    __type__ = 'location'
80
    location_x = BaseEntry('Location_X', BaseEntry.FLOAT)
81
    location_y = BaseEntry('Location_Y', BaseEntry.FLOAT)
82
    label = BaseEntry('Label', BaseEntry.STRING)
83
    scale = BaseEntry('Scale', BaseEntry.INT)
84
    location = TupleEntry(['Location_X', 'Location_Y'], TupleEntry.FLOAT)
85
86
87
class LinkMessage(WeChatMessage):
88
    __type__ = 'link'
89
    title = BaseEntry('Title', BaseEntry.STRING)
90
    description = BaseEntry('Description', BaseEntry.STRING)
91
    url = BaseEntry('Url', BaseEntry.STRING)
92
93
94
class EventMessage(WeChatMessage):
95
    __type__ = ['event']
96
97
    def __init__(self, message):
98
        message.pop("type")
99
        self.type = message.pop('Event')
100
        self.type = str(self.type).lower()
101
        if self.type == "click":
102
            self.__class__.key = BaseEntry('EventKey', BaseEntry.STRING)
103
        elif self.type == "location":
104
            self.__class__.latitude = BaseEntry('Latitude', BaseEntry.FLOAT)
105
            self.__class__.longitude = BaseEntry('Longitude', BaseEntry.FLOAT)
106
            self.__class__.precision = BaseEntry('Precision', BaseEntry.FLOAT)
107
        super(EventMessage, self).__init__(message)
108
109
110
class VoiceMessage(WeChatMessage):
111
    __type__ = 'voice'
112
    media_id = BaseEntry('MediaId', BaseEntry.STRING)
113
    format = BaseEntry('Format', BaseEntry.STRING)
114
    recognition = BaseEntry('Recognition', BaseEntry.STRING)
115
116
117
class VideoMessage(WeChatMessage):
118
    __type__ = ['video', 'shortvideo']
119
    media_id = BaseEntry('MediaId', BaseEntry.STRING)
120
    thumb_media_id = BaseEntry('ThumbMediaId', BaseEntry.STRING)
121
122
123
class UnknownMessage(WeChatMessage):
124
    __type__ = 'unknown'
125