# Source: https://github.com/smallfawn/QLScriptPublic/blob/main/daily/360.py
# Raw: https://raw.githubusercontent.com/smallfawn/QLScriptPublic/main/daily/360.py
# Repo: smallfawn/QLScriptPublic
# Path: daily/360.py
# UploadedAt: 2026-04-07T07:05:19Z
# SHA256: 6ad9e6349174feff19123a743bc626bb84d6916c289d4ab3017d6b967b231a6e
# Category: web版/抓包
# Evidence: web/H5关键词 + cookie/token/header

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# 作者: 青龙面板适配
# 说明: 360社区自动签到脚本（青龙面板专用）
# 依赖: requests
# new Env("360社区签到")
# 用法: 在青龙面板环境变量中设置 BBS360_COOKIE
#      请确保Cookie包含 __cfduid, uid 等必要字段

import os
import re
import time
import random
import requests
from dataclasses import dataclass
from typing import Optional, Tuple

SIGN_PAGE = "https://bbs.360.cn/dsu_paulsign-sign.html"
SIGN_API = "https://bbs.360.cn/plugin.php?id=dsu_paulsign:sign&operation=qiandao&infloat=1&inajax=1"

@dataclass
class CheckinResult:
    ok: bool
    status: str
    detail: str

class BBS360Checkin:
    """360社区签到客户端（青龙面板适配）"""
    def __init__(self, cookie: str, timeout: int = 20):
        self.cookie = cookie.strip()
        self.timeout = timeout
        self.session = requests.Session()
        self.session.headers.update({
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0 Safari/537.36",
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
            "Accept-Language": "zh-CN,zh;q=0.9",
            "Connection": "keep-alive",
            "Cookie": self.cookie,
            "Referer": "https://bbs.360.cn/",
        })

    def fetch_formhash(self) -> Tuple[Optional[str], str]:
        """拉取签到页并提取 formhash"""
        resp = self.session.get(SIGN_PAGE, timeout=self.timeout, allow_redirects=True)
        text = resp.text or ""
        
        # 青龙面板特殊处理：如果返回403，可能是需要验证
        if resp.status_code == 403:
            return None, "403 Forbidden（可能需要绑定手机号）"
            
        # 未登录/未绑定手机号时提示
        if "您需要先登录才能继续本操作" in text or "请使用手机微信扫码安全登录" in text:
            return None, "未登录或账号未绑定手机号（需在360社区绑定手机号）"
        
        # 提取 formhash
        m = re.search(r'formhash=([0-9a-zA-Z]{6,})', text)
        if not m:
            m = re.search(r'name="formhash"\s+value="([0-9a-zA-Z]{6,})"', text)
        
        if not m:
            return None, "未解析到 formhash（页面结构可能变更）"
        
        return m.group(1), "OK"

    def submit_checkin(self, formhash: str) -> CheckinResult:
        """提交签到请求"""
        moods = ["kx", "ym", "tp", "ng", "wl"]
        payload = {
            "formhash": formhash,
            "qdxq": random.choice(moods),
            "qdmode": "1",
            "todaysay": random.choice([
                "打卡签到，愿一切顺利！",
                "新的一天，继续加油～",
                "保持热爱，奔赴山海。",
                "今日签到，万事胜意。",
                "坚持自律，慢慢变强。",
            ]),
            "fastreply": "0",
        }

        resp = self.session.post(SIGN_API, data=payload, timeout=self.timeout)
        raw = resp.text or ""
        
        # 青龙面板特殊处理：返回403或500
        if resp.status_code != 200:
            return CheckinResult(False, f"http_{resp.status_code}", f"HTTP {resp.status_code}")
        
        # 检查签到结果
        if "签到成功" in raw or ("恭喜" in raw and "签到" in raw):
            return CheckinResult(True, "success", self._extract_message(raw) or "签到成功")
        if "已经签到" in raw or "已签到" in raw or "请勿重复签到" in raw:
            return CheckinResult(True, "already", self._extract_message(raw) or "今日已签到")
        if ("formhash" in raw and "错误" in raw) or "请求无效" in raw:
            return CheckinResult(False, "bad_formhash", self._extract_message(raw) or "formhash无效/过期")
        
        return CheckinResult(False, "unknown", self._extract_message(raw) or raw[:200])

    @staticmethod
    def _extract_message(text: str) -> str:
        """提取提示信息"""
        m = re.search(r"showmessage\('([^']+)'\)", text)
        if m:
            return m.group(1)
        
        m = re.search(r"([^\n\r]{0,20}(签到|已签到|重复签到)[^\n\r]{0,40})", text)
        if m:
            return m.group(1)
        
        return ""

    def run(self) -> CheckinResult:
        formhash, info = self.fetch_formhash()
        if not formhash:
            return CheckinResult(False, "no_login_or_parse_failed", info)
        
        time.sleep(random.uniform(1.0, 2.5))
        return self.submit_checkin(formhash)

def main():
    # 青龙面板专用：从环境变量获取Cookie
    cookie = os.getenv("BBS360_COOKIE", "").strip()
    
    if not cookie:
        print("❌ 未设置环境变量 BBS360_COOKIE")
        print("💡 请在青龙面板 → 环境变量 → 添加以下内容：")
        print("   KEY: BBS360_COOKIE")
        print("   VALUE: 从浏览器复制的完整Cookie（包含__cfduid, uid等）")
        return
    
    # 青龙面板特殊处理：检测Cookie是否包含必要字段
    if "__cfduid" not in cookie or "uid" not in cookie:
        print("❌ Cookie无效：缺少必要字段（需包含__cfduid和uid）")
        print("💡 请重新复制Cookie：")
        print("   1. 登录 bbs.360.cn → F12 → Application → Cookies")
        print("   2. 复制 bbs.360.cn 下的所有Cookie字段")
        return
    
    client = BBS360Checkin(cookie=cookie, timeout=20)
    result = client.run()

    # 青龙面板专用输出格式
    if result.ok:
        print(f"✅ 360签到成功 | {result.status} | {result.detail}")
    else:
        print(f"❌ 360签到失败 | {result.status} | {result.detail}")

if __name__ == "__main__":
    main()