/* 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 + "日"; }