mirror of
https://github.com/rubickCenter/rubick
synced 2025-07-19 14:19:39 +08:00
121 lines
4.3 KiB
JavaScript
121 lines
4.3 KiB
JavaScript
import fs from "fs";
|
|
import path from "path";
|
|
import {nativeImage} from "electron";
|
|
import translate from "./translate";
|
|
import {APP_FINDER_PATH} from "./constans";
|
|
import iconvLite from "iconv-lite";
|
|
import bpList from "bplist-parser";
|
|
|
|
const fileLists = [];
|
|
|
|
const isZhRegex = /[\u4e00-\u9fa5]/;
|
|
const getDisplayNameRegex = /\"(?:CFBundleDisplayName)\"\s\=\s\"(.*)\"/;
|
|
|
|
async function getAppZhName(rootPath, appName) {
|
|
try {
|
|
const ERROR_RESULT = '';
|
|
const systemPath = path.join(rootPath, `${appName}/Contents/Resources/zh_CN.lproj/InfoPlist.strings`);
|
|
const customizePath = path.join(rootPath, `${appName}/Contents/Resources/zh-Hans.lproj/InfoPlist.strings`);
|
|
let appInfoPath = '';
|
|
|
|
if (fs.existsSync(systemPath)) {
|
|
appInfoPath = systemPath;
|
|
} else if (fs.existsSync(customizePath)) {
|
|
appInfoPath = customizePath;
|
|
} else {
|
|
return ERROR_RESULT;
|
|
}
|
|
let appZhName = '';
|
|
if (rootPath == '/Applications') {
|
|
const container = iconvLite.decode(fs.readFileSync(appInfoPath), 'utf-16');
|
|
if (container) {
|
|
const res = container.match(getDisplayNameRegex);
|
|
appZhName = res && res[1];
|
|
} else {
|
|
return ERROR_RESULT;
|
|
}
|
|
} else {
|
|
const [{ CFBundleDisplayName = '', CFBundleName = '' }] = await bpList.parseFile(appInfoPath);
|
|
appZhName = CFBundleDisplayName || CFBundleName;
|
|
}
|
|
|
|
return appZhName;
|
|
} catch (error) {
|
|
return ERROR_RESULT;
|
|
}
|
|
}
|
|
|
|
function getDarwinAppList () {
|
|
APP_FINDER_PATH.forEach((searchPath, index) => {
|
|
fs.readdir(searchPath, async (err, files) => {
|
|
try {
|
|
for (let i = 0; i < files.length; i++) {
|
|
const appName = files[i];
|
|
const extname = path.extname(appName);
|
|
const appSubStr = appName.split(extname)[0];
|
|
if ((extname === '.app' || extname === '.prefPane') >= 0) {
|
|
try {
|
|
const path1 = path.join(searchPath, `${appName}/Contents/Resources/App.icns`);
|
|
const path2 = path.join(searchPath, `${appName}/Contents/Resources/AppIcon.icns`);
|
|
const path3 = path.join(searchPath, `${appName}/Contents/Resources/${appSubStr}.icns`);
|
|
const path4 = path.join(searchPath, `${appName}/Contents/Resources/${appSubStr.replace(' ', '')}.icns`);
|
|
let iconPath = path1;
|
|
if (fs.existsSync(path1)) {
|
|
iconPath = path1;
|
|
} else if (fs.existsSync(path2)) {
|
|
iconPath = path2;
|
|
} else if (fs.existsSync(path3)) {
|
|
iconPath = path3;
|
|
} else if (fs.existsSync(path4)) {
|
|
iconPath = path4;
|
|
} else {
|
|
// 性能最低的方式
|
|
const resourceList = fs.readdirSync(path.join(searchPath, `${appName}/Contents/Resources`));
|
|
const iconName = resourceList.filter((file) => path.extname(file) === '.icns')[0];
|
|
iconPath = path.join(searchPath, `${appName}/Contents/Resources/${iconName}`);
|
|
}
|
|
const img = await nativeImage.createThumbnailFromPath(iconPath, { width: 64, height: 64 });
|
|
|
|
const appZhName = await getAppZhName(searchPath, appName);
|
|
|
|
const fileOptions = {
|
|
value: 'plugin',
|
|
icon: img.toDataURL(),
|
|
desc: path.join(searchPath, appName),
|
|
type: 'app',
|
|
action: `open ${path.join(searchPath, appName).replace(' ', '\\ ')}`,
|
|
keyWords: [appSubStr]
|
|
};
|
|
|
|
if (appZhName && isZhRegex.test(appZhName)) {
|
|
const py = translate(appZhName);
|
|
const pinyinArr = py.split(',');
|
|
const firstLatter = pinyinArr.map(py => py[0]);
|
|
// 拼音
|
|
fileOptions.keyWords.push(pinyinArr.join(''));
|
|
// 缩写
|
|
fileOptions.keyWords.push(firstLatter.join(''));
|
|
// 中文
|
|
fileOptions.keyWords.push(appZhName);
|
|
}
|
|
|
|
fileLists.push({
|
|
...fileOptions,
|
|
name: appSubStr,
|
|
names: JSON.parse(JSON.stringify(fileOptions.keyWords)),
|
|
});
|
|
} catch (e) {}
|
|
}
|
|
}
|
|
} catch (e) {
|
|
console.log(e);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
export const getApp = {
|
|
init: getDarwinAppList,
|
|
fileLists,
|
|
}
|