mirror of https://github.com/lhie1/Rules.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
2.9 KiB
JavaScript
120 lines
2.9 KiB
JavaScript
/*
|
|
https://raw.githubusercontent.com/mieqq/mieqq/master/sub_info_panel.js
|
|
*/
|
|
|
|
(async () => {
|
|
let args = getArgs();
|
|
let info = await getDataInfo(args.url);
|
|
if (!info) $done();
|
|
let resetDayLeft = getRmainingDays(parseInt(args["reset_day"]));
|
|
|
|
let used = info.download + info.upload;
|
|
let total = info.total - (info.download + info.upload);
|
|
let expire = args.expire || info.expire;
|
|
let content = [`已用:${bytesToSize(used)} / 可用:${bytesToSize(total)}`];
|
|
|
|
if (resetDayLeft) {
|
|
content.push(`重置流量:剩余${resetDayLeft}天`);
|
|
}
|
|
if (expire) {
|
|
if (/^[\d.]+$/.test(expire)) expire *= 1000;
|
|
content.push(`到期时间:${formatTime(expire)}`);
|
|
}
|
|
|
|
let now = new Date();
|
|
let hour = now.getHours();
|
|
let minutes = now.getMinutes();
|
|
hour = hour > 9 ? hour : "0" + hour;
|
|
minutes = minutes > 9 ? minutes : "0" + minutes;
|
|
|
|
$done({
|
|
title: `${args.title}`,
|
|
content: content.join("\n"),
|
|
icon: args.icon || "airplane.circle",
|
|
"icon-color": args.color || "#007aff",
|
|
});
|
|
})();
|
|
|
|
function getArgs() {
|
|
return Object.fromEntries(
|
|
$argument
|
|
.split("&")
|
|
.map((item) => item.split("="))
|
|
.map(([k, v]) => [k, decodeURIComponent(v)])
|
|
);
|
|
}
|
|
|
|
function getUserInfo(url) {
|
|
let request = { headers: { "User-Agent": "Quantumult%20X" }, url };
|
|
return new Promise((resolve, reject) =>
|
|
$httpClient.get(request, (err, resp) => {
|
|
if (err != null) {
|
|
reject(err);
|
|
return;
|
|
}
|
|
if (resp.status !== 200) {
|
|
reject(resp.status);
|
|
return;
|
|
}
|
|
let header = Object.keys(resp.headers).find(
|
|
(key) => key.toLowerCase() === "subscription-userinfo"
|
|
);
|
|
if (header) {
|
|
resolve(resp.headers[header]);
|
|
return;
|
|
}
|
|
reject("链接响应头不带有流量信息");
|
|
})
|
|
);
|
|
}
|
|
|
|
async function getDataInfo(url) {
|
|
const [err, data] = await getUserInfo(url)
|
|
.then((data) => [null, data])
|
|
.catch((err) => [err, null]);
|
|
if (err) {
|
|
console.log(err);
|
|
return;
|
|
}
|
|
|
|
return Object.fromEntries(
|
|
data
|
|
.match(/\w+=[\d.eE+]+/g)
|
|
.map((item) => item.split("="))
|
|
.map(([k, v]) => [k, Number(v)])
|
|
);
|
|
}
|
|
|
|
function getRmainingDays(resetDay) {
|
|
if (!resetDay) return;
|
|
|
|
let now = new Date();
|
|
let today = now.getDate();
|
|
let month = now.getMonth();
|
|
let year = now.getFullYear();
|
|
let daysInMonth;
|
|
|
|
if (resetDay > today) {
|
|
daysInMonth = 0;
|
|
} else {
|
|
daysInMonth = new Date(year, month + 1, 0).getDate();
|
|
}
|
|
|
|
return daysInMonth - today + resetDay;
|
|
}
|
|
|
|
function bytesToSize(bytes) {
|
|
if (bytes === 0) return "0B";
|
|
let k = 1024;
|
|
sizes = ["B", "KiB", "MiB", "GiB", "TiB", "PiB"];
|
|
let i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
return (bytes / Math.pow(k, i)).toFixed(2) + " " + sizes[i];
|
|
}
|
|
|
|
function formatTime(time) {
|
|
let dateObj = new Date(time);
|
|
let year = dateObj.getFullYear();
|
|
let month = dateObj.getMonth() + 1;
|
|
let day = dateObj.getDate();
|
|
return year + "年" + month + "月" + day + "日";
|
|
} |