113 lines
5.3 KiB
Python
113 lines
5.3 KiB
Python
import redis
|
||
import xml.etree.ElementTree as ET
|
||
|
||
from wcferry import Wcf
|
||
|
||
|
||
|
||
class GroupMemberChange:
|
||
def __init__(self, wcf: Wcf):
|
||
self.wcf = wcf # 假设 wcf 对象在此类中初始化
|
||
self.r = redis.Redis(host='192.168.2.32', port=6379, db=0, decode_responses=True)
|
||
# 初始化本地缓存字典,使用 group_id 作为键
|
||
self.local_membercounts = {}
|
||
self.local_members = {}
|
||
|
||
def get_current_members(self, group_id):
|
||
""" 获取当前群成员信息 """
|
||
print(f"Fetching current members for group_id: {group_id}")
|
||
members = self.wcf.get_chatroom_members(group_id) # 假设返回的数据格式是 {wxid1: 昵称1, wxid2: 昵称2, ...}
|
||
print(f"Current members: {members}")
|
||
return members
|
||
|
||
def get_previous_data_from_redis(self, group_id):
|
||
""" 从 Redis 获取上次的数据 """
|
||
membercount_key = f"group:group_member_count:{group_id}"
|
||
members_key = f"group:group_members:{group_id}"
|
||
|
||
# 读取 Redis 中的数据
|
||
print(f"Fetching previous data from Redis for group_id: {group_id}")
|
||
membercount_previous = self.r.get(membercount_key)
|
||
members_previous = self.r.hgetall(members_key) # 获取上次的成员信息
|
||
print(f"Previous membercount: {membercount_previous}, Previous members: {members_previous}")
|
||
return membercount_previous, members_previous
|
||
|
||
def process_message(self, group_id, xml_data_current):
|
||
""" 处理消息并更新 Redis """
|
||
root_current = ET.fromstring(xml_data_current)
|
||
membercount_current = root_current.find('membercount').text
|
||
|
||
result = [] # 初始化文案列表
|
||
|
||
# 检查是否存在本地缓存数据,如果不存在,则从 Redis 获取
|
||
if group_id not in self.local_membercounts or group_id not in self.local_members:
|
||
print("No local data, fetching from Redis")
|
||
membercount_previous, members_previous = self.get_previous_data_from_redis(group_id)
|
||
|
||
# 如果没有上次的数据,说明是第一次处理,直接存储本次数据
|
||
if membercount_previous is None or not members_previous:
|
||
print("First time processing, saving current data to Redis")
|
||
members_current = self.get_current_members(group_id)
|
||
self.r.set(f"group:group_member_count:{group_id}", membercount_current)
|
||
self.r.delete(f"group:group_members:{group_id}")
|
||
self.r.hset(f"group:group_members:{group_id}", mapping=members_current) # 存储当前成员信息
|
||
|
||
# 更新本地缓存
|
||
self.local_membercounts[group_id] = membercount_current
|
||
self.local_members[group_id] = members_current
|
||
|
||
result.append("$NO_CHANGE$")
|
||
return "\n".join(result)
|
||
else:
|
||
# 如果 Redis 中有数据,就更新本地缓存
|
||
self.local_membercounts[group_id] = membercount_previous
|
||
self.local_members[group_id] = members_previous
|
||
else:
|
||
# 使用本地缓存的数据进行比较
|
||
membercount_previous = self.local_membercounts[group_id]
|
||
members_previous = self.local_members[group_id]
|
||
|
||
# 比较 membercount 是否发生变化
|
||
if membercount_current != membercount_previous:
|
||
print(f"Membercount changed: {membercount_previous} -> {membercount_current}")
|
||
members_current = self.get_current_members(group_id)
|
||
|
||
# TODO 如果用户达到了500人,则删除该群自动添加内容
|
||
|
||
# 比较成员,仅使用 wxid 进行比较
|
||
members_current_set = set(members_current.keys())
|
||
members_previous_set = set(members_previous.keys())
|
||
|
||
added_members = members_current_set - members_previous_set
|
||
removed_members = members_previous_set - members_current_set
|
||
|
||
# 添加变化成员的文案
|
||
for wxid in added_members:
|
||
nickname = members_current[wxid]
|
||
result.append(f"检测到\n {nickname}({wxid})\n加入群聊")
|
||
for wxid in removed_members:
|
||
nickname = members_previous[wxid]
|
||
result.append(f"检测到\n {nickname}({wxid})\n退出群聊")
|
||
|
||
# 更新本地缓存
|
||
print(f"Updating local cache with current membercount and members")
|
||
self.local_membercounts[group_id] = membercount_current
|
||
self.local_members[group_id] = members_current
|
||
print(f"Current membercount: {membercount_current}, Current members: {members_current}")
|
||
print(
|
||
f"Local Current membercount: {self.local_membercounts[group_id]}, Local Current members: {self.local_members[group_id]}")
|
||
|
||
# 更新 Redis 数据
|
||
print(f"Updating Redis with current membercount and members")
|
||
self.r.set(f"group:group_member_count:{group_id}", membercount_current)
|
||
|
||
self.r.delete(f"group:group_members:{group_id}")
|
||
# 更新 Redis 中的成员信息,确保在成员变化时也更新
|
||
self.r.hset(f"group:group_members:{group_id}", mapping=members_current)
|
||
|
||
else:
|
||
result.append("$NO_CHANGE$")
|
||
|
||
# 返回拼接后的结果
|
||
return "\n".join(result)
|