2925邮箱增加账号池功能
This commit is contained in:
@@ -0,0 +1,162 @@
|
||||
(function mail2925UtilsModule(root, factory) {
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = factory();
|
||||
return;
|
||||
}
|
||||
|
||||
root.Mail2925Utils = factory();
|
||||
})(typeof self !== 'undefined' ? self : globalThis, function createMail2925Utils() {
|
||||
const MAIL2925_LIMIT_COOLDOWN_MS = 24 * 60 * 60 * 1000;
|
||||
|
||||
function normalizeTimestamp(value) {
|
||||
const numeric = Number(value);
|
||||
return Number.isFinite(numeric) && numeric > 0 ? numeric : 0;
|
||||
}
|
||||
|
||||
function normalizeMail2925Account(account = {}) {
|
||||
return {
|
||||
id: String(account.id || crypto.randomUUID()),
|
||||
email: String(account.email || '').trim().toLowerCase(),
|
||||
password: String(account.password || ''),
|
||||
enabled: account.enabled !== undefined ? Boolean(account.enabled) : true,
|
||||
lastUsedAt: normalizeTimestamp(account.lastUsedAt),
|
||||
lastLoginAt: normalizeTimestamp(account.lastLoginAt),
|
||||
lastLimitAt: normalizeTimestamp(account.lastLimitAt),
|
||||
disabledUntil: normalizeTimestamp(account.disabledUntil),
|
||||
lastError: String(account.lastError || '').trim(),
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeMail2925Accounts(accounts) {
|
||||
if (!Array.isArray(accounts)) return [];
|
||||
|
||||
const deduped = new Map();
|
||||
for (const account of accounts) {
|
||||
const normalized = normalizeMail2925Account(account);
|
||||
if (!normalized.email) continue;
|
||||
deduped.set(normalized.id, normalized);
|
||||
}
|
||||
return [...deduped.values()];
|
||||
}
|
||||
|
||||
function findMail2925Account(accounts, accountId) {
|
||||
return normalizeMail2925Accounts(accounts).find((account) => account.id === accountId) || null;
|
||||
}
|
||||
|
||||
function isMail2925AccountCoolingDown(account, now = Date.now()) {
|
||||
return normalizeTimestamp(account?.disabledUntil) > normalizeTimestamp(now);
|
||||
}
|
||||
|
||||
function isMail2925AccountAvailable(account, now = Date.now()) {
|
||||
return Boolean(account)
|
||||
&& Boolean(account.email)
|
||||
&& Boolean(account.password)
|
||||
&& account.enabled !== false
|
||||
&& !isMail2925AccountCoolingDown(account, now);
|
||||
}
|
||||
|
||||
function getMail2925AccountStatus(account, now = Date.now()) {
|
||||
if (!account) return 'missing';
|
||||
if (account.enabled === false) return 'disabled';
|
||||
if (isMail2925AccountCoolingDown(account, now)) return 'cooldown';
|
||||
if (!account.password) return 'pending';
|
||||
if (account.lastError) return 'error';
|
||||
return 'ready';
|
||||
}
|
||||
|
||||
function filterMail2925AccountsByStatus(accounts, mode = 'all', now = Date.now()) {
|
||||
const list = normalizeMail2925Accounts(accounts);
|
||||
switch (String(mode || 'all').trim()) {
|
||||
case 'available':
|
||||
return list.filter((account) => isMail2925AccountAvailable(account, now));
|
||||
case 'cooldown':
|
||||
return list.filter((account) => isMail2925AccountCoolingDown(account, now));
|
||||
case 'disabled':
|
||||
return list.filter((account) => account.enabled === false);
|
||||
default:
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
function pickMail2925AccountForRun(accounts, options = {}) {
|
||||
const now = normalizeTimestamp(options.now) || Date.now();
|
||||
const excludeIds = new Set((options.excludeIds || []).filter(Boolean));
|
||||
const candidates = normalizeMail2925Accounts(accounts)
|
||||
.filter((account) => isMail2925AccountAvailable(account, now));
|
||||
if (!candidates.length) return null;
|
||||
|
||||
const filtered = candidates.filter((account) => !excludeIds.has(account.id));
|
||||
const pool = filtered.length ? filtered : candidates;
|
||||
|
||||
return pool
|
||||
.slice()
|
||||
.sort((left, right) => {
|
||||
const leftUsedAt = normalizeTimestamp(left.lastUsedAt);
|
||||
const rightUsedAt = normalizeTimestamp(right.lastUsedAt);
|
||||
if (leftUsedAt !== rightUsedAt) {
|
||||
return leftUsedAt - rightUsedAt;
|
||||
}
|
||||
return String(left.email || '').localeCompare(String(right.email || ''));
|
||||
})[0] || null;
|
||||
}
|
||||
|
||||
function getMail2925BulkActionLabel(mode = 'all', count = 0) {
|
||||
const normalizedCount = Number.isFinite(Number(count)) ? Math.max(0, Number(count)) : 0;
|
||||
const prefix = mode === 'cooldown' ? '清空冷却' : '全部删除';
|
||||
const suffix = normalizedCount > 0 ? `(${normalizedCount})` : '';
|
||||
return `${prefix}${suffix}`;
|
||||
}
|
||||
|
||||
function getMail2925ListToggleLabel(expanded, count = 0) {
|
||||
const normalizedCount = Number.isFinite(Number(count)) ? Math.max(0, Number(count)) : 0;
|
||||
const suffix = normalizedCount > 0 ? `(${normalizedCount})` : '';
|
||||
return `${expanded ? '收起列表' : '展开列表'}${suffix}`;
|
||||
}
|
||||
|
||||
function upsertMail2925AccountInList(accounts, nextAccount) {
|
||||
const list = Array.isArray(accounts) ? accounts.slice() : [];
|
||||
if (!nextAccount?.id) return list;
|
||||
|
||||
const existingIndex = list.findIndex((account) => account?.id === nextAccount.id);
|
||||
if (existingIndex === -1) {
|
||||
list.push(nextAccount);
|
||||
return list;
|
||||
}
|
||||
|
||||
list[existingIndex] = nextAccount;
|
||||
return list;
|
||||
}
|
||||
|
||||
function parseMail2925ImportText(rawText) {
|
||||
const lines = String(rawText || '')
|
||||
.split(/\r?\n/)
|
||||
.map((line) => line.trim())
|
||||
.filter(Boolean);
|
||||
|
||||
return lines
|
||||
.filter((line, index) => !(index === 0 && /^邮箱----密码$/i.test(line)))
|
||||
.map((line) => line.split('----').map((part) => part.trim()))
|
||||
.filter((parts) => parts.length >= 2 && parts[0] && parts[1])
|
||||
.map(([email, password]) => ({
|
||||
email,
|
||||
password,
|
||||
}));
|
||||
}
|
||||
|
||||
return {
|
||||
MAIL2925_LIMIT_COOLDOWN_MS,
|
||||
filterMail2925AccountsByStatus,
|
||||
findMail2925Account,
|
||||
getMail2925AccountStatus,
|
||||
getMail2925BulkActionLabel,
|
||||
getMail2925ListToggleLabel,
|
||||
isMail2925AccountAvailable,
|
||||
isMail2925AccountCoolingDown,
|
||||
normalizeMail2925Account,
|
||||
normalizeMail2925Accounts,
|
||||
normalizeTimestamp,
|
||||
parseMail2925ImportText,
|
||||
pickMail2925AccountForRun,
|
||||
upsertMail2925AccountInList,
|
||||
};
|
||||
});
|
||||
Reference in New Issue
Block a user