LaiTool/src/main/index.js
2024-06-01 15:08:22 +08:00

485 lines
15 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import fspromises from "fs/promises";
import { v4 as uuidv4 } from 'uuid';
import { version } from '../../package.json'
import { graphics } from "systeminformation"
import { app, shell, BrowserWindow, ipcMain, dialog, nativeTheme } from 'electron'
import path, { join } from 'path'
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
import icon from '../../resources/icon.ico?asset'
import { define } from '../define/define.js'
import { func } from './func.js'
import { AsyncQueue } from "./quene.js"
import { DEFINE_STRING } from '../define/define_string.js'
import { Tools } from './tools.js'
import { ImageGenerate } from './backPrompt/imageGenerate.js'
import { Setting } from './setting/setting.js'
import { has, isEmpty } from 'lodash'
// ipc
import { SettingIpc } from './IPCEvent/settingIpc.js'
import { ImageGenerateIpc } from './IPCEvent/imageGenerateIpc.js'
import { WritingIpc } from './IPCEvent/writingIpc.js'
import { VideoGenerateIpc } from './IPCEvent/videoGenerateIpc'
import { TranslateIpc } from './IPCEvent/translateIpc.js'
import { GptIpc } from './IPCEvent/gptIpc.js'
import { MjIpc } from './IPCEvent/mjIpc.js'
import { OriginalImageGenerateIpc } from './IPCEvent/originalImageGenerateIpc'
import { SdIpc } from './IPCEvent/sdIpc.js'
import { DiscordIpc, RemoveDiscordIpc } from './IPCEvent/discordIpc.js'
import { MainIpc } from './IPCEvent/mainIpc.js'
import { GlobalIpc } from "./IPCEvent/globalIpc.js";
import { ImageIpc } from "./IPCEvent/imageIpc.js";
import { system } from "systeminformation";
let tools = new Tools();
let imageGenerate = new ImageGenerate(global);
let setting = new Setting(global);
async function InitData(gl) {
let res = await setting.getSettingDafultData();
gl.config = res;
gl.requestQuene = new AsyncQueue(gl, res.task_number);
gl.fileQueue = new AsyncQueue(gl, 1);
return res;
}
function setIpcHandler(hash) {
if (hash == "discord") {
DiscordIpc(global);
}
}
function removeIpcHandler(hash) {
if (hash == "discord") {
RemoveDiscordIpc();
}
}
async function createWindow(hash = "ShowMessage", data, url = null) {
// Create the browser window.
await InitData(global);
global.currentHash = hash;
// 判断当前是不是有设置的宽高,用的话记忆
let isRe = global.config.window_wh_bm_remember && hash == "ShowMessage" && global.config.window_wh_bm;
let mainWindow = new BrowserWindow({
width: isRe ? global.config.window_wh_bm.width : 900,
height: isRe ? global.config.window_wh_bm.height : 675,
x: isRe ? global.config.window_wh_bm.x : 100,
y: isRe ? global.config.window_wh_bm.y : 100,
title: 'LAITool',
icon: '../../resources/icon.ico',
show: false,
autoHideMenuBar: true,
...(process.platform === 'linux' ? { icon } : {}),
webPreferences: {
preload: join(__dirname, '../preload/index.js'),
sandbox: false,
nodeIntegration: (hash == 'discord' ? false : true), // 在网页中集成Node
nodeIntegrationInWorker: true,
webSecurity: false,
partition: "persist:my-partition",
}
})
mainWindow.myID = uuidv4();
mainWindow.on('ready-to-show', () => {
mainWindow.show()
})
mainWindow.webContents.setWindowOpenHandler((details) => {
shell.openExternal(details.url)
return { action: 'deny' }
})
// HMR for renderer base on electron-vite cli.
// Load the remote URL for development or the local html file for production.
// 判断是不是加载外部网页
if (url) {
mainWindow.loadURL(url)
} else {
if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'] + "/#/" + hash);
mainWindow.webContents.openDevTools();
} else {
if (hash != "") {
mainWindow.loadURL(`file://${path.join(__dirname, '../renderer/index.html')}#/${hash}`)
} else {
mainWindow.loadFile(join(__dirname, '../renderer/index.html'))
}
}
}
mainWindow.on("close", async () => {
// 判断指定的窗口,移除指定的监听
removeIpcHandler(hash);
global.newWindow = global.newWindow.filter(item => item.id != mainWindow.id)
// 判断当前的是不是开启了记录功能
if (global.config.window_wh_bm_remember && hash == "ShowMessage") {
let window_wh_bm = mainWindow.getBounds();
// 记录到文件中
await setting.ModifySampleSetting(JSON.stringify({ window_wh_bm: window_wh_bm }))
}
})
// 创建一个新的窗口,添加对应的监听
global.newWindow.push({
hash,
id: mainWindow.id,
win: mainWindow,
init_folder: data
})
setIpcHandler(hash);
return mainWindow;
}
let mainWindow;
global.createWindow = createWindow;
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(async () => {
// Set app user model id for windows
electronApp.setAppUserModelId('com.electron')
// Default open or close DevTools by F12 in development
// and ignore CommandOrControl + R in production.
// see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils
app.on('browser-window-created', (_, window) => {
optimizer.watchWindowShortcuts(window)
})
//
global.newWindow = [];
mainWindow = createWindow('ShowMessage', null)
//判断是不是又配置文件没有的话将temp中的基础配置加载
// 判断文件夹是不是存在
let config_p = path.dirname(define.config_path);
let isE = await tools.checkExists(config_p);
// 文件夹存在判断json文件数量
let ex_json = [];
if (isE) {
let ex_json_path = await tools.getFilesWithExtensions(config_p, '.json');
for (let i = 0; i < ex_json_path.length; i++) {
const element = ex_json_path[i];
ex_json.push(path.basename(element));
}
} else {
await fspromises.mkdir(config_p, { recursive: true });
}
// 判断文件是不是存在,不存在添加
if (ex_json.length != 5) {
let temp_path = path.join(path.dirname(define.draft_temp_path), 'config');
let tmp_json_path = await tools.getFilesWithExtensions(temp_path, ".json");
for (let i = 0; i < tmp_json_path.length; i++) {
const element = tmp_json_path[i];
if (!ex_json.includes(path.basename(element))) {
await fspromises.copyFile(element, path.join(config_p, path.basename(element)))
}
}
}
// 判断动态文件是不是存在
tools.checkJsonFileExistsOrCreate(path.normalize(define.dynamic_setting));
// 判断标签文件是不是存在
tools.checkJsonFileExistsOrCreate(path.normalize(define.tag_setting));
// 判断SD图片缓存文件是不是存在不存在创建
tools.checkFolderExistsOrCreate(path.normalize(define.temp_sd_image));
tools.checkFolderExistsOrCreate(path.normalize(path.join(define.image_path, "c_s")));
app.on('activate', async function () {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) {
mainWindow = createWindow('ShowMessage', null)
}
})
})
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
SettingIpc();
ImageGenerateIpc();
WritingIpc();
VideoGenerateIpc();
TranslateIpc();
GptIpc();
SdIpc();
MjIpc();
MainIpc(createWindow);
OriginalImageGenerateIpc();
GlobalIpc();
ImageIpc();
ipcMain.handle('dark-mode:toggle', (event, value) => {
if (value) {
nativeTheme.themeSource = value;
} else {
nativeTheme.themeSource = "system";
}
return nativeTheme.shouldUseDarkColors
})
// In this file you can include the rest of your app"s specific main process
// code. You can also put them in separate files and require them here.
ipcMain.handle(DEFINE_STRING.GET_SETTING_Dafault_DATA, async (event) => {
return await InitData(global);
})
ipcMain.handle(DEFINE_STRING.GET_DRAFT_FILE_LIST, async (event) => {
let res = await func.getDraftFileList();
return res;
})
ipcMain.handle(DEFINE_STRING.SELECT_FOLDER, async (event, value = null) => {
let po = ['openDirectory'];
if (value && !isEmpty(value.multi)) {
po.push('multiSelections');
}
let { filePaths } = await dialog.showOpenDialog({
properties: po,
defaultPath: value && !isEmpty(value.defaultPath) ? value.defaultPath : ""
})
return filePaths;
})
ipcMain.handle(DEFINE_STRING.SELECT_FILE, async (event, value) => {
try {
let { filePaths } = await dialog.showOpenDialog({
properties: ['openFile'],
filters: [
{ name: "fileName", extensions: value }
]
})
return {
code: 1,
value: filePaths[0]
}
} catch (error) {
return {
code: 0,
message: `Error Message ${error}`
}
}
})
ipcMain.handle(DEFINE_STRING.GET_DRAFT_TEXT_STYLE, async (event, value) => {
let res = await func.getDraftTextStyle(value);
return res;
})
ipcMain.handle(DEFINE_STRING.GET_TEXT_STYLE_LIST, async (event) => {
let res = await func.getClipSetting("text_style");
return res;
})
ipcMain.handle(DEFINE_STRING.GET_FRIENDLY_REMINDER_LIST, async (event) => {
let res = await func.getClipSetting("friendly_reminder_setting");
return res;
})
ipcMain.handle(DEFINE_STRING.GET_FRIENDLY_REMINDER_DRAFT, async (event, value) => {
let res = await func.GetDraftFriendlyReminder(value);
return res;
})
ipcMain.handle(DEFINE_STRING.ADD_DRAFT, async (event, value) => {
let res = await func.addDraft(value);
return res;
})
// 获取当前版本
ipcMain.handle(DEFINE_STRING.GET_VERSION, async (event) => {
// 获取当前电脑的显卡信息
let da = await graphics();
for (let i = 0; i < da.controllers.length; i++) {
// 获取第一个英伟达或者是AMD的显卡信息
const element = da.controllers[i];
if (element.vendor.startsWith("NVIDIA")) {
global.gpu = element;
global.gpu.type = "NVIDIA";
break;
} else if (element.vendor.startsWith("AMD") || element.vendor.startsWith("Advanced")) {
global.gpu = element;
global.gpu.type = "AMD";
break;
} else {
global.gpu = {
name: "OTHER"
};
global.gpu.type = "OTHER";
}
}
return version + " " + (global.gpu?.name ? global.gpu.name : "");
});
// 监听保存SD配置
ipcMain.handle(DEFINE_STRING.SAVE_SD_CONFIG, async (event, value) => await func.SaveSDConfig(value))
// 监听保存生成视频的简单配置
ipcMain.handle(DEFINE_STRING.SAVE_GENERAL_SETTING, async (event, value) => await func.SaveGeneralSetting(value));
// 获取当前的视频合成配置信息
ipcMain.handle(DEFINE_STRING.GET_VIDEO_CONFIG_MESSAGE, async (event) => await func.GetVideoConfigMessage());
// 监听保存字幕的是指信息
ipcMain.handle(DEFINE_STRING.SAVE_ASS_CONFIG, async (event, value) => await func.SaveAssConfig(value));
// 监听获取当前系统安装的字体
ipcMain.handle(DEFINE_STRING.GET_SYSTEM_INSTALL_FONTNAME, async (event) => await func.GetSystemInstallFontName());
// 监听删除视频配置任务删除指定ID的值
ipcMain.handle(DEFINE_STRING.DELETE_VIDEO_CONFIG, async (event, value) => await func.DeleteVideoConfig(value));
// 监听添加生图任务信息
ipcMain.handle(DEFINE_STRING.ADD_IMAGE_TASK_LIST, async (event, value) => await func.AddImageTask(value));
// 监听删除生成图片列表中的信息
ipcMain.handle(DEFINE_STRING.DELETE_IMAGE_TASK_LIST, async (event, value) => await func.DeleteImageTaskList(value));
// 监听获取加密的机械码任务
ipcMain.handle(DEFINE_STRING.GET_MACHINE_ID, async (event, value) => await func.GetMachineId());
// 监听获取不想要的提示词任务
ipcMain.handle(DEFINE_STRING.GET_BAD_PROMPT, async (event) => await func.GetBadPrompt());
// 保存不想要的提示词
ipcMain.handle(DEFINE_STRING.SAVE_BAD_PROMPT, async (event, value) => await func.SaveBadPrompt(value));
// 一键删除不想要的值
ipcMain.handle(DEFINE_STRING.DELETE_BAD_PROMPT, async (event) => await func.DeleteBadPrompt());
// 监听反推任务
ipcMain.handle(DEFINE_STRING.PUSH_BACK_PROMPT, async (event) => await func.PushBackPrompt());
// 打开GPT购买界面
ipcMain.on(DEFINE_STRING.OPEN_GPT_BUY_URL, async (event, value) => await func.openGptBuyUrl(value));
// 监听打开任意网站的任务
ipcMain.on(DEFINE_STRING.OPEN_URL, async (event, value) => await func.OpenUrl(value));
// 监听抽帧任务
ipcMain.handle(DEFINE_STRING.GET_FRAME, async (event, value) => await func.getFrame(value));
// 监听获取ADtailer列表的任务
ipcMain.handle(DEFINE_STRING.GET_ADETAILER_LIST, async (event) => await func.GetADetailerList());
// 监听保存ADtailer数据
ipcMain.handle(DEFINE_STRING.SAVE_DETAILER_CONFIG, async (event, value) => await func.SaveADetailerConfig(value));
// 分镜识别。语音识别
ipcMain.handle(DEFINE_STRING.START_STORY_BOARDING, async (event, value) => await func.StartStoryboarding(value));
// 保存试用结束时间
ipcMain.on(DEFINE_STRING.SAVE_TRIAL_END_TIME, (event, value) => {
global.endTime = value.endTime;
global.permissions = value.permissions;
});
// 获取当前机器的权限
ipcMain.handle(DEFINE_STRING.GET_PERMISSION, async (event) => {
return {
code: 1,
endTime: global.endTime,
permissions: global.permissions
}
})
// 试用文件资源打开指定的文件夹
ipcMain.on(DEFINE_STRING.OPEN_FOLDER, (event, value) => shell.openPath(path.join(global.config.project_path, "tmp/" + value)));
// 监听字幕的保存
ipcMain.handle(DEFINE_STRING.SAVE_NEW_WORD, async (event, value) => {
return await func.SaveNewWord(value);
})
/**
* 监听字幕对齐任务,通过前端传过来的数据
*/
ipcMain.handle(DEFINE_STRING.ALIGN_DRAFT_IMG_TO_TEXT, async (event, value) => {
return await func.alginDraftImgToText(value);
})
/**
* 监听单张重绘任务
*/
ipcMain.handle(DEFINE_STRING.RE_GENERATE_IAMGE_ONE, async (event, value) => {
console.log(value[0]);
let newWindow = global.newWindow.filter(item => item.id == value[0]);
let res = await func.ReGenerateImageOne(newWindow, value)
return res;
})
/**
* 监听文件夹高清任务
*/
ipcMain.handle(DEFINE_STRING.IMPROVE_IMAGE_RESOULTION, async (event, value) => {
let res = await imageGenerate.ImproveResolution(value);
return res;
})
/**
* 监听刷新窗口的事件
*/
ipcMain.handle(DEFINE_STRING.REFRASH_IMAGWE_DATA, async (event, value) => {
console.log(value)
let newWindow = global.newWindow.filter(item => item.id == value[0]);
let img_dir = path.join(global.config.project_path, "tmp/" + value[1]);
let res = await imageGenerate.getFolderImageList(newWindow, img_dir, true);
return res;
})
// 监听打开全局窗口事件
ipcMain.on(DEFINE_STRING.SHOW_GLOABAL_MESSAGE_DIALOG, (event, value) => {
global.newWindow[0].win.webContents.send(DEFINE_STRING.SHOW_MESSAGE_DIALOG, value)
})
/**
* 监听一个窗口,返回窗口创建成功后需要的基础数据
*/
ipcMain.on(DEFINE_STRING.SHOW_NEW_WINDOW, async (event, value) => {
let newW = createWindow(value[0], value[1]);
})
// 监听程序关闭
ipcMain.on(DEFINE_STRING.QUIT_APP, (event) => {
app.quit();
})
/**
* 监听图片对齐任务
*/
ipcMain.on(DEFINE_STRING.ALIGN_DRAFT_IMG, async (event, value) => {
func.alignDraftImage(mainWindow, value)
})