/** * 工具函数模块 * 提供系统常用的工具函数,包括文件下载、字符串处理、系统操作等 */ import * as os from "os" import common from '../../../dxmodules/dxCommon.js' import logger from "../../../dxmodules/dxLogger.js" const utils = {} /** * 获取URL文件的下载大小(字节数) * @param {string} url - 文件的URL地址 * @returns {number} 文件大小(字节),如果获取失败则返回0 */ utils.getUrlFileSize = function (url) { // 使用wget命令获取文件大小信息 let actualSize = common.systemWithRes(`wget --spider -S ${url} 2>&1 | grep 'Length' | awk '{print $2}'`, 100).match(/\d+/g) return actualSize ? parseInt(actualSize) : 0 } /** * 判断值是否为空(空字符串、null或undefined) * @param {*} str - 要判断的值 * @returns {boolean} 如果值为空则返回true,否则返回false */ utils.isEmpty = function (str) { return (str === "" || str === null || str === undefined) } /** * 解析字符串为JSON对象 * 注意:value内不能有"号 * @param {string} inputString - 要解析的字符串,格式为{key1=value1, key2=value2} * @returns {Object} 解析后的JSON对象 */ utils.parseString = function (inputString) { // 获取{}及其之间的内容 inputString = inputString.slice(inputString.indexOf("{"), inputString.lastIndexOf("}") + 1) // key=value正则,key是\w+(字母数字下划线,区别大小写),=两边可有空格,value是\w+或相邻两个"之间的内容(包含") const keyValueRegex = /(\w+)\s*=\s*("[^"]*"|\w+(\.\w+)?)/g; let jsonObject = {}; let match; // 遍历匹配结果,构建JSON对象 while ((match = keyValueRegex.exec(inputString)) !== null) { let key = match[1]; let value = match[2] // 根据值的类型进行转换 if (/^\d+$/.test(value)) { // 数字类型 value = parseInt(value) } else if (/^\d+\.\d+$/.test(value)) { // 小数类型 value = parseFloat(value) } else if (value == 'true') { // 布尔值true value = true } else if (value == 'false') { // 布尔值false value = false } else { // 字符串类型,去除引号和空格 value = value.replace(/"/g, '').trim() } jsonObject[key] = value; } return jsonObject; } /** * 等待文件下载完成并进行MD5校验 * 注意:超时时间不得超过喂狗时间,否则下载慢会导致系统重启 * @param {string} update_addr - 下载地址 * @param {string} downloadPath - 存储路径 * @param {number} timeout - 超时时间(毫秒) * @param {string} update_md5 - MD5校验值 * @param {number} fileSize - 文件大小(字节) * @returns {boolean} 下载结果:true表示成功,false表示失败 */ utils.waitDownload = function (update_addr, downloadPath, timeout, update_md5, fileSize) { // 删除原文件 common.systemBrief(`rm -rf "${downloadPath}"`) // 异步下载文件 common.systemBrief(`wget -c "${update_addr}" -O "${downloadPath}" &`) let startTime = new Date().getTime() // 循环检查下载进度 while (true) { // 计算已下载的文件大小 let size = parseInt(common.systemWithRes(`file="${downloadPath}"; [ -e "$file" ] && wc -c "$file" | awk '{print $1}' || echo "0"`, 100).split(/\s/g)[0]) // 如果文件大小达到预期,进行MD5校验 if (size == fileSize) { let ret = common.md5HashFile(downloadPath) if (ret) { let md5 = ret.map(v => v.toString(16).padStart(2, '0')).join('') if (md5 == update_md5) { // MD5校验成功 return true } } // MD5校验失败,删除文件 common.systemBrief(`rm -rf "${downloadPath}"`) return false } // 如果下载超时,删除下载的文件并且重启,停止异步继续下载 if (new Date().getTime() - startTime > timeout) { vf203.pwm.fail() common.systemBrief(`rm -rf "${downloadPath}"`) // 立即重启 this.restart() return false } // 暂停100毫秒后继续检查 os.sleep(100) } } /** * 立即重启 */ utils.restart = function () { common.systemBrief("reboot -f") } export default utils