def send(self, ctype, uin, content): self.msgId += 1 sendUrl = { 'buddy': 'http://d1.web2.qq.com/channel/send_buddy_msg2', 'group': 'http://d1.web2.qq.com/channel/send_qun_msg2', 'discuss': 'http://d1.web2.qq.com/channel/send_discu_msg2' } sendTag = {'buddy':'to', 'group':'group_uin', 'discuss':'did'} self.smartRequest( url = sendUrl[ctype], data = { 'r': JsonDumps({ sendTag[ctype]: int(uin), 'content': JsonDumps( FaceParse(content) + [['font', {'name': '宋体', 'size': 10, 'style': [0,0,0], 'color': '000000'}]] ), 'face': 522, 'clientid': self.clientid, 'msg_id': self.msgId, 'psessionid': self.psessionid }) }, Referer = ('http://d1.web2.qq.com/proxy.html?v=20151105001&' 'callback=1&id=2'), repeatOnDeny=5 )
def __init__(self, **kw): for tag in TAGS: if tag[:-1] not in kw: self.__dict__[tag[:-1]] = '' self.__dict__.update(kw) self.__dict__['shortRepr'] = '%s"%s"' % (CTYPES[self.ctype], self.name) self.__dict__['json'] = JsonDumps(self.__dict__, ensure_ascii=False)
def fetchBuddyTable(self): result = self.smartRequest( url='http://s.web2.qq.com/api/get_user_friends2', data={'r': JsonDumps({ 'vfwebqq': self.vfwebqq, 'hash': self.hash })}, Referer=('http://d1.web2.qq.com/proxy.html?v=20151105001&' 'callback=1&id=2'), expectedKey='marknames', repeatOnDeny=4) qqResult = self.smartRequest( url='http://qun.qq.com/cgi-bin/qun_mgr/get_friend_list', data={'bkn': self.bkn}, Referer='http://qun.qq.com/member.html') nameDict = {} for blist in list(qqResult.values()): for d in blist.get('mems', []): name = HTMLUnescape(d['name']) qq = str(d['uin']) nameDict[qq] = name buddies = [] for info in result['info']: uin = str(info['uin']) qq = str(info['nick']) name = nameDict.get(qq, '#NULL') nick = '#NULL' mark = '#NULL' buddies.append([qq, uin, nick, mark, name]) # 各属性的顺序绝对不能变 return buddies
def fetchBuddyTable(self): result = self.smartRequest( url = 'http://s.web2.qq.com/api/get_user_friends2', data = { 'r': JsonDumps({'vfwebqq':self.vfwebqq, 'hash':self.hash}) }, Referer = ('http://d1.web2.qq.com/proxy.html?v=20151105001&' 'callback=1&id=2'), expectedKey = 'marknames', repeatOnDeny = 4 ) markDict = dict((str(d['uin']), str(d['markname'])) for d in result['marknames']) qqResult = self.smartRequest( url = 'http://qun.qq.com/cgi-bin/qun_mgr/get_friend_list', data = {'bkn': self.bkn}, Referer = 'http://qun.qq.com/member.html' ) qqDict = collections.defaultdict(list) for blist in list(qqResult.values()): for d in blist.get('mems', []): name = HTMLUnescape(d['name']) qqDict[name].append(str(d['uin'])) buddies, unresolved, resolvedQQ = [], [], set() for info in result['info']: uin = str(info['uin']) nick = str(info['nick']) mark = markDict.get(uin, '') name = mark or nick qqlist = qqDict.get(name, []) if len(qqlist) == 1: qq = qqlist[0] resolvedQQ.add(qq) else: qq = '#NULL' unresolved.append('好友“%s”(uin=%s)' % (name, uin)) # 各属性的顺序绝对不能变 buddies.append([qq, uin, nick, mark, name]) for blist in list(qqResult.values()): for d in blist.get('mems', []): name = HTMLUnescape(d['name']) qq = str(d['uin']) if qq not in resolvedQQ: buddies.append([qq, '-'+qq, '#NULL', '#NULL', name]) if unresolved: unresolved.sort() WARN('因存在重名或名称中含特殊字符,无法绑定以下好友的真实QQ号,请修改其备' '注名,保证备注名的唯一性且不带特殊字符:\n\t%s', '\n\t'.join(unresolved)) return buddies
def Poll(self): result = self.smartRequest( url = 'https://d1.web2.qq.com/channel/poll2', data = { 'r': JsonDumps({ 'ptwebqq':self.ptwebqq, 'clientid':self.clientid, 'psessionid':self.psessionid, 'key':'' }) }, Referer = ('http://d1.web2.qq.com/proxy.html?v=20151105001&' 'callback=1&id=2') ) if not result or 'errmsg' in result: return 'timeout', '', '', '' else: result = result[0] ctype = { 'message': 'buddy', 'group_message': 'group', 'discu_message': 'discuss' }[result['poll_type']] fromUin = str(result['value']['from_uin']) memberUin = str(result['value'].get('send_uin', '')) content = FaceReverseParse(result['value']['content']) return ctype, fromUin, memberUin, content
def onTermCommand(bot, command): command = BYTES2STR(command) if command.startswith('GET /'): http = True end = command.find('\r\n') if end == -1 or not command[:end - 3].endswith(' HTTP/'): argv = [] else: url = command[5:end - 9].rstrip('/') if url == 'favicon.ico': return b'' argv = [Unquote(x) for x in url.split('/')] else: http = False argv = command.strip().split(None, 3) if argv and argv[0] in cmdFuncs: try: result, err = cmdFuncs[argv[0]](bot, argv[1:], http) except Exception as e: result, err = None, '运行命令过程中出错:' + str(type(e)) + str(e) ERROR(err, exc_info=True) else: result, err = None, 'QQBot 命令格式错误' if http: rep = {'result': result, 'err': err} rep = STR2BYTES(JsonDumps(rep, ensure_ascii=False, indent=4)) rep = (b'HTTP/1.1 200 OK\r\n' + b'Connection: close\r\n' + b'Content-Length: ' + STR2BYTES(str(len(rep))) + b'\r\n' + b'Content-Type: text/plain;charset=utf-8\r\n\r\n' + rep) else: rep = STR2BYTES(str(err or result)) + b'\r\n' return rep
def fetchGroupTable(self): qqResult = self.smartRequest( url='http://qun.qq.com/cgi-bin/qun_mgr/get_group_list', data={'bkn': self.bkn}, Referer='http://qun.qq.com/member.html' ) result = self.smartRequest( url='http://s.web2.qq.com/api/get_group_name_list_mask2', data={ 'r': JsonDumps({'vfwebqq': self.vfwebqq, 'hash': self.hash}) }, Referer=('http://d1.web2.qq.com/proxy.html?v=20151105001&' 'callback=1&id=2'), expectedKey='gmarklist', repeatOnDeny=6 ) markDict = dict((str(d['uin']), str(d['markname'])) \ for d in result['gmarklist']) qqDict = collections.defaultdict(list) for k in ('create', 'manage', 'join'): for d in qqResult.get(k, []): qqDict[HTMLUnescape(d['gn'])].append(str(d['gc'])) qqDict2 = getManaulGroupQQDict() groups, unresolved = [], [] for info in result['gnamelist']: uin = str(info['gid']) nick = str(info['name']) mark = markDict.get(uin, '') gcode = str(info['code']) if PY3: nick = nick.replace('\xa0', ' ') mark = mark.replace('\xa0', ' ') name = mark or nick qqlist = qqDict.get(nick, []) if len(qqlist) == 1: qq = qqlist[0] else: qqlist = qqDict2.get(nick, []) if len(qqlist) == 1: qq = qqlist[0] else: qq = '#NULL' unresolved.append('群“%s”(uin=%s)' % (name, uin)) groups.append([qq, uin, nick, mark, name, gcode]) if unresolved: unresolved.sort() WARN('因存在重名或名称中含特殊字符,无法绑定以下' '群的真实QQ号:\n\t%s', '\n\t'.join(unresolved)) return groups
def GroupShut(self, groupqq, qqlist, t): shutlist = JsonDumps([{'uin':int(qq), 't':t} for qq in qqlist]) self.smartRequest( url = 'http://qinfo.clt.qq.com/cgi-bin/qun_info/set_group_shutup', Referer = 'http://qinfo.clt.qq.com/qinfo_v3/member.html', data = {'gc':groupqq, 'bkn':self.bkn, 'shutup_list':shutlist}, expectedCodes = (0,), repeatOnDeny = 5 ) return qqlist
def fetchBuddyTable(self): buddyTable = QContactTable('buddy') result = self.smartRequest( url='http://s.web2.qq.com/api/get_user_friends2', data={ 'r': JsonDumps({ 'vfwebqq': self.vfwebqq, 'hash': self.hash }) }, Referer=('http://d1.web2.qq.com/proxy.html?v=20151105001&' 'callback=1&id=2'), expectedKey='marknames', repeatOnDeny=4) markDict = dict( (str(d['uin']), str(d['markname'])) for d in result['marknames']) qqResult = self.smartRequest( url='http://qun.qq.com/cgi-bin/qun_mgr/get_friend_list', data={'bkn': self.bkn}, Referer='http://qun.qq.com/member.html') qqDict = collections.defaultdict(list) for blist in list(qqResult.values()): for d in blist.get('mems', []): name = HTMLUnescape(d['name']) qqDict[name].append(str(d['uin'])) for info in result['info']: uin = str(info['uin']) nick = str(info['nick']) mark = markDict.get(uin, '') if PY3: nick = nick.replace('\xa0', ' ') mark = mark.replace('\xa0', ' ') name = mark or nick qqlist = qqDict.get(name, []) if len(qqlist) == 1: qq = qqlist.pop() else: qq = self.fetchBuddyQQ(uin) try: qqlist.remove(qq) except ValueError: pass buddyTable.Add(uin=uin, name=name, qq=qq, mark=mark, nick=nick) buddyTable.lastUpdateTime = time.time() return buddyTable
def fetchGroupTable(self): groupTable = QContactTable('group') result = self.smartRequest( url = 'http://s.web2.qq.com/api/get_group_name_list_mask2', data = { 'r': JsonDumps({'vfwebqq':self.vfwebqq, 'hash':self.hash}) }, Referer = ('http://d1.web2.qq.com/proxy.html?v=20151105001&' 'callback=1&id=2'), expectedKey = 'gmarklist', repeateOnDeny = 3 ) markDict = dict((str(d['uin']), str(d['markname'])) \ for d in result['gmarklist']) qqResult = self.smartRequest( url = 'http://qun.qq.com/cgi-bin/qun_mgr/get_group_list', data = {'bkn': self.bkn}, Referer = 'http://qun.qq.com/member.html' ) qqDict = collections.defaultdict(list) for k in ('create', 'manage', 'join'): for d in qqResult.get(k, []): name = d['gn'].replace(' ', ' ').replace('&', '&') qqDict[name].append(str(d['gc'])) for info in result['gnamelist']: uin = str(info['gid']) name = str(info['name']) mark = markDict.get(uin, '') qqlist = qqDict.get(name, []) if len(qqlist) == 1: qq = qqlist.pop() else: qq = self.fetchGroupQQ(uin) for x in qqlist: if qq[-6:] == x[-6:]: qq = x break try: qqlist.remove(qq) except ValueError: pass groupTable.Add(uin=uin, name=(mark or name), nick=name, qq=qq, mark=mark, gcode=str(info['code'])) groupTable.lastUpdateTime = time.time() return groupTable
def Poll(self): try: result = self.smartRequest( url='https://d1.web2.qq.com/channel/poll2', data={ 'r': JsonDumps({ 'ptwebqq': self.ptwebqq, 'clientid': self.clientid, 'psessionid': self.psessionid, 'key': '' }) }, Referer=('https://d1.web2.qq.com/proxy.html?v=20151105001&' 'callback=1&id=2'), expectedCodes=(0, 100003, 100100, 100012)) # "{'retcode': 0, 'retmsg': 'ok', 'errmsg': 'error'}" if type(result) is dict and \ result.get('retcode', 1) == 0 and \ result.get('errmsg', '') == 'error': DEBUG(result) raise RequestError except RequestError: ERROR('接收消息出错,开始测试登录 cookie 是否过期...') try: self.TestLogin() except RequestError: ERROR('登录 cookie 很可能已过期') raise else: INFO('登录 cookie 尚未过期') return 'timeout', '', '', '' else: if (not result) or (not isinstance(result, list)): DEBUG(result) return 'timeout', '', '', '' else: result = result[0] ctype = { 'message': 'buddy', 'group_message': 'group', 'discu_message': 'discuss' }[result['poll_type']] fromUin = str(result['value']['from_uin']) memberUin = str(result['value'].get('send_uin', '')) content = FaceReverseParse(result['value']['content']) return ctype, fromUin, memberUin, content
def getUinAndPsessionid(self): result = self.smartRequest( url = 'http://d1.web2.qq.com/channel/login2', data = { 'r': JsonDumps({ 'ptwebqq': self.ptwebqq, 'clientid': self.clientid, 'psessionid': '', 'status': 'online' }) }, Referer = ('http://d1.web2.qq.com/proxy.html?v=20151105001' '&callback=1&id=2'), Origin = 'http://d1.web2.qq.com' ) self.uin = result['uin'] self.psessionid = result['psessionid'] self.hash = qHash(self.uin, self.ptwebqq) self.bkn = bknHash(self.session.cookies['skey']) INFO('已获取uin和psessionid')
def fetchGroupTable(self): groupTable = QContactTable('group') qqResult = self.smartRequest( url='http://qun.qq.com/cgi-bin/qun_mgr/get_group_list', data={'bkn': self.bkn}, Referer='http://qun.qq.com/member.html') result = self.smartRequest( url='http://s.web2.qq.com/api/get_group_name_list_mask2', data={ 'r': JsonDumps({ 'vfwebqq': self.vfwebqq, 'hash': self.hash }) }, Referer=('http://d1.web2.qq.com/proxy.html?v=20151105001&' 'callback=1&id=2'), expectedKey='gmarklist', repeatOnDeny=6) markDict = dict((str(d['uin']), str(d['markname'])) \ for d in result['gmarklist']) qqDict = collections.defaultdict(list) for k in ('create', 'manage', 'join'): for d in qqResult.get(k, []): qqDict[HTMLUnescape(d['gn'])].append(str(d['gc'])) unresolved = [] for info in result['gnamelist']: uin = str(info['gid']) name = str(info['name']) mark = markDict.get(uin, '') if PY3: name = name.replace('\xa0', ' ') mark = mark.replace('\xa0', ' ') qqlist = qqDict.get(name, []) if len(qqlist) == 1: # 没有重名现象 qq = qqlist[0] qqDict.pop(name) elif len(qqlist) > 1: # 有重名现象 qq = self.fetchGroupQQ(uin) # 这里返回的qq号可能只有最后6位是对的 for trueQQ in qqlist[:]: if qq[-6:] == trueQQ[-6:]: qq = trueQQ qqlist.remove(trueQQ) break else: # 可能是 qun.qq.com 返回的 name 和 w.qq.com 返回的 name 不一致 # 比如: “x x” 和 “x x” ,尽管经过前面的转义处理,但可能还是 # 有没有转过来的 # 也可能是两次请求的空隙期间加入了一个新群(理论上有这种可能) unresolved.append((uin, name, mark)) continue groupTable.Add(uin=uin, name=(mark or name), nick=name, qq=qq, mark=mark, gcode=str(info['code'])) for uin, name, mark in unresolved: qq = self.fetchGroupQQ(uin) # 这里返回的qq号可能只有最后6位是对的 for xname, qqlist in list(qqDict.items()): for trueQQ in qqlist[:]: if qq[-6:] == trueQQ[-6:]: qq = trueQQ if len(qqlist) == 1: qqDict.pop(xname) else: qqlist.remove(qq) break else: continue break groupTable.Add(uin=uin, name=(mark or name), nick=name, qq=qq, mark=mark, gcode=str(info['code'])) groupTable.lastUpdateTime = time.time() return groupTable