上传文件至「py」
This commit is contained in:
@@ -0,0 +1,645 @@
|
||||
# [author: authook]
|
||||
# [title: jd_账密登陆]
|
||||
# [create_at: 2023-09-19 15:29:17]
|
||||
# [version: 2.3]
|
||||
# [pin: true]
|
||||
# [price: 0]
|
||||
# [rule: ^账密登录$]
|
||||
# [rule: ^账密登陆$]
|
||||
# [rule: ^账密刷新$]
|
||||
# [rule: ^账密强制刷新$]
|
||||
# [rule: ^账密管理$]
|
||||
# [priority: 6666666]优先级
|
||||
# [admin: false]
|
||||
# [service: authook]
|
||||
# [icon: https://bbs.autman.cn/assets/files/2024-05-16/1715842374-826456-2584e965be6ed12773865dbb8e29a449.png]
|
||||
# [description: jd_账密登陆插件 兼容兔子,pro等框架</br>指令:账密登录,账密登录,账密管理 </br> 配置:在插件配参中配置,</br>权限:需开启qls,jdNotify权限</br>注意⚠️账密刷新请勿手动发送,否则会将ck绑定至管理员账号上!!!(插件已自动内置定时刷新账密)]
|
||||
|
||||
# [param: {"required":true,"key":"jd.rabbit_host","placeholder":"http://192.168.1.1:81","name":"【rabbit】登陆地址:","desc":"登陆地址,例:http://192.168.3.22"}]
|
||||
# [param: {"required":true,"key":"jd.pro_host","placeholder":"http://192.168.1.1:81","name":"【pro】登陆地址:","desc":"pro登陆地址"}]
|
||||
# [param: {"required":true,"key":"jd.login_ql_name","placeholder":"ql容器名称","name":"【ql】容器名称","desc":"ql容器名称"}]
|
||||
# [param: {"required":true,"key":"jd.login_type","placeholder":"登陆框架","name":"登陆框架","desc":"pro框架请输入pro rabbit兔子框架请输入rabbit"}]
|
||||
|
||||
# =======================
|
||||
# 项目:jd_账密登陆.py
|
||||
# 构建时间:2025-02-10 20:52:29
|
||||
import datetime
|
||||
from email import message
|
||||
import json
|
||||
import logging
|
||||
import math
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
import time
|
||||
import traceback
|
||||
import inspect
|
||||
from base64 import b64encode
|
||||
from urllib.parse import quote, urlparse
|
||||
|
||||
import colorlog
|
||||
import middleware
|
||||
import requests
|
||||
from Crypto.Cipher import AES
|
||||
from Crypto.Util.Padding import pad
|
||||
|
||||
|
||||
class TOOL:
|
||||
def __init__(self):
|
||||
self.plugin_pre = "rabbit_zm"
|
||||
self.remark = ""
|
||||
self.platform_arr = self.platformArr()
|
||||
# 将日期和时间格式化为字符串
|
||||
self.cut_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||
self.logger = logging.getLogger()
|
||||
self.color_formatter = colorlog.ColoredFormatter(
|
||||
'%(log_color)s%(levelname)s: %(message)s',
|
||||
log_colors={
|
||||
'DEBUG': 'cyan',
|
||||
'INFO': 'green',
|
||||
'WARNING': 'yellow',
|
||||
'ERROR': 'red',
|
||||
'CRITICAL': 'red,bg_white',
|
||||
}
|
||||
)
|
||||
self.logger = self._configure_logger()
|
||||
|
||||
def _configure_logger(self):
|
||||
"""配置并返回一个带颜色的 logger 对象"""
|
||||
logger = logging.getLogger(self.plugin_pre)
|
||||
logger.setLevel(logging.DEBUG) # 设置日志默认最低级别
|
||||
|
||||
# 检查是否已添加过控制台处理器,避免重复添加
|
||||
if not any(isinstance(handler, logging.StreamHandler) for handler in logger.handlers):
|
||||
console_handler = logging.StreamHandler()
|
||||
console_handler.setLevel(logging.DEBUG) # 控制台日志最低级别
|
||||
console_handler.setFormatter(self.color_formatter)
|
||||
logger.addHandler(console_handler)
|
||||
|
||||
return logger
|
||||
|
||||
def log(self, level, message):
|
||||
"""通用日志方法"""
|
||||
if level == logging.INFO:
|
||||
self.logger.info(message)
|
||||
elif level == logging.ERROR:
|
||||
self.logger.error(message)
|
||||
elif level == logging.WARNING:
|
||||
self.logger.warning(message)
|
||||
elif level == logging.DEBUG:
|
||||
self.logger.debug(message)
|
||||
elif level == logging.CRITICAL:
|
||||
self.logger.critical(message)
|
||||
|
||||
def log_info(self, message):
|
||||
self.log(logging.INFO, message)
|
||||
|
||||
def log_err(self, message):
|
||||
self.log(logging.ERROR, message)
|
||||
|
||||
def log_warn(self, message):
|
||||
self.log(logging.WARNING, message)
|
||||
|
||||
def platformArr(self):
|
||||
plat_arr = []
|
||||
for p in ["qq", "wx", "wb", "qb", "bt", "tg"]:
|
||||
t = {"platform": f"{p}", "imType": p}
|
||||
plat_arr.append(t)
|
||||
return plat_arr
|
||||
|
||||
def pushMsg(self, userId, chatId, imType, title, content):
|
||||
# 获取当前日期和时间
|
||||
now = datetime.datetime.now()
|
||||
# 将日期和时间格式化为字符串
|
||||
formatted_datetime = now.strftime('%Y-%m-%d %H:%M:%S')
|
||||
self.remark = ""
|
||||
return middleware.push(imType, chatId, userId, title, f"{formatted_datetime}\n{content}")
|
||||
|
||||
def pushGroup(self, imtype, groupCode, content):
|
||||
self.pushMsg(0, groupCode, imtype, "", content)
|
||||
|
||||
def autman_host(self):
|
||||
file_path = inspect.getframeinfo(inspect.currentframe()).filename
|
||||
dir_path = os.path.dirname(os.path.abspath(file_path))
|
||||
setConfPath = dir_path.split("develop/scripts")[0] + "/middleware.py"
|
||||
try:
|
||||
os.setuid(0) # 强制转为root 前提是autman账户以root用户启用
|
||||
with open(setConfPath, "r", encoding="utf-8") as f:
|
||||
data = f.read()
|
||||
lines = data.splitlines()
|
||||
for line in lines:
|
||||
if "url =" in line:
|
||||
res = line.split('"')
|
||||
url = res[1][0:-5]
|
||||
self.log_info(url)
|
||||
return url
|
||||
except Exception as e:
|
||||
self.log_info(f"❌autman_host error {e}")
|
||||
|
||||
def replyMsg(self, content):
|
||||
return sender.reply(content)
|
||||
|
||||
def pushMaster(self, content):
|
||||
arr = ["qq", "wx", "tg", "qb", 'wb']
|
||||
for p in arr:
|
||||
masters = sender.bucketGet(p, "masters")
|
||||
if masters:
|
||||
masters_arr = masters.split(",") if "," in masters else masters.split("&")
|
||||
for m in masters_arr:
|
||||
middleware.push(p, "", m, "", content)
|
||||
|
||||
def qls(self):
|
||||
qls = []
|
||||
ql_id_arr = sender.bucketAllKeys("qls")
|
||||
if not ql_id_arr:
|
||||
return []
|
||||
for ql_id in ql_id_arr:
|
||||
value = sender.bucketGet("qls", ql_id)
|
||||
if value:
|
||||
qls.append(json.loads(value))
|
||||
return qls
|
||||
|
||||
def autman_host(self):
|
||||
file_path = inspect.getframeinfo(inspect.currentframe()).filename
|
||||
dir_path = os.path.dirname(os.path.abspath(file_path))
|
||||
setConfPath = dir_path.split("develop/scripts")[0] + "/middleware.py"
|
||||
try:
|
||||
os.setuid(0) # 强制转为root 前提是autman账户以root用户启用
|
||||
with open(setConfPath, "r", encoding="utf-8") as f:
|
||||
data = f.read()
|
||||
lines = data.splitlines()
|
||||
for line in lines:
|
||||
if "url =" in line:
|
||||
res = line.split('"')
|
||||
url = res[1][0:-5]
|
||||
self.log_info(url)
|
||||
return url
|
||||
except Exception as e:
|
||||
self.log_info(f"❌autman_host error {e}")
|
||||
|
||||
|
||||
class QL:
|
||||
def __init__(self, ql):
|
||||
self.host = ql["host"]
|
||||
self.client_id = ql["client_id"]
|
||||
self.client_secret = ql["client_secret"]
|
||||
self.token = self.get_token()
|
||||
self.name = ql['name']
|
||||
self.content = ""
|
||||
self.version = self.system()
|
||||
|
||||
def gettimestamp(self):
|
||||
return str(int(time.time() * 1000))
|
||||
|
||||
def get_token(self):
|
||||
url = f"{self.host}/open/auth/token?client_id={self.client_id}&client_secret={self.client_secret}"
|
||||
print(url)
|
||||
headers = {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': '*/*',
|
||||
'Cache-Control': 'no-cache',
|
||||
'Host': "",
|
||||
'Connection': 'keep-alive'
|
||||
}
|
||||
host = urlparse(url).netloc
|
||||
if ":" in host:
|
||||
host = host.split(":")[0]
|
||||
headers['Host'] = host
|
||||
try:
|
||||
response = requests.get(url, timeout=10, headers=headers)
|
||||
res = response.json()
|
||||
if response.status_code == 200 and res["code"] == 200:
|
||||
return res["data"]["token"]
|
||||
else:
|
||||
return None
|
||||
except Exception as e:
|
||||
return None
|
||||
|
||||
def Api(self, api, apd, method, payload):
|
||||
url = f"{self.host}/open/{api}/{apd}"
|
||||
headers = {
|
||||
"Content-Type": "application/json;charset=UTF-8",
|
||||
"Authorization": f"Bearer {self.token}",
|
||||
}
|
||||
try:
|
||||
response = requests.request(method, url, headers=headers, data=payload, timeout=5)
|
||||
return response.json()
|
||||
except Exception as e:
|
||||
return None
|
||||
|
||||
# 环境变量
|
||||
def envGet(self, keyword):
|
||||
return self.Api('envs', f"?searchValue={keyword}&t={self.gettimestamp()}", 'GET', {})
|
||||
|
||||
def envSet(self, env):
|
||||
return self.Api('envs', f"?t={self.gettimestamp()}", 'POST', env)
|
||||
|
||||
def envUpdate(self, env):
|
||||
return self.Api('envs', f"?t={self.gettimestamp()}", 'PUT', env)
|
||||
|
||||
def envEnable(self, ids):
|
||||
return self.Api('envs', f"/enable?t={self.gettimestamp()}", 'PUT', json.dumps(ids))
|
||||
|
||||
def envDisable(self, ids):
|
||||
return self.Api('envs', f"/disable?t={self.gettimestamp()}", 'PUT', json.dumps(ids))
|
||||
|
||||
def envDel(self, ids):
|
||||
return self.Api('envs', f"?t={self.gettimestamp()}", 'delete', json.dumps(ids))
|
||||
|
||||
def envMove(self, id, data):
|
||||
return self.Api('envs', f"/{id}/move?t={self.gettimestamp()}", 'PUT', json.dumps(data))
|
||||
|
||||
# 定时任务
|
||||
def cronGet(self, keyword):
|
||||
return self.Api('crons', f"?searchValue={keyword}&t={self.gettimestamp()}", 'GET', None)
|
||||
|
||||
def cronRun(self, ids):
|
||||
return self.Api('crons', f"run?t={self.gettimestamp()}", 'PUT', ids)
|
||||
|
||||
def cronStop(self, ids):
|
||||
return self.Api('crons', f"stop?t={self.gettimestamp()}", 'PUT', ids)
|
||||
|
||||
def cronEnable(self, ids):
|
||||
return self.Api('crons', f"enable?t={self.gettimestamp()}", 'PUT', ids)
|
||||
|
||||
def cronDisable(self, ids):
|
||||
return self.Api('crons', f"disable?t={self.gettimestamp()}", 'PUT', ids)
|
||||
|
||||
def cronDetail(self, cronId):
|
||||
return self.Api('crons', f"{cronId}?t={self.gettimestamp()}", 'GET', None)
|
||||
|
||||
def cronLogs(self, cronId):
|
||||
return self.Api('crons', f"{cronId}/log?t={self.gettimestamp()}", 'GET', None)
|
||||
|
||||
def cronLog(self, cronId):
|
||||
return self.Api('crons', f"{cronId}/log?t={self.gettimestamp()}", 'GET', None)
|
||||
|
||||
# 配置文件
|
||||
def configsGet(self, name):
|
||||
if self.version < "2.17":
|
||||
return self.Api('configs', f"{name}?t={self.gettimestamp()}", 'GET', None)
|
||||
else:
|
||||
return self.Api('configs/detail', f"?path={name}&t={self.gettimestamp()}", 'GET', None)
|
||||
|
||||
def configsSet(self, data):
|
||||
return self.Api('configs', f"save?t={self.gettimestamp()}", 'POST', data)
|
||||
|
||||
# 订阅任务
|
||||
def subsGet(self, keyword):
|
||||
return self.Api('subscriptions', f"?searchValue={keyword}&t={self.gettimestamp()}", 'GET', None)
|
||||
|
||||
def subsSet(self, data):
|
||||
return self.Api('subscriptions', f"save?t={self.gettimestamp()}", 'PUT', data)
|
||||
|
||||
def subsRun(self, ids):
|
||||
return self.Api('subscriptions', f"run?t={self.gettimestamp()}", 'PUT', ids)
|
||||
|
||||
def subsEnable(self, ids):
|
||||
return self.Api('subscriptions', f"enable?t={self.gettimestamp()}", 'PUT', ids)
|
||||
|
||||
def subsDisable(self, ids):
|
||||
return self.Api('subscriptions', f"disable?t={self.gettimestamp()}", 'PUT', ids)
|
||||
|
||||
def subsLog(self, subId):
|
||||
return self.Api('subscriptions', f"{subId}/log?t={self.gettimestamp()}", 'GET', None)
|
||||
|
||||
def system(self):
|
||||
url = f"{self.host}/open/system?t={self.gettimestamp()}"
|
||||
headers = {
|
||||
"Content-Type": "application/json;charset=UTF-8",
|
||||
}
|
||||
try:
|
||||
res = requests.get(url)
|
||||
if res.status_code == 200:
|
||||
rj = res.json()
|
||||
return rj['data']['version']
|
||||
except Exception as e:
|
||||
return 2.16
|
||||
|
||||
|
||||
class ZM_RABBIT():
|
||||
def __init__(self):
|
||||
self.pins = self.get_pins()
|
||||
self.conf = self.get_conf()
|
||||
self.init()
|
||||
self.s = requests.session()
|
||||
pass
|
||||
|
||||
def hide_phone(self, text):
|
||||
if not text:
|
||||
return text
|
||||
if len(text) != 11:
|
||||
return text
|
||||
return re.sub(r'(\d{3})\d{4}(\d{4})', r'\1****\2', text)
|
||||
|
||||
def check_ck_status(self, ck):
|
||||
headers = {
|
||||
"Cookie": ck,
|
||||
"referer": "https://h5.m.jd.com/",
|
||||
"User-Agent": "jdapp;iPhone;10.1.2;15.0;network/wifi;Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1",
|
||||
}
|
||||
|
||||
response = requests.get('https://plogin.m.jd.com/cgi-bin/ml/islogin', headers=headers)
|
||||
data = response.json()
|
||||
return data['islogin'] == "1" if 'islogin' in data else False
|
||||
|
||||
def en_pwd(self, pwd):
|
||||
key = b"wn:_/imCQF;rBNS{V=|kML[(+$%Tjgy)"
|
||||
iv = b"zA#f.x>jN!h-0[{$"
|
||||
cipher = AES.new(key, AES.MODE_CBC, iv)
|
||||
encrypted = cipher.encrypt(pad(pwd.encode(), AES.block_size))
|
||||
return b64encode(encrypted).decode()
|
||||
|
||||
def get_conf(self):
|
||||
self.conf = {
|
||||
"paid": "n",
|
||||
"fee": 0,
|
||||
"qr_code": "",
|
||||
"host": "",
|
||||
"ql_name": None
|
||||
}
|
||||
if middleware.bucketGet("otto", "rabbit_pro_paid"):
|
||||
self.conf["paid"] = middleware.bucketGet("otto", "rabbit_pro_paid")
|
||||
if middleware.bucketGet("otto", "rabbit_pro_fee"):
|
||||
self.conf['fee'] = middleware.bucketGet("otto", "rabbit_pro_fee")
|
||||
if middleware.bucketGet("otto", "rabbit_pro_qr_code"):
|
||||
self.conf['qr_code'] = middleware.bucketGet("otto", "rabbit_pro_qr_code")
|
||||
if not middleware.bucketGet("otto", "rabbit_pro_host"):
|
||||
tool.pushMaster("未配置rabbit登录地址,请先去【配参】配置")
|
||||
exit()
|
||||
self.conf['host'] = middleware.bucketGet("otto", "rabbit_pro_host")
|
||||
if not middleware.bucketGet("otto", "rabbit_ql_name"):
|
||||
tool.pushMaster("未配置rabbit登陆容器名称,请先去【配参】配置")
|
||||
exit()
|
||||
self.conf['ql_name'] = middleware.bucketGet("otto", "rabbit_ql_name")
|
||||
return self.conf
|
||||
|
||||
def init(self):
|
||||
res = requests.get(self.conf['host'] + "/api/Config")
|
||||
tool.log_info(res.text)
|
||||
if res.status_code == 200:
|
||||
rj = res.json()
|
||||
if rj['success']:
|
||||
self.conf['container_id'] = rj['data']['list'][0]['container_id']
|
||||
self.conf['container_name'] = rj['data']['list'][0]['container_name']
|
||||
self.conf['autocount'] = rj['data']['autocount']
|
||||
return self.conf
|
||||
tool.replyMsg(rj['message'] + ",请完善rabbitPro配置")
|
||||
exit()
|
||||
|
||||
def get_pins(self):
|
||||
return sender.bucketKeys("pin" + imType.upper(), userId)
|
||||
|
||||
def account_list(self):
|
||||
acc_list = []
|
||||
acc_key = set()
|
||||
if self.pins and len(self.pins) > 0:
|
||||
for pin in self.pins:
|
||||
acc_str = sender.bucketGet("", pin)
|
||||
if acc_str:
|
||||
acc = {
|
||||
"username": acc_str.split("#")[0],
|
||||
"pwd": acc_str.split("#")[1],
|
||||
"ck": acc_str.split("#")[2],
|
||||
}
|
||||
if acc_str.split("#")[0] not in acc_key:
|
||||
acc_list.append(acc)
|
||||
acc_key.add(acc_str.split("#")[0])
|
||||
|
||||
return acc_list
|
||||
|
||||
def login_init(self, mobile):
|
||||
headers = {
|
||||
"Content-Type": "application/json",
|
||||
"User_Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1"
|
||||
}
|
||||
data = {"account": mobile, "container_id": self.conf['container_id']}
|
||||
url = self.conf['host'] + "/pwd/init"
|
||||
res = self.s.post(url, headers=headers, data=json.dumps(data))
|
||||
tool.log_info(f"{mobile}: login_init res {res.text}")
|
||||
if res.status_code == 200:
|
||||
rj = res.json()
|
||||
if not rj['success']:
|
||||
tool.replyMsg(f"[{self.hide_phone(mobile)}]登陆初始化失败:{rj['message']}")
|
||||
return
|
||||
if rj['data']['status'] == 505:
|
||||
return True
|
||||
else:
|
||||
tool.replyMsg(f"f{rj['message']}")
|
||||
return False
|
||||
|
||||
pass
|
||||
|
||||
def login(self, mobile, pwd):
|
||||
headers = {
|
||||
"Content-Type": "application/json",
|
||||
"User_Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1"
|
||||
}
|
||||
data = {"account": mobile, "pwd": self.en_pwd(pwd), "container_id": self.conf['container_id']}
|
||||
res = self.s.post(f"{self.conf['host']}/pwd/login", headers=headers, data=json.dumps(data))
|
||||
tool.log_info(f"{mobile}: login res {res.text}")
|
||||
if res.status_code == 200:
|
||||
rj = res.json()
|
||||
if rj['code'] == 601:
|
||||
tool.replyMsg(f"[{self.hide_phone(mobile)}]账号需要点击验证之后,重新登陆\n{rj['RiskUrl']}")
|
||||
return False, None
|
||||
if rj['code'] == 200:
|
||||
tool.replyMsg(f"【登陆账户】:{self.hide_phone(mobile)}\n【JD账户】:{rj['pin']}\n【登陆结果】:{rj['message']}")
|
||||
value_json = {
|
||||
"mobile": mobile,
|
||||
"pwd": pwd
|
||||
}
|
||||
sender.bucketSet("rabbit_zm_acc", rj['pin'], json.dumps(value_json))
|
||||
return True, rj['pin']
|
||||
elif rj['code'] == 503:
|
||||
tool.replyMsg(f"[{self.hide_phone(mobile)}]{rj['message']}")
|
||||
return False, None
|
||||
elif rj['code'] == 555:
|
||||
# 需要验证
|
||||
riskUrl = rj['RiskUrl']
|
||||
tool.replyMsg(f"[{self.hide_phone(mobile)}]请手动点击验证链接,然后再次返回登陆:{riskUrl}")
|
||||
return False, None
|
||||
else:
|
||||
tool.replyMsg(f"[{self.hide_phone(mobile)}]登陆异常:{rj['message']}")
|
||||
return False, None
|
||||
|
||||
def after_login(self, pin):
|
||||
time.sleep(random.randint(3,5))
|
||||
sender.bucketSet('pin' + imType.upper(), pin, userId)
|
||||
qls = tool.qls()
|
||||
if not qls or len(qls) == 0:
|
||||
tool.pushMaster("未配置青龙容器,无法同步更新容器ck")
|
||||
exit()
|
||||
default_ql = list(filter(lambda item: self.conf['ql_name'] in item['name'],qls))
|
||||
if not default_ql:
|
||||
tool.pushMaster(f"容器【{self.conf['ql_name']}】,不存在,请重新配置")
|
||||
return
|
||||
tql = QL(default_ql[0])
|
||||
if not tql.token:
|
||||
return
|
||||
res = tql.envGet("JD_COOKIE")
|
||||
if res['code'] != 200 or len(res['data']) == 0:
|
||||
return
|
||||
if len(res['data']) <= 0:
|
||||
return
|
||||
cookie = list(filter(lambda item: pin in item['value'], res['data']))
|
||||
if not cookie:
|
||||
return
|
||||
if cookie[0]['status'] == 1:
|
||||
return
|
||||
if not self.check_ck_status(cookie[0]['value']):
|
||||
return
|
||||
ck = cookie[0]['value']
|
||||
pt_key = re.findall(r"pt_key=(.*?);", ck)[0]
|
||||
val = {
|
||||
"ID": pin,
|
||||
"Pet": False,
|
||||
"Fruit": False,
|
||||
"DreamFactory": False,
|
||||
"Note": "",
|
||||
"PtKey": pt_key,
|
||||
"AssetCron": "",
|
||||
"PushPlus": "",
|
||||
"LoginedAt": datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
|
||||
"ClientID": tql.client_id
|
||||
}
|
||||
sender.bucketSet('jdNotify', pin, json.dumps(val))
|
||||
|
||||
for ql in qls:
|
||||
if self.conf['ql_name'] in ql['name']:
|
||||
continue
|
||||
tql = QL(ql)
|
||||
if not tql.token:
|
||||
continue
|
||||
res = tql.envGet("JD_COOKIE")
|
||||
if res['code'] != 200 or len(res['data']) == 0:
|
||||
continue
|
||||
if len(res['data']) <= 0:
|
||||
continue
|
||||
cookie = list(filter(lambda item: pin in item['value'], res['data']))
|
||||
if not cookie:
|
||||
continue
|
||||
ck = cookie[0]['value']
|
||||
id = cookie[0].get('id', cookie[0].get("_id"))
|
||||
remarks = cookie[0].get('remarks', pin)
|
||||
if ck:
|
||||
updateEnv = {
|
||||
"name": "JD_COOKIE",
|
||||
"value": ck,
|
||||
"remarks": remarks,
|
||||
"id": id,
|
||||
}
|
||||
res = tql.envUpdate(json.dumps(updateEnv))
|
||||
tool.log_info(f"update res {res}")
|
||||
res = tql.envEnable([id])
|
||||
tool.log_info(f"envEnable res {res}")
|
||||
|
||||
def refresh_account(self):
|
||||
need = 0
|
||||
success = 0
|
||||
failed = 0
|
||||
failed_user = []
|
||||
tool.log_info(f"[rabbit]账密刷新开始......")
|
||||
acc_map = sender.bucketAll("rabbit_zm_acc")
|
||||
if not acc_map:
|
||||
sender.reply("暂无账密数据,已退出")
|
||||
# 查询pin对应的ck是否有效
|
||||
for pin, accStr in acc_map.items():
|
||||
jdStr = sender.bucketGet("jdNotify", pin)
|
||||
if not jdStr:
|
||||
continue
|
||||
jd_json = json.loads(jdStr)
|
||||
ck = f"pt_pin={pin}; pt_key={jd_json['PtKey']}"
|
||||
if self.check_ck_status(ck):
|
||||
tool.log_info(f"账号【{pin}】有效✅,跳过刷新")
|
||||
continue
|
||||
need += 1
|
||||
acc_json = json.loads(accStr)
|
||||
refresh_res = self.run_login(acc_json['mobile'], acc_json['pwd'])
|
||||
if not refresh_res:
|
||||
failed += 1
|
||||
failed_user.append(f"{quote(pin)}[{self.hide_phone(acc_json['mobile'])}]")
|
||||
else:
|
||||
success += 1
|
||||
content = f"[rabbit]账密刷新结束"
|
||||
if need > 0:
|
||||
content += f"\n本次需要刷新:{need}个"
|
||||
content += f"\n本次刷新成功:{success}个🎉"
|
||||
if failed_user:
|
||||
content += f"\n本次刷新失败:{failed}个😭"
|
||||
s = "\n".join(failed_user)
|
||||
content += f"\n刷新失败用户:{s}"
|
||||
else:
|
||||
content += f"\n本次所有账户有效,无需刷新🎉"
|
||||
tool.pushMaster(content)
|
||||
|
||||
def account_manage(self):
|
||||
acc_map = sender.bucketAll("rabbit_zm_acc")
|
||||
if not acc_map:
|
||||
tool.replyMsg("暂无账密记录,请先登录")
|
||||
exit()
|
||||
content = f"账密列表如下:"
|
||||
no = 0
|
||||
for pin,accStr in acc_map.items():
|
||||
acc_json = json.loads(accStr)
|
||||
no +=1
|
||||
content += f"\n{no}、{quote(pin)}[{self.hide_phone(acc_json['mobile'])}]"
|
||||
tool.replyMsg(content)
|
||||
|
||||
|
||||
def run_login(self, mobile, pwd):
|
||||
if not self.login_init(mobile):
|
||||
return False
|
||||
login_res, pin = self.login(mobile, pwd)
|
||||
if not login_res:
|
||||
return False
|
||||
self.after_login(pin)
|
||||
return True
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sender = middleware.Sender(middleware.getSenderID())
|
||||
plugin_ver = sender.getPluginVersion()
|
||||
plugin_name = sender.getPluginName()
|
||||
msg = sender.getMessage().strip('"')
|
||||
imType = "fake" if sender.getImtype() == "cron" else sender.getImtype()
|
||||
chatId = sender.getChatID()
|
||||
userId = sender.getUserID()
|
||||
isAdmin = sender.isAdmin()
|
||||
username = sender.getUserName()
|
||||
tool = TOOL()
|
||||
#### 定时任务 #####
|
||||
cron = middleware.Cron(None)
|
||||
crons = list(filter(lambda item: "兔子账密刷新" in item['cmd'],cron.getCrons()))
|
||||
if not crons:
|
||||
tool.log_info(f"【兔子账密刷新】定时任务不存在,重新添加")
|
||||
id = cron.addCron("0 0,3,5 * * *","兔子账密刷新",True,False,"兔子账密刷新","","","")
|
||||
tool.log_info(f"add cron id = {id}")
|
||||
#### 定时任务 ####
|
||||
tz = ZM_RABBIT()
|
||||
if "登录" in msg or "登陆" in msg:
|
||||
sms_content = "请在60秒内输入手机号(q:退出)"
|
||||
tool.replyMsg(sms_content)
|
||||
mobile = sender.listen(60000)
|
||||
if not mobile or mobile == "q" or mobile == "error":
|
||||
tool.replyMsg("已退出!")
|
||||
exit()
|
||||
pattern = r'^1[3-9]\d{9}$'
|
||||
if not re.match(pattern, mobile):
|
||||
tool.replyMsg("手机号格式错误,已退出!")
|
||||
exit()
|
||||
tool.replyMsg("请在60秒内输入登录密码(q:退出)")
|
||||
pwd = sender.listen(60000)
|
||||
if not pwd or pwd == "q" or pwd == "error":
|
||||
tool.replyMsg("已退出!")
|
||||
exit()
|
||||
if len(pwd) < 8:
|
||||
tool.replyMsg("密码格式错误,已退出!")
|
||||
exit()
|
||||
tz.run_login(mobile, pwd)
|
||||
exit()
|
||||
if "刷新" in msg:
|
||||
tz.refresh_account()
|
||||
exit()
|
||||
if "管理" in msg:
|
||||
tz.account_manage()
|
||||
Reference in New Issue
Block a user