Skip to content
This repository has been archived by the owner on Aug 23, 2020. It is now read-only.

Commit

Permalink
所有好友、群成员的QQ都可以绑定了
Browse files Browse the repository at this point in the history
  • Loading branch information
pandolia committed May 12, 2017
1 parent 1b22fd9 commit db68403
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 73 deletions.
6 changes: 5 additions & 1 deletion changes
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
2017-05-11 qqbot v2.2.10
2017-05-12 qqbot v2.2.10
1) 根据测试结果, poll 消息时不再忽略 103 代码。
2) 绝大部分情况下,所有好友以及所有群成员的 qq 都可以绑定了,也就是说:绝大部分情况下, onQQMessage 中的 contact.qq 或 member.qq 都是有效的 QQ 号码。
感谢腾讯更改协议, webqq 可直接返回已绑定的 qq-uin 。
3) 本次更改协议的副作用:好友的 nick 属性和 mark 属性都不再有意义了(暂时),这两个属性永远都是 '#NULL' ,但可以使用好友的 name 属性。
如果有网友的机器人程序利用了这两个属性,需要修改代码。

2017-05-11 qqbot v2.2.9
1) 修正某些 linux 系统下 python2 下 sqlite3 数据库文件路径 bug ,感谢 lang 反馈问题。
Expand Down
4 changes: 2 additions & 2 deletions qcontact-attr.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@

- `b.uin` : str 对象,好友的 uin ,每次登录时分配的一个随机 id

- `b.nick` : str 对象,好友的昵称,当无法获取时为 '#NULL'
- `b.nick` : str 对象,永远为 '#NULL'

- `b.mark` : str 对象,好友的备注名,当无法获取时为 '#NULL'
- `b.mark` : str 对象,永远为 '#NULL'

- `b.name` : str 对象,当设置了备注名时为备注名,否则为昵称,当无法获取时为 'uin'+b.uin

Expand Down
93 changes: 23 additions & 70 deletions qqbot/qcontactdb/fetch.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,43 +26,28 @@ def fetchBuddyTable(self):
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)
nameDict = {}
for blist in list(qqResult.values()):
for d in blist.get('mems', []):
name = HTMLUnescape(d['name'])
qqDict[name].append(str(d['uin']))

buddies, unresolved = [], []

qq = str(d['uin'])
nameDict[qq] = name
buddies = []
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]
else:
qq = '#NULL'
unresolved.append('好友“%s”(uin=%s)' % (name, uin))

# 各属性的顺序绝对不能变
buddies.append([qq, uin, nick, mark, name])

if unresolved:
unresolved.sort()
WARN('因存在重名或名称中含特殊字符,无法绑定以下好友的真实QQ号,请修改其备'
'注名,保证备注名的唯一性且不带特殊字符:\n\t%s', '\n\t'.join(unresolved))
qq = str(info['nick'])
name = nameDict.get(qq, '#NULL')
nick = '#NULL'
mark = '#NULL'
buddies.append([qq, uin, nick, mark, name]) # 各属性的顺序绝对不能变

return buddies

Expand Down Expand Up @@ -133,9 +118,14 @@ def fetchGroupMemberTable(self, group):
expectedKey = 'minfo',
repeatOnDeny = 5
)

uinDict = {}
for m, inf in zip(result['ginfo']['members'], result['minfo']):
uin = str(m['muin'])
qq = str(inf['nick'])
uinDict[qq] = uin

cardDict = collections.defaultdict(list)
nickDict = collections.defaultdict(list)
membs = []
if group.qq != '#NULL':
r = self.smartRequest(
url='http://qinfo.clt.qq.com/cgi-bin/qun_info/get_group_members_new',
Expand All @@ -145,6 +135,9 @@ def fetchGroupMemberTable(self, group):

for m in r['mems']:
qq = str(m['u'])
if qq not in uinDict:
continue
uin = uinDict[qq]
nick = HTMLUnescape(m['n'])
card = HTMLUnescape(r.get('cards', {}).get(qq, ''))
mark = HTMLUnescape(r.get('remarks', {}).get(qq, ''))
Expand All @@ -165,52 +158,12 @@ def fetchGroupMemberTable(self, group):
levelname = HTMLUnescape(r.get('levelname', {}).get('lvln' + str(level), ''))
point = r.get('lv', {}).get(qq, {}).get('p', 0)

memb = [qq, None, nick, mark, card, name, join_time, last_speak_time,
memb = [qq, uin, nick, mark, card, name, join_time, last_speak_time,
role, role_id, is_buddy, level, levelname, point]

if card:
cardDict[STR2BYTES(card)[:18]].append(memb)

nickDict[nick].append(memb)

membss, unresolved = [], []
ucDict = dict((str(it['muin']), it['card']) for it in result.get('cards', {}))
for m, inf in zip(result['ginfo']['members'], result['minfo']):
uin, nick = str(m['muin']), str(inf['nick'])
card = ucDict.get(uin, '')
if not PY3:
card = card.replace('\xc2\xa0', ' ')
nick = nick.replace('\xc2\xa0', ' ')
else:
card = card.replace('\xa0', ' ')
nick = nick.replace('\xa0', ' ')
name = card or nick

membs = nickDict.get(nick, [])
if len(membs) == 1:
memb = membs[0]
else:
membs = cardDict.get(STR2BYTES(card)[:18], [])
if len(membs) == 1:
memb = membs[0]
else:
memb = None

if memb is None:
unresolved.append('成员“%s”(uin=%s)' % (name, uin))
memb = ['#NULL', uin, nick, mark, card, name, -1, -1,
'#NULL', -1, -1, -1, '#NULL', -1]
else:
memb[1] = uin

membss.append(memb)

if unresolved:
unresolved.sort()
WARN('因存在重名或名称中含特殊字符,无法绑定 %s 中以下'
'成员的真实QQ号:\n\t%s', group, '\n\t'.join(unresolved))
membs.append(memb)

return membss
return membs

def fetchDiscussTable(self):
result = self.smartRequest(
Expand Down

1 comment on commit db68403

@feisuweb
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good 就等你这个功能。

Please sign in to comment.