def process_args(self, kwargs): args = defaultdict(str) for k, v in kwargs.items(): if is_string(v): v = to_text(v) args[k] = v return args
class ArticlesReply(WeChatReply): TEMPLATE = to_text(""" <xml> <ToUserName><![CDATA[{target}]]></ToUserName> <FromUserName><![CDATA[{source}]]></FromUserName> <CreateTime>{time}</CreateTime> <MsgType><![CDATA[news]]></MsgType> <ArticleCount>{count}</ArticleCount> <Articles>{items}</Articles> </xml> """) def __init__(self, message=None, **kwargs): super(ArticlesReply, self).__init__(message, **kwargs) self._articles = [] def add_article(self, article): if len(self._articles) >= 10: raise AttributeError("Can't add more than 10 articles" " in an ArticlesReply") else: self._articles.append(article) def render(self): items = [] for article in self._articles: items.append(article.render()) self._args["items"] = ''.join(items) self._args["count"] = len(items) if "content" not in self._args: self._args["content"] = '' return ArticlesReply.TEMPLATE.format(**self._args)
class TextReply(WeChatReply): TEMPLATE = to_text(""" <xml> <ToUserName><![CDATA[{target}]]></ToUserName> <FromUserName><![CDATA[{source}]]></FromUserName> <CreateTime>{time}</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[{content}]]></Content> </xml> """)
def encrypt_message(self, reply, timestamp=None, nonce=None): """ 加密微信回复 :param reply: 加密前的回复 :type reply: WeChatReply 或 XML 文本 :return: 加密后的回复文本 """ if hasattr(reply, "render"): reply = reply.render() timestamp = timestamp or to_text(int(time.time())) nonce = nonce or generate_token(5) encrypt = to_text(self.prp_crypto.encrypt(reply, self.corp_id)) signature = get_signature(self.token, timestamp, nonce, encrypt) return to_text( self.ENCRYPTED_MESSAGE_XML.format(encrypt=encrypt, signature=signature, timestamp=timestamp, nonce=nonce))
class VoiceReply(WeChatReply): TEMPLATE = to_text(""" <xml> <ToUserName><![CDATA[{target}]]></ToUserName> <FromUserName><![CDATA[{source}]]></FromUserName> <CreateTime>{time}</CreateTime> <MsgType><![CDATA[voice]]></MsgType> <Voice> <MediaId><![CDATA[{media_id}]]></MediaId> </Voice> </xml> """)
def update_department(self, department_id, name): """ 修改分组名。 :param department_id: 分组 ID,由微信分配 :param name: 分组名字(30个字符以内) :return: 返回的 JSON 数据包 """ return self.post( url="https://qyapi.weixin.qq.com/cgi-bin/departments/update", data={ "department": { "id": int(department_id), "name": to_text(name) } })
def __init__(self, message=None, **kwargs): if message and "source" not in kwargs: kwargs["source"] = message.target if message and "target" not in kwargs: kwargs["target"] = message.source if 'time' not in kwargs: kwargs["time"] = int(time.time()) args = defaultdict(str) for k, v in kwargs.items(): if is_string(v): v = to_text(v) args[k] = v self.process_args(args) self._args = args
def create_department(self, name, parentid, order=None, id=None): """ 创建分组。 :param name: 分组名字(30个字符以内) :return: 返回的 JSON 数据包 """ name = to_text(name) return self.post( url="https://qyapi.weixin.qq.com/cgi-bin/departments/create", data={ "name": name, "parentid": parentid, "order": order, "id": id })
class VideoReply(WeChatReply): TEMPLATE = to_text(""" <xml> <ToUserName><![CDATA[{target}]]></ToUserName> <FromUserName><![CDATA[{source}]]></FromUserName> <CreateTime>{time}</CreateTime> <MsgType><![CDATA[video]]></MsgType> <Video> <MediaId><![CDATA[{media_id}]]></MediaId> <Title><![CDATA[{title}]]></Title> <Description><![CDATA[{description}]]></Description> </Video> </xml> """) def process_args(self, args): args.setdefault('title', '') args.setdefault('description', '')
def decrypt(self, text, corp_id): """ 对密文进行解密 :param text: 需要解密的密文 :param corp_id: 微信公众平台的 AppID :return: 解密后的字符串 """ text = to_binary(text) decryptor = self.cipher.decryptor() plain_text = decryptor.update( base64.b64decode(text)) + decryptor.finalize() padding = byte2int(plain_text, -1) content = plain_text[16:-padding] xml_len = socket.ntohl(struct.unpack("I", content[:4])[0]) xml_content = content[4:xml_len + 4] from_appid = content[xml_len + 4:] if to_text(from_appid) != corp_id: raise AppIdValidationError(text, corp_id) return xml_content
def add_filter(self, func, rules): """ 为 BaseRoBot 添加一个 ``filter handler``。 :param func: 如果 rules 通过,则处理该消息的 handler。 :param rules: 一个 list,包含要匹配的字符串或者正则表达式。 :return: None """ if not callable(func): raise ValueError("{} is not callable".format(func)) if not isinstance(rules, list): raise ValueError("{} is not list".format(rules)) if len(rules) > 1: for x in rules: self.add_filter(func, [x]) else: target_content = rules[0] if isinstance(target_content, six.string_types): target_content = to_text(target_content) def _check_content(message): return message.content == target_content elif is_regex(target_content): def _check_content(message): return target_content.match(message.content) else: raise TypeError("%s is not a valid rule" % target_content) argc = len(signature(func).parameters.keys()) @self.text def _f(message, session=None): _check_result = _check_content(message) if _check_result: if isinstance(_check_result, bool): _check_result = None return func(*[message, session, _check_result][:argc])
def render(self): return to_text(self.TEMPLATE.format(**self._args))
def render(self): return to_text( self.__TEMPLATE__.format(**self.process_args(self.args)))
</Video> </xml> """) def process_args(self, args): args.setdefault('title', '') args.setdefault('description', '') Article = renderable_named_tuple(typename="Article", field_names=("title", "description", "img", "url"), tempalte=to_text(""" <item> <Title><![CDATA[{title}]]></Title> <Description><![CDATA[{description}]]></Description> <PicUrl><![CDATA[{img}]]></PicUrl> <Url><![CDATA[{url}]]></Url> </item> """)) class ArticlesReply(WeChatReply): TEMPLATE = to_text(""" <xml> <ToUserName><![CDATA[{target}]]></ToUserName> <FromUserName><![CDATA[{source}]]></FromUserName> <CreateTime>{time}</CreateTime> <MsgType><![CDATA[news]]></MsgType> <ArticleCount>{count}</ArticleCount> <Articles>{items}</Articles> </xml>
def __get__(self, instance, owner): v = get_value(instance, self.entry, self.default) if v is not None: return to_text(v) return v