wechatpy.parser.parse_message()   D
last analyzed

Complexity

Conditions 12

Size

Total Lines 35
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 12.0092

Importance

Changes 0
Metric Value
cc 12
eloc 25
nop 1
dl 0
loc 35
rs 4.8
c 0
b 0
f 0
ccs 24
cts 25
cp 0.96
crap 12.0092

How to fix   Complexity   

Complexity

Complex classes like wechatpy.parser.parse_message() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
# -*- coding: utf-8 -*-
2 10
"""
3
    wechatpy.parser
4
    ~~~~~~~~~~~~~~~~
5
    This module provides functions for parsing WeChat messages
6
7
    :copyright: (c) 2014 by messense.
8
    :license: MIT, see LICENSE for more details.
9
"""
10 10
from __future__ import absolute_import, unicode_literals
11 10
import xmltodict
12
13 10
from wechatpy.messages import MESSAGE_TYPES, UnknownMessage
14 10
from wechatpy.events import EVENT_TYPES
15 10
from wechatpy.utils import to_text
16
17
18 10
def parse_message(xml):
19
    """
20
    解析微信服务器推送的 XML 消息
21
22
    :param xml: XML 消息
23
    :return: 解析成功返回对应的消息或事件,否则返回 ``UnknownMessage``
24
    """
25 10
    if not xml:
26
        return
27 10
    message = xmltodict.parse(to_text(xml))['xml']
28 10
    message_type = message['MsgType'].lower()
29 10
    event_type = None
30 10
    if message_type == 'event' or message_type.startswith('device_'):
31 10
        if 'Event' in message:
32 10
            event_type = message['Event'].lower()
33
        # special event type for device_event
34 10
        if event_type is None and message_type.startswith('device_'):
35 10
            event_type = message_type
36 10
        elif message_type.startswith('device_'):
37 10
            event_type = 'device_{event}'.format(event=event_type)
38
39 10
        if event_type == 'subscribe' and message.get('EventKey'):
40 10
            event_key = message['EventKey']
41 10
            if event_key.startswith(('scanbarcode|', 'scanimage|')):
42 10
                event_type = 'subscribe_scan_product'
43 10
                message['Event'] = event_type
44 10
            elif event_key.startswith('qrscene_'):
45
                # Scan to subscribe with scene id event
46 10
                event_type = 'subscribe_scan'
47 10
                message['Event'] = event_type
48 10
                message['EventKey'] = event_key[len('qrscene_'):]
49 10
        message_class = EVENT_TYPES.get(event_type, UnknownMessage)
50
    else:
51 10
        message_class = MESSAGE_TYPES.get(message_type, UnknownMessage)
52
    return message_class(message)
53