# Path: wxpy/api/consts.py
# ATTACHMENT = 'Attachment'
# 
# PICTURE = 'Picture'
# 
# TEXT = 'Text'
# 
# VIDEO = 'Video'
# 
# Path: wxpy/compatible/utils.py
# def force_encoded_string_output(func):
# 
#     if sys.version_info.major < 3:
# 
#         def _func(*args, **kwargs):
#             return func(*args, **kwargs).encode(sys.stdout.encoding or 'utf-8')
# 
#         return _func
# 
#     else:
#         return func
# 
# Path: wxpy/utils/misc.py
# def handle_response(to_class=None):
#     """
#     装饰器：检查从 itchat 返回的字典对象，并将其转化为指定类的实例
#     若返回值不为0，会抛出 ResponseError 异常
# 
#     :param to_class: 需转化成的类，若为None则不转换
#     """
# 
#     def decorator(func):
#         @wraps(func)
#         def wrapped(*args, **kwargs):
#             ret = func(*args, **kwargs)
# 
#             if ret is None:
#                 return
# 
#             smart_map(check_response_body, ret)
# 
#             if to_class:
#                 if args:
#                     self = args[0]
#                 else:
#                     self = inspect.currentframe().f_back.f_locals.get('self')
# 
#                 from wxpy.api.bot import Bot
#                 if isinstance(self, Bot):
#                     bot = weakref.proxy(self)
#                 else:
#                     bot = getattr(self, 'bot', None)
#                     if not bot:
#                         raise ValueError('bot not found:m\nmethod: {}\nself: {}\nbot: {}'.format(
#                             func, self, bot
#                         ))
# 
#                 ret = smart_map(to_class, ret, bot)
# 
#                 if isinstance(ret, list):
#                     from wxpy.api.chats import Group
#                     if to_class == Group:
#                         from wxpy.api.chats import Groups
#                         ret = Groups(ret)
#                     else:
#                         from wxpy.api.chats import Chats
#                         ret = Chats(ret, bot)
# 
#             return ret
# 
#         return wrapped
# 
#     return decorator


import datetime
import logging
import re
import time
from functools import partial, wraps
from wxpy.api.consts import ATTACHMENT, PICTURE, TEXT, VIDEO
from wxpy.compatible import *
from wxpy.compatible.utils import force_encoded_string_output
from wxpy.utils import handle_response
            from wxpy import SentMessage
        from wxpy.utils import BaseRequest
        from wxpy.utils import BaseRequest
        from .group import Group
        from .member import Member
        from .friend import User
    send() 系列方法较为雷同，因此采用装饰器方式完成发送，并返回 SentMessage 对象
    """

    def decorator(func):
        @wraps(func)
        def wrapped(self, *args, **kwargs):

            # 用于初始化 SentMessage 的属性
            sent_attrs = dict(
                type=msg_type, receiver=self,
                create_time=datetime.datetime.now()
            )

            # 被装饰函数需要返回两个部分:
            # itchat_call_or_ret: 请求 itchat 原函数的参数字典 (或返回值字典)
            # sent_attrs_from_method: 方法中需要添加到 SentMessage 的属性字典
            itchat_call_or_ret, sent_attrs_from_method = func(self, *args, **kwargs)

            if msg_type:
                # 找到原 itchat 中的同名函数，并转化为指定了 `toUserName` 的偏函数
                itchat_partial_func = partial(
                    getattr(self.bot.core, func.__name__),
                    toUserName=self.user_name
                )

                logger.info('sending {} to {}:\n{}'.format(
                    func.__name__[5:], self,
                    sent_attrs_from_method.get('text') or sent_attrs_from_method.get('path')
                ))


# Path: wxpy/api/consts.py
# ATTACHMENT = 'Attachment'
# 
# PICTURE = 'Picture'
# 
# TEXT = 'Text'
# 
# VIDEO = 'Video'
# 
# Path: wxpy/compatible/utils.py
# def force_encoded_string_output(func):
# 
#     if sys.version_info.major < 3:
# 
#         def _func(*args, **kwargs):
#             return func(*args, **kwargs).encode(sys.stdout.encoding or 'utf-8')
# 
#         return _func
# 
#     else:
#         return func
# 
# Path: wxpy/utils/misc.py
# def handle_response(to_class=None):
#     """
#     装饰器：检查从 itchat 返回的字典对象，并将其转化为指定类的实例
#     若返回值不为0，会抛出 ResponseError 异常
# 
#     :param to_class: 需转化成的类，若为None则不转换
#     """
# 
#     def decorator(func):
#         @wraps(func)
#         def wrapped(*args, **kwargs):
#             ret = func(*args, **kwargs)
# 
#             if ret is None:
#                 return
# 
#             smart_map(check_response_body, ret)
# 
#             if to_class:
#                 if args:
#                     self = args[0]
#                 else:
#                     self = inspect.currentframe().f_back.f_locals.get('self')
# 
#                 from wxpy.api.bot import Bot
#                 if isinstance(self, Bot):
#                     bot = weakref.proxy(self)
#                 else:
#                     bot = getattr(self, 'bot', None)
#                     if not bot:
#                         raise ValueError('bot not found:m\nmethod: {}\nself: {}\nbot: {}'.format(
#                             func, self, bot
#                         ))
# 
#                 ret = smart_map(to_class, ret, bot)
# 
#                 if isinstance(ret, list):
#                     from wxpy.api.chats import Group
#                     if to_class == Group:
#                         from wxpy.api.chats import Groups
#                         ret = Groups(ret)
#                     else:
#                         from wxpy.api.chats import Chats
#                         ret = Chats(ret, bot)
# 
#             return ret
# 
#         return wrapped
# 
#     return decorator


# Path: wxpy/api/chats/chat.py
import datetime
import logging
import re
import time
from functools import partial, wraps
from wxpy.api.consts import ATTACHMENT, PICTURE, TEXT, VIDEO
from wxpy.compatible import *
from wxpy.compatible.utils import force_encoded_string_output
from wxpy.utils import handle_response
            from wxpy import SentMessage
        from wxpy.utils import BaseRequest
        from wxpy.utils import BaseRequest
        from .group import Group
        from .member import Member
        from .friend import User

    send() 系列方法较为雷同，因此采用装饰器方式完成发送，并返回 SentMessage 对象
    """

    def decorator(func):
        @wraps(func)
        def wrapped(self, *args, **kwargs):

            # 用于初始化 SentMessage 的属性
            sent_attrs = dict(
                type=msg_type, receiver=self,
                create_time=datetime.datetime.now()
            )

            # 被装饰函数需要返回两个部分:
            # itchat_call_or_ret: 请求 itchat 原函数的参数字典 (或返回值字典)
            # sent_attrs_from_method: 方法中需要添加到 SentMessage 的属性字典
            itchat_call_or_ret, sent_attrs_from_method = func(self, *args, **kwargs)

            if msg_type:
                # 找到原 itchat 中的同名函数，并转化为指定了 `toUserName` 的偏函数
                itchat_partial_func = partial(
                    getattr(self.bot.core, func.__name__),
                    toUserName=self.user_name
                )

                logger.info('sending {} to {}:\n{}'.format(
                    func.__name__[5:], self,
                    sent_attrs_from_method.get('text') or sent_attrs_from_method.get('path')
                ))


                @handle_response()