wxpy.api.chats.chat 源代码

# coding: utf-8
from __future__ import unicode_literals

import logging

from wxpy.api.messages import SentMessage
from wxpy.api.messages.message_types import *
from wxpy.compatible import PY2
from wxpy.compatible.utils import force_encoded_string_output

if PY2:
    # noinspection PyUnresolvedReferences
    from urlparse import urljoin
else:
    from urllib.parse import urljoin

logger = logging.getLogger(__name__)


[文档]class Chat(object): def __init__(self, core, _chat): """ 基本聊天对象 单个用户 (:class:`User`) 和群聊 (:class:`Group`) 的基础类 :param core: 关联的内核对象 :param _chat: username 或 原始数据 dict """ self.core = core self.bot = self.core.bot self._chat = _chat @property def puid(self): """ 持续有效,且稳定唯一的聊天对象/用户ID,适用于持久保存 请使用 :any:`Bot.enable_puid()` 来启用 puid 属性 .. tip:: | :any:`puid <Chat.puid>` 是 **wxpy 特有的聊天对象/用户ID** | 不同于其他 ID 属性,**puid** 可始终被获取到,且具有稳定的唯一性 .. attention:: puid 映射数据 **不可跨机器人使用** """ if self.core.puid_map: return self.core.puid_map.get_puid(self) else: raise TypeError('puid is not enabled, you can enable it by `bot.enable_puid()`') @property def nickname(self): """ 该聊天对象的昵称 (好友、群员的昵称,或群名称) """ nickname = self.raw.get('NickName') if nickname: return nickname elif self.username == self.core.username: return self.core.name @property def name(self): """ | 该聊天对象的友好名称 | 即: 从 备注名称、群聊显示名称、昵称(或群名称),username 中按序选取第一个可用的 """ for attr in 'remark_name', 'display_name', 'nickname', 'username': _name = getattr(self, attr, None) if _name: return _name
[文档] def send(self, content, msg_type=None, media_id=None): """ 发送消息。默认为发送文本消息,也可指定其他消息类型 :param content: 消息类型为 TEXT 时为消息的文本内容,其他类型时为文件路径 :param msg_type: 消息类型,支持 TEXT, IMAGE, STICKER, VIDEO, FILE (默认为 TEXT) :param media_id: 文件在服务器中的唯一 ID,填写后可省略上传步骤 :return: 已发送的消息 :rtype: :class:`SentMessage` """ return self.core.send(self, content, msg_type, media_id)
[文档] def send_image(self, path, media_id=None): """ 发送图片 :param path: 图片的文件路径 :param media_id: 文件在服务器中的唯一 ID,填写后可省略上传步骤 :return: 已发送的消息 :rtype: :class:`SentMessage` """ return self.send(path, IMAGE, media_id)
[文档] def send_sticker(self, path, media_id=None): """ 发送表情 (类似于手机端中发送收藏的表情) :param path: 表情图片的文件路径 :param media_id: 文件在服务器中的唯一 ID,填写后可省略上传步骤 :return: 已发送的消息 :rtype: :class:`SentMessage` """ return self.send(path, STICKER, media_id)
[文档] def send_video(self, path, media_id=None): """ 发送视频 :param path: 视频的文件路径 (通常为 mp4 格式) :param media_id: 文件在服务器中的唯一 ID,填写后可省略上传步骤 :return: 已发送的消息 :rtype: :class:`SentMessage` """ return self.send(path, VIDEO, media_id)
[文档] def send_file(self, path, media_id=None): """ 发送文件 :param path: 文件路径 :param media_id: 文件在服务器中的唯一 ID,填写后可省略上传步骤 :return: 已发送的消息 :rtype: :class:`SentMessage` """ return self.send(path, FILE, media_id)
[文档] def send_card(self, wxid, friend_or_mp): """ 发送好友名片或公众号名片 (被发送的名片必须为好友关系或已关注的公众号) :param wxid: 好友或公众号的微信ID (无法直接获取,需要手动填写) :param friend_or_mp: 好友对象或公众号对象 """ card_name = friend_or_mp.nickname if isinstance(friend_or_mp, Chat) else friend_or_mp logger.info('sending {} to {}: {}'.format(CARD, self, card_name)) return self.core.send( self, content='<msg username="{}" nickname="{}"/>'.format(wxid, card_name), msg_type=CARD, url=self.core.uris.send_msg, text=card_name )
[文档] def mark_as_read(self): """ 消除当前聊天对象的未读提示小红点 """ logger.debug('marking {} as read'.format(self)) return self.core.status_notify(self.core.username, self.username, 1)
[文档] def pin(self): """ 将聊天对象置顶 """ logger.info('pinning {}'.format(self)) return self.core.op_log(self, 3, 1)
[文档] def unpin(self): """ 取消聊天对象的置顶状态 """ logger.info('unpinning {}'.format(self)) return self.core.op_log(self, 3, 0)
[文档] def get_avatar(self, save_path=None): """ 获取头像 :param save_path: 保存路径(后缀通常为.jpg),若空则直接返回字节数据 """ logger.info('getting avatar of {}'.format(self)) if self.raw.get('HeadImgUrl'): return self.core.download(urljoin(self.core.uris.current_page, self.raw['HeadImgUrl']), save_path) else: raise ValueError('failed to get the avatar url for {}'.format(self))
@property def raw(self): """ 原始数据 """ if isinstance(self._chat, dict): return self._chat else: return self.core.data.raw_chats.get(self._chat, dict()) @property def username(self): """ 该聊天对象的内部 ID,会随着登陆会话而改变,通常不需要用到 .. attention:: 此 ID 在机器人重新登录后 **会被改变** ! """ if PY2: if isinstance(self._chat, unicode): return self._chat else: return self._chat['UserName'] else: if isinstance(self._chat, str): return self._chat else: return self._chat['UserName']
[文档] def update(self): """ 更新聊天对象的详细信息 .. tip:: | 对于群聊对象,`group.update()` 仅更新群本身,而不会更新群成员的详细信息 | 若要更新群员信息,可使用 `group.members.update()` """ self.core.batch_get_contact(self)
@force_encoded_string_output def __repr__(self): return self.__unicode__() def __unicode__(self): return '<{}: {}>'.format(self.__class__.__name__, self.name) def __eq__(self, other): return hash(self) == hash(other) def __cmp__(self, other): return 0 if self.__eq__(other) else 1 def __hash__(self): return hash((Chat, self.username))