本人是一个魔兽世界老玩家,因为今年twitch的curse客户端已国内不发正常使用了,致使如今更新插件每次要去网站上下载,而后在手动拖到魔兽插件的根目录替换,很是麻烦并且容易搞错。因此就萌生了本身实现一个简版的twitch功能,curse在国内能够访问因此打算就用electron来作,内置nodejs环境这样我能够用爬虫爬取curse网站的插件数据,获取插件列表,插件下载地址,而后下载zip包解压安装到wow插件目录,彻底自动化。html
getAddonsList = (path:string, page?:number) : Promise<any> => {
return new Promise((resolve) => {
let timer = setTimeout(():void => {
electron.ipcRenderer.removeListener('getBaseAddons', () => {});
resolve(TIME_OUT_KEY)
}, AJAX_TIME_OUT);
electron.ipcRenderer.send('baseAddons', path, page);
electron.ipcRenderer.on('getBaseAddons', (e:any, data:any) => {
clearTimeout(timer);
electron.ipcRenderer.removeListener('getBaseAddons', () => {});
resolve(data)
})
})
};
复制代码
getAddonDownUrl = (rowData: any = {}): Promise<any> => {
const installFilePath = localStorage.getItem(WOW_ADDONS_FILE_PATH_KEY);
return new Promise((resolve) => {
let timer = setTimeout((): void => {
electron.ipcRenderer.removeListener(`${rowData.path}-getDownAddonUrl`, () => {});
resolve(TIME_OUT_KEY);
}, AJAX_TIME_OUT);
electron.ipcRenderer.send('downAddon', rowData, installFilePath);
electron.ipcRenderer.on(`${rowData.path}-getDownAddonUrl`, (e:any, data:any) => {
if (data) {
resolve(data);
}
electron.ipcRenderer.removeListener(`${rowData.path}-getDownAddonUrl`, () => {});
clearTimeout(timer);
});
})
};
复制代码
handleDownloading = (downloadUrl: string, rowData: any): void => { // 下载插件
let file = `${this.state.installFilePath}/${rowData.label}_${Date.now()}.zip`;
let writeStream = fs.createWriteStream(file);
this.setState({ loading: true, btnTxt: LOAD_BTN_TXT, zipFile: file });
request.get(downloadUrl).pipe(writeStream);
// 开始下载
writeStream.on('drain', () : void => {});
// 下载成功
writeStream.on('finish', (): void => {
this.setState({ btnTxt: INSTALL_BTN_TXT });
this.unzipAddon().then((folderList: Array<any>): void => {
this.handleInstallDown(folderList, rowData);
})
});
// 下载失败
writeStream.on('error', ():void => {
rimraf(file, () => {});
this.setState({ loading: false, btnTxt: `下载插件失败重试` });
})
};
复制代码
unzipAddon = (): Promise<any> => { // 解压插件zip包
return new Promise((resolve) => {
const zip = new AdmZip(this.state.zipFile);
const folderList: Array<any> = [];
zip.getEntries().forEach((entry:any) => {
const entryName = entry.entryName;
const folderName = entryName.split('/')[0];
if (folderList.indexOf(folderName) === -1) {
folderList.push(folderName);
}
});
// 执行解压
zip.extractAllTo(this.state.installFilePath, true);
resolve(folderList)
})
};
复制代码
handleInstallDown = (folderList:Array<any>, rowData:any): void => {
const fileJson = `${this.state.installFilePath}/${INSTALL_ADDONS}`;
const { setMyAddonList, updateAddonList, setUpdateAddonList } = this.props.store!;
if (!fs.existsSync(fileJson)) {
fs.writeFileSync(fileJson, '[]')
}
const item = JSON.parse(JSON.stringify(rowData));
item.folderList = folderList;
// 同步本地插件列表
myAddon.setAddon(item);
// 从新获取一次安装插件列表
setMyAddonList(myAddon.getAddonList());
// 删除zip包
rimraf(this.state.zipFile, () => {});
// 若安装的插件在须要更新的列表里存在则删除掉
let cacheUpdateAddonList = JSON.parse(JSON.stringify(updateAddonList));
if (cacheUpdateAddonList.filter((v:any) => v.path === rowData.path).length !== 0) {
setUpdateAddonList(cacheUpdateAddonList.filter((v:any) => v.path !== rowData.path))
}
this.setState({ btnTxt: SUCCESS_BTN_TXT, loading: false });
};
复制代码