V 2.2.9 自动匹配,手动排序

This commit is contained in:
2024-06-13 00:37:31 +08:00
parent 3774e9fe55
commit 79a1929e79
76 changed files with 2499 additions and 1042 deletions
+32
View File
@@ -0,0 +1,32 @@
import { PromptIpc } from "./promptIpc"
import { SettingIpc } from './settingIpc.js'
import { ImageGenerateIpc } from './imageGenerateIpc.js'
import { WritingIpc } from './writingIpc.js'
import { VideoGenerateIpc } from './videoGenerateIpc'
import { TranslateIpc } from './translateIpc.js'
import { GptIpc } from './gptIpc.js'
import { MjIpc } from './mjIpc.js'
import { OriginalImageGenerateIpc } from './originalImageGenerateIpc'
import { SdIpc } from './sdIpc.js'
import { MainIpc } from './mainIpc.js'
import { GlobalIpc } from "./globalIpc.js";
import { ImageIpc } from "./imageIpc.js";
import { SystemIpc } from "./system.js";
export function RegisterIpc(createWindow) {
PromptIpc()
SettingIpc();
ImageGenerateIpc();
WritingIpc();
VideoGenerateIpc();
TranslateIpc();
GptIpc();
SdIpc();
MjIpc();
MainIpc(createWindow);
OriginalImageGenerateIpc();
GlobalIpc();
ImageIpc();
SystemIpc();
}
+3
View File
@@ -63,6 +63,9 @@ function MjIpc() {
// 获取所有的MJ生图模型
ipcMain.handle(DEFINE_STRING.MJ.GET_MJ_IMAGE_ROBOT_MODEL, async (event) => await mjSimple.GetMJImageRobotModel());
// 自动匹配用户表标签
ipcMain.handle(DEFINE_STRING.MJ.AUTO_MATCH_USER, async (event, value) => await mJOriginalImageGenerate.AutoMatchUser(value));
/**
* 监听DISCORD界面创建消息,并修改数据
*/
+18
View File
@@ -0,0 +1,18 @@
import { ipcMain } from "electron";
import { DEFINE_STRING } from '../../define/define_string'
import { Prompt } from "../Public/Prompt";
let prompt = new Prompt();
function PromptIpc() {
// 获取所有的排序选项
ipcMain.handle(DEFINE_STRING.PROMPT.GET_SORT_OPTIONS, (event) => prompt.GetPromptSortOptions());
// 保存提示词排序数据
ipcMain.handle(DEFINE_STRING.PROMPT.SAVE_PROMPT_SORT_DATA, (event, value) => prompt.SavePromptSort(value));
// 获取已经保存的提示词数据
ipcMain.handle(DEFINE_STRING.PROMPT.GET_PROMPT_SORT_DATA, (event) => prompt.GetPromptSort())
}
export {
PromptIpc
}
+17
View File
@@ -2,11 +2,13 @@ const {
ipcMain, app
} = require("electron")
import { DEFINE_STRING } from '../../define/define_string'
import { GetDataByTypeAndProperty, SaveDataByTypeAndProperty, DeleteDataByTypeAndProperty } from '../../define/setting/dynamicSetting';
import {
Setting
} from '../setting/setting'
let setting = new Setting(global);
async function SettingIpc() {
// 获取背景音乐配置列表
@@ -65,6 +67,21 @@ async function SettingIpc() {
// // 保存指定的配置文件里面指定的属性的数据
ipcMain.handle(DEFINE_STRING.SAVE_DEFINE_CONFIG_JSON_BY_PROPERTY, async (event, value) => await setting.SaveDefineConfigJsonByProperty(value))
//#region 动态设置(只是动态设置)
// 获取动态配置的的指定主分类,指定的属性的数据(只是获取动态的,type定死了dynamic
ipcMain.handle(DEFINE_STRING.SETTING.GET_DATA_BY_TYPE_AND_PROPERTY, async (event, value) => await GetDataByTypeAndProperty(value));
// 保存动态配置的的指定主分类,指定的属性的数据
ipcMain.handle(DEFINE_STRING.SETTING.SAVE_DATA_BY_TYPE_AND_PROPERTY, async (event, value) => await SaveDataByTypeAndProperty(value));
// 删除动态配置的的指定主分类,指定的属性的数据
ipcMain.handle(DEFINE_STRING.SETTING.DELETE_DATA_BY_TYPE_AND_PROPERTY, async (event, value) => await DeleteDataByTypeAndProperty(value));
//#endregion
}
export {
+128 -5
View File
@@ -8,11 +8,14 @@ import { Tools } from "../tools";
import path from 'path'
import sharp from 'sharp'
import { define } from "../../define/define";
import { AwesomeRegx } from "awesome-js";
import { AwesomeHelp } from "awesome-js";
import { checkStringValueAddSuffix, errorMessage, successMessage } from "../generalTools";
import { ImageSetting } from "../../define/setting/imageSetting";
import { DiscordAPI } from "../../api/discordApi";
import { GPT } from "../Public/GPT";
import { TagDefine } from "../../define/tagDefine";
import { cloneDeep } from "lodash";
import { LOGGER_DEFINE } from "../../define/logger_define";
const { v4: uuidv4 } = require('uuid');
/**
@@ -26,15 +29,122 @@ export class MJOriginalImageGenerate {
this.tools = new Tools();
this.discordAPI = new DiscordAPI();
this.gpt = new GPT(global);
this.tagDefine = new TagDefine(global);
}
/**
* 返回指定的人物到前端
* @param {*} data
*/
sendChangeMessage(data) {
this.global.newWindow[0].win.webContents.send(DEFINE_STRING.DISCORD.MAIN_DISCORD_MESSAGE_CHANGE, data);
sendChangeMessage(data, message_name = DEFINE_STRING.DISCORD.MAIN_DISCORD_MESSAGE_CHANGE) {
this.global.newWindow[0].win.webContents.send(message_name, data);
}
/**
* 通过文本自动匹配数据
* @param {*} value
*/
async AutoMatchUser(value) {
try {
value = JSON.parse(value);
// 获取所有的角色数据,包括别名
// 获取所有的角色数据
let character_tags = await this.tagDefine.getTagDataByTypeAndProperty("dynamic", "character_tags");
if (character_tags.code == 0) {
return errorMessage("获取角色数据错误,错误信息如下:" + character_tags.message, LOGGER_DEFINE.ORIGINAL_AUTO_MATCH_USER)
}
character_tags = character_tags.data;
if (character_tags.length == 0) {
return errorMessage("请先添加角色数据", LOGGER_DEFINE.ORIGINAL_AUTO_MATCH_USER)
}
let character_tags_data = [];
for (let i = 0; i < character_tags.length; i++) {
let item = character_tags[i];
// 这边还要判断是不是显示(只有显示的才hi自动匹配)
if (!item.hasOwnProperty("isShow") || !item.isShow) {
continue;
}
let temp_name = [item.label];
// 判断当前的数是不是存在别名
if (item.children && item.children.length > 0) {
for (let j = 0; j < item.children.length; j++) {
const element = item.children[j];
temp_name.push(element.label);
}
}
character_tags_data.push({
key: item.key,
value: item.value,
names: temp_name
})
}
if (character_tags_data.length == 0) {
return errorMessage("当前没有显示的角色数据,请先选择哪些是要显示的角色数据", LOGGER_DEFINE.ORIGINAL_AUTO_MATCH_USER)
}
for (let i = 0; i < value.length; i++) {
const element = value[i];
let res_data = {
code: 1,
id: element.id, // 当前 data 的ID
match_character: [],
}
// 获取当前的字幕数据
let temp_sub = [];
for (let j = 0; element.suValue && j < element.suValue.length; j++) {
const element = array[j];
temp_sub.push(element.srt_value);
}
let word = "";
if (temp_sub.length == 0) {
word = element.after_gpt;
} else {
word = temp_sub.join(",");
}
let match_keys = [];
// 开始循环判断,只要又一个满足就跳出新婚换
for (let j = 0; j < character_tags_data.length; j++) {
const item = character_tags_data[j];
let names = AwesomeHelp.makeSensitiveMap(item.names);
// 开始判断
let name_res = AwesomeHelp.checkSensitiveWord(word, false, names);
if (name_res.size > 0) {
match_keys.push(item.key);
}
}
// 判断是不是又匹配到的数据
if (match_keys.length > 0) {
// 进行数据的处理,通过对应的key,获取对应的数据,将所有的数进行返回
for (let i = 0; i < match_keys.length; i++) {
const item = match_keys[i];
let index = character_tags.findIndex(x => x.key == item);
if (index == -1) {
continue;
}
let temp_item_data = cloneDeep(character_tags[index]);
if (temp_item_data.children) {
delete temp_item_data.children
}
res_data.match_character.push(temp_item_data)
}
}
// 开始往前端传递数据
this.sendChangeMessage(res_data, DEFINE_STRING.MJ.MACTH_USER_RETURN);
}
return successMessage(null, "人物标签自动匹配完成", LOGGER_DEFINE.ORIGINAL_AUTO_MATCH_USER)
} catch (error) {
return errorMessage("通过文本自动匹配数据错误,错误信息如下:" + error.message, LOGGER_DEFINE.ORIGINAL_AUTO_MATCH_USER)
}
}
/**
* 初始化MJ设置
*/
@@ -290,6 +400,11 @@ export class MJOriginalImageGenerate {
"Authorization": mjSetting.api_key
}
res = await this.discordAPI.mjApiImagine(imagine_url, data, headers);
if (res.code == 24) {
throw new Error("提示词包含敏感词,请修改后重试");
}
} else if (imagine_url.includes("api.ephone.ai")) {
// ePhoneAPI
let headers = {
@@ -306,6 +421,15 @@ export class MJOriginalImageGenerate {
}
res = await this.discordAPI.mjApiImagine(imagine_url, data, headers);
}
// 错误检查
if (res.code == 23) {
throw new Error("生图队列已满,请稍后尝试");
}
if (res.code != 1 && res.code != 22) {
throw new Error("未知错误,可联系管理员排查" + res.description);
}
// 创建成功,开始下一个
this.sendChangeMessage({
code: 1,
@@ -406,7 +530,6 @@ export class MJOriginalImageGenerate {
}
let style_ids = await this.pm.GetConfigJson(JSON.stringify(["image_style", []]), false);
let image_styles = await ImageStyleDefine.getImageStyleStringByIds(style_ids.data);
// 替换风格的逻辑
let current_task = null;
@@ -419,7 +542,7 @@ export class MJOriginalImageGenerate {
// 拼接提示词
// 图生图的链接
// 获取风格词 + 命令后缀
let prompt = " " + image_styles + old_prompt + (mjSetting.image_suffix ? mjSetting.image_suffix : "");
let prompt = old_prompt + (mjSetting.image_suffix ? mjSetting.image_suffix : "");
// 判断当前生图模式
let request_model = mjSetting.request_model
+1 -2
View File
@@ -62,13 +62,12 @@ export class OriginalImageGenerate {
let seed = sd_setting.setting.seed;
let style_ids = await this.pm.GetConfigJson(JSON.stringify(["image_style", []]), false);
let image_styles = await ImageStyleDefine.getImageStyleStringByIds(style_ids.data);
for (let i = 0; i < data.length; i++) {
const element = data[i];
let adetailer = element.adetailer;
let imageJson = JSON.parse(await fspromises.readFile(path.normalize(element.prompt_json), 'utf-8'));
let prompt = sd_setting.webui.prompt + image_styles + ',' + element.prompt;
let prompt = sd_setting.webui.prompt + ',' + element.prompt;
// 添加前缀
if (prefix_prompt) {
prompt = prefix_prompt + ',' + prompt;
+1 -1
View File
@@ -3,7 +3,7 @@ import path, { resolve } from "path";
import { Tools } from "../tools";
import fs from "fs";
import { ImageSetting } from "../../define/setting/imageSetting";
import { isEmpty, reject } from "lodash";
import { isEmpty } from "lodash";
import { basicApi } from "../../api/apiBasic";
import sharp from 'sharp';
import { file, image } from "../../define/Tools";
+82
View File
@@ -0,0 +1,82 @@
import { errorMessage, successMessage } from "../generalTools";
import { LOGGER_DEFINE } from '../../define/logger_define'
import { Setting } from "../setting/setting";
export class Prompt {
constructor() {
this.setting = new Setting(global);
}
/**
* 获取所有的排序选项
*/
GetPromptSortOptions() {
return successMessage([
{
label: '人物',
value: 'character'
}, {
label: '场景',
value: 'scene'
}, {
label: '提示词',
value: 'prompt'
}, {
label: '风格',
value: 'style'
}
], null, LOGGER_DEFINE.PROMPT.GET_PROMPT_SORT_OPTIONS);
}
/**
* 保存SD排序的选项
* @param {*} value
*/
async SavePromptSort(value) {
try {
// 将当前数据保存
await this.setting.SaveDefineConfigJsonByProperty(JSON.stringify(['img_base', 'prompt_sort', value]));
return successMessage(null, "保存提示词排序顺序成功", LOGGER_DEFINE.PROMPT.SAVE_PROMPT_SORT_DATA);
} catch (error) {
return errorMessage(error.toString(), LOGGER_DEFINE.PROMPT.SAVE_PROMPT_SORT_DATA);
}
}
/**
* 获取当前的
*/
async GetPromptSort() {
try {
let res = await this.setting.GetDefineConfigJsonByProperty(JSON.stringify(['img_base', 'prompt_sort', false, []]))
if (res.code == 0) {
throw new Error(res.message);
}
res = res.data;
if (res && res.length == 0) {
res = [
{
label: '风格',
value: 'style'
},
{
label: '人物',
value: 'character'
},
{
label: '场景',
value: 'scene'
},
{
label: '提示词',
value: 'prompt'
}
]
}
return successMessage(res, "获取数据成功", LOGGER_DEFINE.PROMPT.GET_PROMPT_SORT_DATA)
} catch (error) {
return errorMessage(error.toString(), LOGGER_DEFINE.PROMPT.GET_PROMPT_SORT_DATA)
}
}
}
+1 -1
View File
@@ -110,7 +110,7 @@ export class SD {
return successMessage(data);
} catch (error) {
return errorMessage("加载数据失败,错误信息如下:" +error.toString());
return errorMessage("加载数据失败,错误信息如下:" + error.toString());
}
}
+5 -9
View File
@@ -13,6 +13,8 @@ const execAsync = util.promisify(exec);
const { v4: uuidv4 } = require('uuid'); // 引入UUID库来生成唯一标识符
let fspromises = require("fs").promises;
import { ImageSetting } from "../../define/setting/imageSetting";
import { errorMessage } from "../generalTools";
import { LOGGER_DEFINE } from "../../define/logger_define";
export class ImageGenerate {
@@ -339,7 +341,7 @@ export class ImageGenerate {
// 监听总批次完成
this.global.requestQuene.setBatchCompletionCallback(batch, (failedTasks) => {
debugger
if (failedTasks.length > 0) {
let message = `
批次生成任务都已完成。
@@ -489,16 +491,10 @@ export class ImageGenerate {
}
else {
return {
code: 0,
message: "参数错误"
}
return errorMessage("参数错误", LOGGER_DEFINE.GLOBAL.PARAM_ERROR)
}
} catch (error) {
return {
code: 0,
message: error.toString()
}
return errorMessage(error.toString(), "imageGenerate_DownloadImageFile");
}
}
}
+5 -1
View File
@@ -364,8 +364,12 @@ export class VideoGenerate {
await fspromises.writeFile(project_config_path, JSON.stringify(obj));
// let task_list = JSON.parse(await fspromises.readFile(path.join(this.global.config.project_path,'scripts/task_')));
let scriptPath = path.join(define.scripts_path, 'Lai.exe');
let gpu = this.global.gpu.type;
if (video_config.libx264) {
gpu = "OTHER"
}
// 执行生成图片的脚本
let script = `cd "${define.scripts_path}" && "${scriptPath}" -c "${project_config_path.replaceAll('\\', '/')}" "${this.global.gpu.type}"`;
let script = `cd "${define.scripts_path}" && "${scriptPath}" -c "${project_config_path.replaceAll('\\', '/')}" "${gpu}"`;
const output = await execAsync(script, { maxBuffer: 1024 * 1024 * 10, encoding: 'utf-8' });
if (output.stderr != '') {
obj.status = "video_error";
+1 -1
View File
@@ -382,7 +382,7 @@ function startObserving() {
if (window.observer) {
return;
}
debugger
// 没有开始监听
MutationObserverElement();
console.log("开始监听")
+1 -1
View File
@@ -507,7 +507,7 @@ export class DiscordSimple {
if (window.observer) {
return;
}
debugger
// 没有开始监听
MutationObserverElement();
console.log("开始监听")
+7 -1
View File
@@ -1052,7 +1052,13 @@ async function StartStoryboarding(value) {
global.newWindow[0].win.webContents.send(DEFINE_STRING.GET_FRAME_RETUN, { code: 1, data: "正在调用进程。请勿关闭程序" })
let cc = `${path.join(define.scripts_path, 'Lai.exe')}`;
let child = spawn(cc, ["-a", value.video_path, frame_path, input_path, value.sensitivity, global.gpu.type], { encoding: 'utf-8' });
// 获取生成视频设置
let video_config = JSON.parse(await fspromises.readFile(define.video_config, 'utf-8'));
let gpu = global.gpu.type;
if (video_config.libx264) {
gpu = "OTHER";
}
let child = spawn(cc, ["-a", value.video_path, frame_path, input_path, value.sensitivity, gpu], { encoding: 'utf-8' });
child.on('error', console.error)
child.stdout.on('data', (data) => {
console.log(data.toString());
+4 -4
View File
@@ -72,8 +72,8 @@ function checkStringValueDeletePrefix(value, prefix) {
* @returns
*/
function successMessage(data, message = null, service = null) {
if (service && message) {
global.logger.info(service, `成功返回数据`);
if (service) {
global.logger.info(service, message ? message : '成功返回数据');
}
return {
code: 1,
@@ -89,8 +89,8 @@ function successMessage(data, message = null, service = null) {
* @returns
*/
function errorMessage(message, service = null) {
if (service && message) {
global.logger.error(service, message);
if (service) {
global.logger.error(service, message ? message : '未知报错,没有捕获的错误');
}
return {
code: 0,
+2 -28
View File
@@ -18,22 +18,9 @@ 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 { SystemIpc } from "./IPCEvent/system.js";
import { system } from "systeminformation";
import { Logger } from "./logger.js";
import { RegisterIpc } from "./IPCEvent/index.js";
let tools = new Tools();
let imageGenerate = new ImageGenerate(global);
@@ -226,20 +213,7 @@ app.on('window-all-closed', () => {
}
})
SettingIpc();
ImageGenerateIpc();
WritingIpc();
VideoGenerateIpc();
TranslateIpc();
GptIpc();
SdIpc();
MjIpc();
MainIpc(createWindow);
OriginalImageGenerateIpc();
GlobalIpc();
ImageIpc();
SystemIpc();
RegisterIpc(createWindow);
ipcMain.handle('dark-mode:toggle', (event, value) => {
+10 -1
View File
@@ -317,7 +317,11 @@ export class Setting {
/**
* 获取指定的配置文件里面指定的属性的数据
* @param {*} value
* @param {*} value 执行方法必要的信息
* 0 define中的指定属性(指定的配置文件)
* 1 要获取的什么属性信息 propertyproperty 为null,赶回当前配置文件的所有数据
* 2 是不是要校验属性不存在
* 3 属性没有找到的默认值
*/
async GetDefineConfigJsonByProperty(value) {
return ImageSetting.GetDefineConfigJsonByProperty(value);
@@ -326,6 +330,11 @@ export class Setting {
/**
* 保存指定的配置文件里面指定的属性的数据
* @param {*} value
* 0 define中的指定属性(指定的配置文件)
* 1 要获取的什么属性信息 propertyproperty 为null,赶回当前配置文件的所有数据
* 2 要写入的值
* 3 是不是要校验属性不存在
*/
async SaveDefineConfigJsonByProperty(value) {
return ImageSetting.SaveDefineConfigJsonByProperty(value);