def get_user_buy_info(cfg: Config): retrtCfg = cfg.common.retry default_user_buy_info = BuyInfo() for idx in range(retrtCfg.max_retry_count): try: # 默认设置首个qq为购买信息 default_user_buy_info.qq = uin2qq( cfg.account_configs[0].account_info.uin) uploader = Uploader(lanzou_cookie) buy_info_filepath = uploader.download_file_in_folder( uploader.folder_online_files, uploader.user_monthly_pay_info_filename, ".cached", show_log=False) buy_users = {} # type: Dict[str, BuyInfo] with open(buy_info_filepath, 'r', encoding='utf-8') as data_file: raw_infos = json.load(data_file) for qq, raw_info in raw_infos.items(): info = BuyInfo().auto_update_config(raw_info) buy_users[qq] = info for game_qq in info.game_qqs: buy_users[game_qq] = info if len(buy_users) == 0: # note: 如果读取失败或云盘该文件列表为空,则默认所有人都放行 default_user_buy_info.expire_at = "2120-01-01 00:00:00" return default_user_buy_info user_buy_info = default_user_buy_info for account_cfg in cfg.account_configs: qq = uin2qq(account_cfg.account_info.uin) if qq in buy_users: if time_less(user_buy_info.expire_at, buy_users[qq].expire_at): # 若当前配置的账号中有多个账号都付费了,选择其中付费结束时间最晚的那个 user_buy_info = buy_users[qq] return user_buy_info except Exception as e: logFunc = logger.debug if use_by_myself(): logFunc = logger.error logFunc(f"第{idx + 1}次检查是否付费时出错了,稍后重试", exc_info=e) time.sleep(retrtCfg.retry_wait_time) return default_user_buy_info
def _get_user_buy_info(cfg: Config): retrtCfg = cfg.common.retry default_user_buy_info = BuyInfo() for try_idx in range(retrtCfg.max_retry_count): try: # 默认设置首个qq为购买信息 default_user_buy_info.qq = uin2qq(cfg.account_configs[0].account_info.uin) uploader = Uploader(lanzou_cookie) has_no_users = True remote_filenames = [uploader.user_monthly_pay_info_filename, uploader.cs_user_monthly_pay_info_filename] import copy # 单种渠道内选择付费结束时间最晚的,手动和卡密间则叠加 user_buy_info_list = [copy.deepcopy(default_user_buy_info) for v in remote_filenames] for idx, remote_filename in enumerate(remote_filenames): user_buy_info = user_buy_info_list[idx] try: buy_info_filepath = uploader.download_file_in_folder(uploader.folder_online_files, remote_filename, ".cached", show_log=False) except FileNotFoundError as e: # 如果网盘没有这个文件,就跳过 continue buy_users = {} # type: Dict[str, BuyInfo] with open(buy_info_filepath, 'r', encoding='utf-8') as data_file: raw_infos = json.load(data_file) for qq, raw_info in raw_infos.items(): info = BuyInfo().auto_update_config(raw_info) buy_users[qq] = info for game_qq in info.game_qqs: buy_users[game_qq] = info if len(buy_users) != 0: has_no_users = False for account_cfg in cfg.account_configs: qq = uin2qq(account_cfg.account_info.uin) if qq in buy_users: if time_less(user_buy_info.expire_at, buy_users[qq].expire_at): # 若当前配置的账号中有多个账号都付费了,选择其中付费结束时间最晚的那个 user_buy_info = buy_users[qq] user_buy_info_list[idx] = user_buy_info if has_no_users: # note: 如果读取失败或云盘该文件列表为空,则默认所有人都放行 default_user_buy_info.expire_at = "2120-01-01 00:00:00" return default_user_buy_info merged_user_buy_info = copy.deepcopy(default_user_buy_info) for user_buy_info in user_buy_info_list: if user_buy_info.total_buy_month == 0: continue if merged_user_buy_info.total_buy_month == 0: merged_user_buy_info = copy.deepcopy(user_buy_info) else: merged_user_buy_info.merge(user_buy_info) return merged_user_buy_info except Exception as e: logFunc = logger.debug if use_by_myself(): logFunc = logger.error logFunc(f"第{try_idx + 1}次检查是否付费时出错了,稍后重试", exc_info=e) time.sleep(retrtCfg.retry_wait_time) return default_user_buy_info
def update_buy_user_local(order_infos: List[OrderInfo]): buy_users = {} # type: Dict[str, BuyInfo] if os.path.exists(local_save_path): with open(local_save_path, 'r', encoding='utf-8') as data_file: raw_infos = json.load(data_file) for qq, raw_info in raw_infos.items(): info = BuyInfo().auto_update_config(raw_info) buy_users[qq] = info datetime_fmt = "%Y-%m-%d %H:%M:%S" now = datetime.now() now_str = now.strftime(datetime_fmt) for order_info in order_infos: delta = timedelta(hours=24) if has_buy_recently(order_info.qq, delta): logger.error(f"{order_info.qq}在{delta}内已经处理过,是否是重复运行了?") continue if order_info.qq in buy_users: user_info = buy_users[order_info.qq] else: user_info = BuyInfo() user_info.qq = order_info.qq buy_users[order_info.qq] = user_info # 更新时长 expired_at = datetime.strptime(user_info.expire_at, datetime_fmt) if now > expired_at: # 已过期,从当前时间开始重新计算 start_time = now else: # 续期,从之前结束时间叠加 start_time = expired_at updated_expired_at = start_time + order_info.buy_month * month_inc user_info.expire_at = updated_expired_at.strftime(datetime_fmt) user_info.total_buy_month += order_info.buy_month user_info.buy_records.append(BuyRecord().auto_update_config({ "buy_month": order_info.buy_month, "buy_at": now_str, "reason": "购买", })) # 更新游戏QQ for game_qq in order_info.game_qqs: if game_qq not in user_info.game_qqs: user_info.game_qqs.append(game_qq) msg = f"{user_info.qq} 购买 {order_info.buy_month} 个月成功,过期时间为{user_info.expire_at},购买前过期时间为{expired_at}。累计购买{user_info.total_buy_month}个月。" msg += "购买详情如下:\n" + '\n'.join('\t' + f'{record.buy_at} {record.reason} {record.buy_month} 月' for record in user_info.buy_records) logger.info(msg) save_buy_timestamp(order_info.qq) with open(local_save_path, 'w', encoding='utf-8') as save_file: json.dump(to_raw_type(buy_users), save_file, indent=2, ensure_ascii=False) total_month = 0 for qq, user_info in buy_users.items(): if qq == "1054073896": # 跳过自己<_<,不然数据被污染了 continue total_month += user_info.total_buy_month total_money = 5 * total_month logger.info(color("bold_green") + f"目前总购买人数为{len(buy_users)},累计购买月数为{total_month},累积金额约为{total_money}")
def test_try_notify_new_pay_info(): qq_accounts = ["123", "456", "789"] # 准备初始付费信息 user_buy_info = BuyInfo() user_buy_info.qq = qq_accounts[0] user_buy_info.game_qqs = qq_accounts[1:] user_buy_info.append_records_and_recompute([ BuyRecord().auto_update_config({ "buy_month": 1, "buy_at": "2021-10-01 12:30:15", "reason": "购买" }), BuyRecord().auto_update_config({ "buy_month": 2, "buy_at": "2021-10-02 12:30:15", "reason": "购买" }), BuyRecord().auto_update_config({ "buy_month": 3, "buy_at": "2021-10-03 12:30:15", "reason": "购买" }), ]) # 清空数据 UserBuyInfoDB().with_context(str(qq_accounts)).reset() # 执行第一次查询 new_buy_dlc, new_buy_monthly_pay_records = try_notify_new_pay_info( qq_accounts, user_buy_info, show_message_box=False) # 在没有数据的情况下不应产生通知 assert new_buy_dlc is False assert len(new_buy_monthly_pay_records) == 0 # 增加1个月付费和购买dlc,再次执行查询 delta_normal_months = [ BuyRecord().auto_update_config({ "buy_month": 1, "buy_at": "2021-10-04 12:30:15", "reason": "购买" }), BuyRecord().auto_update_config({ "buy_month": 2, "buy_at": "2021-10-05 12:30:15", "reason": "购买" }), ] user_buy_info.append_records_and_recompute([ *delta_normal_months, BuyRecord().auto_update_config({ "buy_month": 2, "buy_at": "2021-02-08 00:00:00", "reason": "自动更新DLC赠送(自2.8至今最多累积未付费时长两个月***注意不是从购买日开始计算***)", }), ]) new_buy_dlc, new_buy_monthly_pay_records = try_notify_new_pay_info( qq_accounts, user_buy_info, show_message_box=False) # 确保通知有dlc和新的普通按月付费 assert new_buy_dlc is True assert new_buy_monthly_pay_records == delta_normal_months # 不做任何操作,再次执行操作 new_buy_dlc, new_buy_monthly_pay_records = try_notify_new_pay_info( qq_accounts, user_buy_info, show_message_box=False) # 确保未发生变化 assert new_buy_dlc is False assert len(new_buy_monthly_pay_records) == 0