HenryXiaoYang / XYBot

XYBot是一个可运行于Linux和Windows的基于Hook的微信机器人🤖️!✅高度可自定义! ✅支持自我编写插件!非常多的功能:天气🌤️、获取新闻📰、ChatGPT聊天🗣️、Hypixel玩家查询🎮、随机图片📷、随机链接🔗、随机群成员👥、五子棋♟️、签到✅、查询积分📊、积分榜🏆、积分转送💰、积分抽奖🎁、积分红包🧧等
https://henryxiaoyang.github.io/XYBot/
GNU General Public License v3.0
347 stars 39 forks source link

查找一个时区出错,不能签到 #50

Closed Sendu-sanxing closed 2 months ago

Sendu-sanxing commented 2 months ago

'No time zone found with key Asia/Shanghai'

电脑自身时区设置没有问题,同时写了脚本发现依赖也没有问题,不知道怎么改 (时区检测脚本) from dateutil import tz from datetime import datetime

def test_timezone(timezone_str): try: timezone = tz.gettz(timezone_str) datetime.now(timezone) print(f"时区 {timezone_str} 设置成功。当前时间:{datetime.now(timezone)}") except Exception as e: print(f"设置时区出错:{e}")

if name == "main": test_timezone("Asia/Shanghai")

Sendu-sanxing commented 2 months ago

通过添加 fallback 机制解决了

import random from datetime import datetime from zoneinfo import ZoneInfo from dateutil import tz

import yaml from loguru import logger

import pywxdll from utils.database import BotDatabase from utils.plugin_interface import PluginInterface

def get_timezone_object(timezone_str): """ 尝试使用 zoneinfo 加载时区,如果失败则使用 dateutil.tz 作为回退。 """ try: return ZoneInfo(timezone_str) except ZoneInfoNotFoundError: logger.warning(f"ZoneInfo not found for {timezone_str}, falling back to dateutil.") return tz.gettz(timezone_str)

class sign_in(PluginInterface): def init(self): config_path = "plugins/sign_in.yml" with open(config_path, "r", encoding="utf-8") as f: config = yaml.safe_load(f)

    self.min_points = config["min_points"]
    self.max_points = config["max_points"]

    main_config_path = "main_config.yml"
    with open(main_config_path, "r", encoding="utf-8") as f:
        main_config = yaml.safe_load(f)

    self.ip = main_config["ip"]
    self.port = main_config["port"]
    self.timezone_str = main_config["timezone"]

    self.timezone = get_timezone_object(self.timezone_str)  # 使用回退机制获取时区对象
    self.bot = pywxdll.Pywxdll(self.ip, self.port)
    self.db = BotDatabase()

async def run(self, recv):
    signin_points = random.randint(self.min_points, self.max_points)
    sign_wxid = recv.get("id1", recv["wxid"])
    signstat = str(self.db.get_stat(sign_wxid))

    nickname = self.bot.get_chatroom_nickname(recv["wxid"], sign_wxid)["nick"]

    if self.signstat_check(signstat):
        self.db.add_points(sign_wxid, signin_points)
        now_datetime_str = datetime.now(self.timezone).strftime("%Y%m%d")
        self.db.set_stat(sign_wxid, now_datetime_str)

        out_message = f"\n-----XYBot-----\n签到成功!你领到了{signin_points}个积分!✅"
        logger.info(f"[发送信息]{out_message}| [发送到] {recv['wxid']}")
        self.bot.send_at_msg(recv["wxid"], recv.get("id1"), nickname, out_message)

    else:
        last_sign_date_formated = datetime.strptime(signstat, "%Y%m%d").strftime("%Y年%m月%d日")
        out_message = f"\n-----XYBot-----\n❌你今天已经签到过了,每日凌晨刷新签到哦!上次签到日期:{last_sign_date_formated}"
        logger.info(f"[发送信息]{out_message}| [发送到] {recv['wxid']}")
        self.bot.send_at_msg(recv["wxid"], recv.get("id1"), nickname, out_message)

def signstat_check(self, signstat):
    signstat = "20000101" if signstat in ["0", "1"] else signstat
    last_sign_date = datetime.strptime(signstat, "%Y%m%d").date()
    now_date = datetime.now(self.timezone).date()
    return (now_date - last_sign_date).days >= 1
HenryXiaoYang commented 2 months ago

盲猜是在windows上部署的。由于现在默认的时区格式是linux的,在windows上会出问题。这个问题在下个版本会修掉的。