mirror of
https://github.com/fofolee/uTools-quickcommand.git
synced 2025-10-09 23:13:22 +08:00
为大部分命令添加输出结构结构化数据
This commit is contained in:
@@ -58,13 +58,19 @@ const quickcommand = {
|
||||
{
|
||||
timeout: ms,
|
||||
},
|
||||
(err, stdout, stderr) => {
|
||||
() => {
|
||||
var end = new Date().getTime();
|
||||
callback(end - start);
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
asyncSleep: async function (ms) {
|
||||
return new Promise((resolve) => {
|
||||
this.setTimeout(resolve, ms);
|
||||
});
|
||||
},
|
||||
|
||||
// 关闭进程
|
||||
kill: function (pid, signal = "SIGTERM", cb) {
|
||||
kill(pid, signal, cb);
|
||||
|
@@ -72,7 +72,8 @@ const submitForm = async (tab, buttonSelector, inputSelectors) => {
|
||||
const getText = async (tab, selector) => {
|
||||
return await executeScript(
|
||||
tab,
|
||||
`document.querySelector('${selector}')?.textContent || ''`
|
||||
`const element = document.querySelector('${selector}');
|
||||
return element?.textContent || element?.innerText || '';`
|
||||
);
|
||||
};
|
||||
|
||||
@@ -80,7 +81,7 @@ const getHtml = async (tab, selector) => {
|
||||
return await executeScript(
|
||||
tab,
|
||||
`const element = document.querySelector('${selector}');
|
||||
return element ? element.innerHTML : '';`
|
||||
return element?.outerHTML || '';`
|
||||
);
|
||||
};
|
||||
|
||||
@@ -110,7 +111,7 @@ const scrollToElement = async (tab, selector) => {
|
||||
};
|
||||
|
||||
const getScrollPosition = async (tab) => {
|
||||
return await executeScript(
|
||||
const result = await executeScript(
|
||||
tab,
|
||||
`
|
||||
return JSON.stringify({
|
||||
@@ -119,10 +120,11 @@ const getScrollPosition = async (tab) => {
|
||||
});
|
||||
`
|
||||
);
|
||||
return JSON.parse(result);
|
||||
};
|
||||
|
||||
const getPageSize = async (tab) => {
|
||||
return await executeScript(
|
||||
const result = await executeScript(
|
||||
tab,
|
||||
`
|
||||
return JSON.stringify({
|
||||
@@ -137,6 +139,7 @@ const getPageSize = async (tab) => {
|
||||
});
|
||||
`
|
||||
);
|
||||
return JSON.parse(result);
|
||||
};
|
||||
|
||||
const waitForElement = async (tab, selector, timeout = 5000) => {
|
||||
|
@@ -4,6 +4,7 @@ const zlib = require("./zlib");
|
||||
const { htmlParser } = require("./htmlParser");
|
||||
const array = require("./array");
|
||||
const time = require("./time");
|
||||
const { regexTransform } = require("./regexTransform");
|
||||
|
||||
module.exports = {
|
||||
htmlParser,
|
||||
@@ -12,4 +13,5 @@ module.exports = {
|
||||
zlib,
|
||||
array,
|
||||
time,
|
||||
regexTransform,
|
||||
};
|
||||
|
9
plugin/lib/quickcomposer/data/regexTransform.js
Normal file
9
plugin/lib/quickcomposer/data/regexTransform.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const regexTransform = (text, regex, replacement) => {
|
||||
if (replacement) {
|
||||
return text.replace(regex, replacement);
|
||||
} else {
|
||||
return text.match(regex);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = { regexTransform };
|
@@ -76,44 +76,207 @@ const time = {
|
||||
parse: function (time, format) {
|
||||
if (!time) return null;
|
||||
|
||||
const now = new Date();
|
||||
let year = now.getFullYear();
|
||||
let month = now.getMonth() + 1; // 转换为正常月份
|
||||
let day = now.getDate();
|
||||
let hours = 0;
|
||||
let minutes = 0;
|
||||
let seconds = 0;
|
||||
|
||||
// 处理时间戳
|
||||
if (format === "timestamp") {
|
||||
return new Date(Number(time) * 1000);
|
||||
const date = new Date(Number(time) * 1000);
|
||||
return this._formatTimeObject(date);
|
||||
}
|
||||
if (format === "timestamp_ms") {
|
||||
return new Date(Number(time));
|
||||
const date = new Date(Number(time));
|
||||
return this._formatTimeObject(date);
|
||||
}
|
||||
|
||||
// 处理标准格式
|
||||
const now = new Date();
|
||||
const year = now.getFullYear();
|
||||
let result;
|
||||
// 如果没有指定格式,尝试自动识别
|
||||
if (!format) {
|
||||
// 尝试直接解析
|
||||
const date = new Date(time);
|
||||
if (date.getTime()) {
|
||||
return this._formatTimeObject(date);
|
||||
}
|
||||
|
||||
switch (format) {
|
||||
case "YYYY-MM-DD":
|
||||
case "YYYY-MM-DD HH:mm:ss":
|
||||
case "YYYY-MM-DD HH:mm":
|
||||
result = new Date(time);
|
||||
break;
|
||||
case "YYYY年MM月DD日":
|
||||
time = time.replace(/[年月日]/g, (match) => {
|
||||
return { 年: "-", 月: "-", 日: "" }[match];
|
||||
});
|
||||
result = new Date(time);
|
||||
break;
|
||||
case "MM/DD/YYYY":
|
||||
const [month, day, yyyy] = time.split("/");
|
||||
result = new Date(yyyy, month - 1, day);
|
||||
break;
|
||||
case "DD/MM/YYYY":
|
||||
const [dd, mm, yy] = time.split("/");
|
||||
result = new Date(yy, mm - 1, dd);
|
||||
break;
|
||||
default:
|
||||
result = new Date(time);
|
||||
// 尝试解析常见格式
|
||||
const patterns = {
|
||||
// 标准格式
|
||||
"YYYY-MM-DD HH:mm:ss":
|
||||
/^(\d{4})-(\d{1,2})-(\d{1,2}) (\d{1,2}):(\d{1,2}):(\d{1,2})$/,
|
||||
"YYYY-MM-DD HH:mm": /^(\d{4})-(\d{1,2})-(\d{1,2}) (\d{1,2}):(\d{1,2})$/,
|
||||
"YYYY-MM-DD": /^(\d{4})-(\d{1,2})-(\d{1,2})$/,
|
||||
// 中文格式
|
||||
"YYYY年MM月DD日 HH时mm分ss秒":
|
||||
/^(\d{4})年(\d{1,2})月(\d{1,2})日 (\d{1,2})时(\d{1,2})分(\d{1,2})秒$/,
|
||||
"YYYY年MM月DD日 HH:mm:ss":
|
||||
/^(\d{4})年(\d{1,2})月(\d{1,2})日 (\d{1,2}):(\d{1,2}):(\d{1,2})$/,
|
||||
YYYY年MM月DD日: /^(\d{4})年(\d{1,2})月(\d{1,2})日$/,
|
||||
// 斜杠格式
|
||||
"MM/DD/YYYY HH:mm:ss":
|
||||
/^(\d{1,2})\/(\d{1,2})\/(\d{4}) (\d{1,2}):(\d{1,2}):(\d{1,2})$/,
|
||||
"DD/MM/YYYY HH:mm:ss":
|
||||
/^(\d{1,2})\/(\d{1,2})\/(\d{4}) (\d{1,2}):(\d{1,2}):(\d{1,2})$/,
|
||||
"MM/DD/YYYY": /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/,
|
||||
"DD/MM/YYYY": /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/,
|
||||
// 点号格式
|
||||
"DD.MM.YYYY": /^(\d{1,2})\.(\d{1,2})\.(\d{4})$/,
|
||||
// 时间格式
|
||||
"HH:mm:ss": /^(\d{1,2}):(\d{1,2}):(\d{1,2})$/,
|
||||
"HH:mm": /^(\d{1,2}):(\d{1,2})$/,
|
||||
};
|
||||
|
||||
for (const [patternFormat, regex] of Object.entries(patterns)) {
|
||||
const matches = time.match(regex);
|
||||
if (matches) {
|
||||
format = patternFormat;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result.getTime() ? result : null;
|
||||
// 解析时间字符串
|
||||
const parseTimeString = (timeStr) => {
|
||||
const parts = timeStr.split(/[: ]/);
|
||||
return {
|
||||
hours: parseInt(parts[0]) || 0,
|
||||
minutes: parseInt(parts[1]) || 0,
|
||||
seconds: parseInt(parts[2]) || 0,
|
||||
};
|
||||
};
|
||||
|
||||
// 根据格式解析
|
||||
if (format) {
|
||||
// 移除所有非数字和分隔符
|
||||
const cleanTime = time.replace(/[^0-9/\-.: ]/g, "");
|
||||
const parts = cleanTime.split(/[/\-.: ]/);
|
||||
|
||||
switch (format) {
|
||||
case "YYYY-MM-DD":
|
||||
case "YYYY-MM-DD HH:mm:ss":
|
||||
case "YYYY-MM-DD HH:mm":
|
||||
case "YYYY年MM月DD日":
|
||||
case "YYYY年MM月DD日 HH:mm:ss":
|
||||
case "YYYY年MM月DD日 HH时mm分ss秒":
|
||||
year = parseInt(parts[0]);
|
||||
month = parseInt(parts[1]);
|
||||
day = parseInt(parts[2]);
|
||||
if (parts.length > 3) {
|
||||
const timeStr = parts.slice(3).join(":");
|
||||
const timeObj = parseTimeString(timeStr);
|
||||
hours = timeObj.hours;
|
||||
minutes = timeObj.minutes;
|
||||
seconds = timeObj.seconds;
|
||||
}
|
||||
break;
|
||||
case "MM/DD/YYYY":
|
||||
case "MM/DD/YYYY HH:mm:ss":
|
||||
year = parseInt(parts[2]);
|
||||
month = parseInt(parts[0]);
|
||||
day = parseInt(parts[1]);
|
||||
if (parts.length > 3) {
|
||||
const timeStr = parts.slice(3).join(":");
|
||||
const timeObj = parseTimeString(timeStr);
|
||||
hours = timeObj.hours;
|
||||
minutes = timeObj.minutes;
|
||||
seconds = timeObj.seconds;
|
||||
}
|
||||
break;
|
||||
case "DD/MM/YYYY":
|
||||
case "DD/MM/YYYY HH:mm:ss":
|
||||
case "DD.MM.YYYY":
|
||||
year = parseInt(parts[2]);
|
||||
month = parseInt(parts[1]);
|
||||
day = parseInt(parts[0]);
|
||||
if (parts.length > 3) {
|
||||
const timeStr = parts.slice(3).join(":");
|
||||
const timeObj = parseTimeString(timeStr);
|
||||
hours = timeObj.hours;
|
||||
minutes = timeObj.minutes;
|
||||
seconds = timeObj.seconds;
|
||||
}
|
||||
break;
|
||||
case "HH:mm:ss":
|
||||
case "HH:mm":
|
||||
const timeObj = parseTimeString(cleanTime);
|
||||
hours = timeObj.hours;
|
||||
minutes = timeObj.minutes;
|
||||
seconds = timeObj.seconds;
|
||||
break;
|
||||
default:
|
||||
// 尝试使用原生解析
|
||||
const date = new Date(time);
|
||||
if (date.getTime()) {
|
||||
year = date.getFullYear();
|
||||
month = date.getMonth() + 1;
|
||||
day = date.getDate();
|
||||
hours = date.getHours();
|
||||
minutes = date.getMinutes();
|
||||
seconds = date.getSeconds();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 验证日期是否有效
|
||||
const testDate = new Date(year, month - 1, day, hours, minutes, seconds);
|
||||
if (!testDate.getTime()) return null;
|
||||
|
||||
return this._formatTimeObject(testDate);
|
||||
},
|
||||
|
||||
// 格式化时间对象
|
||||
_formatTimeObject: function (date) {
|
||||
const year = date.getFullYear();
|
||||
const month = date.getMonth() + 1;
|
||||
const day = date.getDate();
|
||||
const hours = date.getHours();
|
||||
const minutes = date.getMinutes();
|
||||
const seconds = date.getSeconds();
|
||||
|
||||
return {
|
||||
date: {
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
},
|
||||
time: {
|
||||
hours,
|
||||
minutes,
|
||||
seconds,
|
||||
},
|
||||
formats: {
|
||||
// 标准格式
|
||||
iso: date.toISOString(),
|
||||
locale: date.toLocaleString(),
|
||||
localeDate: date.toLocaleDateString(),
|
||||
localeTime: date.toLocaleTimeString(),
|
||||
// 常用格式
|
||||
"YYYY-MM-DD": `${year}-${this._pad(month)}-${this._pad(day)}`,
|
||||
"YYYY-MM-DD HH:mm:ss": `${year}-${this._pad(month)}-${this._pad(
|
||||
day
|
||||
)} ${this._pad(hours)}:${this._pad(minutes)}:${this._pad(seconds)}`,
|
||||
dateCN: `${year}年${this._pad(month)}月${this._pad(day)}日`,
|
||||
"MM/DD/YYYY": `${this._pad(month)}/${this._pad(day)}/${year}`,
|
||||
"DD/MM/YYYY": `${this._pad(day)}/${this._pad(month)}/${year}`,
|
||||
"HH:mm:ss": `${this._pad(hours)}:${this._pad(minutes)}:${this._pad(
|
||||
seconds
|
||||
)}`,
|
||||
},
|
||||
timestamp: Math.floor(date.getTime() / 1000),
|
||||
timestamp_ms: date.getTime(),
|
||||
// 日历信息
|
||||
calendar: {
|
||||
week: date.getDay(),
|
||||
weekText: ["日", "一", "二", "三", "四", "五", "六"][date.getDay()],
|
||||
isWeekend: date.getDay() === 0 || date.getDay() === 6,
|
||||
isLeapYear: (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0,
|
||||
daysInMonth: new Date(year, month, 0).getDate(),
|
||||
constellation: this._getConstellation(month, day),
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
// 时间加减
|
||||
|
@@ -192,7 +192,8 @@ module.exports = {
|
||||
|
||||
// 启动应用
|
||||
launch: async function (appName) {
|
||||
return await quickcommand.runAppleScript(`
|
||||
if (!appName) return;
|
||||
await quickcommand.runAppleScript(`
|
||||
tell application "${appName}"
|
||||
activate
|
||||
end tell
|
||||
@@ -201,7 +202,8 @@ module.exports = {
|
||||
|
||||
// 退出应用
|
||||
quit: async function (appName) {
|
||||
return await quickcommand.runAppleScript(`
|
||||
if (!appName) return;
|
||||
await quickcommand.runAppleScript(`
|
||||
tell application "${appName}"
|
||||
quit
|
||||
end tell
|
||||
@@ -210,7 +212,8 @@ module.exports = {
|
||||
|
||||
// 隐藏应用
|
||||
hide: async function (appName) {
|
||||
return await quickcommand.runAppleScript(`
|
||||
if (!appName) return;
|
||||
await quickcommand.runAppleScript(`
|
||||
tell application "System Events"
|
||||
set visible of process "${appName}" to false
|
||||
end tell
|
||||
@@ -219,7 +222,8 @@ module.exports = {
|
||||
|
||||
// 显示应用
|
||||
show: async function (appName) {
|
||||
return await quickcommand.runAppleScript(`
|
||||
if (!appName) return;
|
||||
await quickcommand.runAppleScript(`
|
||||
tell application "System Events"
|
||||
set visible of process "${appName}" to true
|
||||
end tell
|
||||
@@ -231,7 +235,8 @@ module.exports = {
|
||||
|
||||
// 最小化窗口
|
||||
minimize: async function (appName) {
|
||||
return await quickcommand.runAppleScript(`
|
||||
if (!appName) return;
|
||||
await quickcommand.runAppleScript(`
|
||||
tell application "System Events"
|
||||
tell process "${appName}"
|
||||
try
|
||||
@@ -244,7 +249,8 @@ module.exports = {
|
||||
|
||||
// 最大化窗口
|
||||
maximize: async function (appName) {
|
||||
return await quickcommand.runAppleScript(`
|
||||
if (!appName) return;
|
||||
await quickcommand.runAppleScript(`
|
||||
tell application "System Events"
|
||||
tell process "${appName}"
|
||||
try
|
||||
@@ -258,6 +264,7 @@ module.exports = {
|
||||
|
||||
// 获取窗口信息
|
||||
getWindows: async function (appName) {
|
||||
if (!appName) return;
|
||||
const result = await quickcommand.runAppleScript(`
|
||||
tell application "System Events"
|
||||
tell process "${appName}"
|
||||
@@ -341,6 +348,7 @@ module.exports = {
|
||||
|
||||
// 获取应用脚本字典
|
||||
getScriptDictionary: async function (appName) {
|
||||
if (!appName) return;
|
||||
try {
|
||||
const { execSync } = require("child_process");
|
||||
|
||||
|
@@ -23,7 +23,7 @@ module.exports = {
|
||||
return json
|
||||
end tell
|
||||
`);
|
||||
return JSON.parse(result);
|
||||
return JSON.parse(result.replace(/missing value/g, "null"));
|
||||
},
|
||||
|
||||
// 获取当前文件夹
|
||||
|
@@ -54,17 +54,6 @@ function formatQuery(queryParams) {
|
||||
}
|
||||
}
|
||||
|
||||
// 解析路径名
|
||||
function parsePath(path) {
|
||||
return url.parse(path);
|
||||
}
|
||||
|
||||
// 解析主机名
|
||||
function parseHost(host) {
|
||||
const { hostname, port } = url.parse(`http://${host}`);
|
||||
return { hostname, port };
|
||||
}
|
||||
|
||||
// 解析 URL 参数
|
||||
function getQueryParam(urlString, param) {
|
||||
const { query } = url.parse(urlString, true);
|
||||
@@ -92,32 +81,13 @@ function isAbsolute(urlString) {
|
||||
return url.parse(urlString).protocol !== null;
|
||||
}
|
||||
|
||||
// 解析 URL 的各个部分
|
||||
function parseComponents(urlString) {
|
||||
const { protocol, auth, hostname, port, pathname, search, hash } =
|
||||
url.parse(urlString);
|
||||
|
||||
return {
|
||||
protocol: protocol?.replace(":", ""),
|
||||
auth,
|
||||
hostname,
|
||||
port,
|
||||
pathname,
|
||||
search: search?.replace("?", ""),
|
||||
hash: hash?.replace("#", ""),
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
parse,
|
||||
format,
|
||||
parseQuery,
|
||||
formatQuery,
|
||||
parsePath,
|
||||
parseHost,
|
||||
getQueryParam,
|
||||
addQueryParam,
|
||||
removeQueryParam,
|
||||
isAbsolute,
|
||||
parseComponents,
|
||||
};
|
||||
|
Reference in New Issue
Block a user