V 2.2.10 新增MJ的代理模式

This commit is contained in:
2024-06-24 13:11:19 +08:00
parent 79a1929e79
commit bac97bc41c
102 changed files with 6374 additions and 1172 deletions
+27
View File
@@ -0,0 +1,27 @@
import { ipcMain } from "electron";
import { DEFINE_STRING } from '../../define/define_string'
import { ReverseBook } from "../ReverseManage/Book/ReverseBook";
import { BasicReverse } from "../Task/BasicReverse";
let reverseBook = new ReverseBook();
let basicReverse = new BasicReverse();
export function BookIpc() {
// 获取样式图片的子列表
ipcMain.handle(DEFINE_STRING.BOOK.GET_BOOK_TYPE, async (event) => reverseBook.GetBookType());
// 新增或者是修改小说数据
ipcMain.handle(DEFINE_STRING.BOOK.ADD_OR_MODIFY_BOOK, async (event, book) => reverseBook.AddOrModifyBook(book));
// 获取小说数据(通过传递的参数进行筛选)
ipcMain.handle(DEFINE_STRING.BOOK.GET_BOOK_DATA, async (event, bookQuery) => reverseBook.GetBookData(bookQuery));
//#region 一键反推
ipcMain.handle(DEFINE_STRING.BOOK.GET_BOOK_TASK_DATA, async (event, bookTaskCondition) => reverseBook.GetBookTaskData(bookTaskCondition));
// 获取抽帧数据
ipcMain.handle(DEFINE_STRING.BOOK.GET_FRAME_DATA, async (event, bookId) => basicReverse.GetFrameData(bookId));
//#endregion
}
+1 -1
View File
@@ -4,7 +4,7 @@ import {
import { DEFINE_STRING } from '../../define/define_string'
import {
ImageGenerate
} from '../backPrompt/imageGenerate'
} from '../ReverseManage/imageGenerate'
let imageGenerate = new ImageGenerate(global);
function ImageGenerateIpc() {
+3 -1
View File
@@ -11,7 +11,8 @@ 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";
import { SystemIpc } from "./systemIpc.js";
import { BookIpc } from "./bookIpc.js"
export function RegisterIpc(createWindow) {
PromptIpc()
@@ -28,5 +29,6 @@ export function RegisterIpc(createWindow) {
GlobalIpc();
ImageIpc();
SystemIpc();
BookIpc();
}
+3
View File
@@ -12,6 +12,9 @@ function PromptIpc() {
// 获取已经保存的提示词数据
ipcMain.handle(DEFINE_STRING.PROMPT.GET_PROMPT_SORT_DATA, (event) => prompt.GetPromptSort())
// 获取提示词文件数据(txt,指定路径)
ipcMain.handle(DEFINE_STRING.PROMPT.OPEN_PROMPT_FILE_TXT, (event, value) => prompt.OpenPromptFileTxt(value))
}
export {
PromptIpc
+34
View File
@@ -7,6 +7,10 @@ import {
Setting
} from '../setting/setting'
let setting = new Setting(global);
import { BasicSetting } from '../setting/basicSetting';
let basicSetting = new BasicSetting();
import { MJSetting } from '../setting/mjSetting';
let mjSetting = new MJSetting();
async function SettingIpc() {
@@ -82,6 +86,36 @@ async function SettingIpc() {
//#endregion
//#region 基础设置
// 获取软件的基础设置(初始的时候执行一次)
ipcMain.handle(DEFINE_STRING.SETTING.GET_SOFTWARE_SETTING, async (event) => await basicSetting.GetSoftwareSetting());
// 保存软件的基础设置
ipcMain.handle(DEFINE_STRING.SETTING.SAVE_SOFT_WARE_SETTING, async (event, value) => await basicSetting.SaveSoftWareSetting(value));
// 返回组件尺寸的大小的数据(通用)
ipcMain.handle(DEFINE_STRING.SETTING.GET_COMPONENT_SIZE, async (event) => basicSetting.GetComponentSize());
//#endregion
//#region MJ 设置
// 获取MJ基础设置信息
ipcMain.handle(DEFINE_STRING.SETTING.GET_MJ_SETTING, async (event, value) => mjSetting.GetMJSetting(value));
// 保存MJ的基础设置信息
ipcMain.handle(DEFINE_STRING.SETTING.UPDATE_MJ_SETTING, async (event, value) => mjSetting.UpdateMJSetting(value));
// 获取MJ的所有设置
ipcMain.handle(DEFINE_STRING.SETTING.GET_MJ_SETTING_TREE_DATA, async (event) => mjSetting.GetMJSettingTreeData());
// 保存MJ的所有设置
ipcMain.handle(DEFINE_STRING.SETTING.SAVE_MJ_SETTING_TREE_DATA, async (event, value) => mjSetting.SaveMJSettingTreeData(value));
// MJ代理模式账号同步
ipcMain.handle(DEFINE_STRING.SETTING.MJ_REMOTE_ACCOUNT_SYNC, async (event) => mjSetting.MjRemoteAccountSync());
//#endregion
}
export {
-17
View File
@@ -1,17 +0,0 @@
import { ipcMain } from "electron";
import { DEFINE_STRING } from '../../define/define_string'
const { shell } = require('electron')
function SystemIpc() {
// 打开指定的文件
ipcMain.on(DEFINE_STRING.SYSTEM.OPEN_FILE, async (event, value) => {
await shell.openPath(value);
});
}
export {
SystemIpc
}
+40
View File
@@ -0,0 +1,40 @@
import { ipcMain } from "electron";
import { DEFINE_STRING } from '../../define/define_string'
import { CheckFileOrDirExist } from "../../define/Tools/file";
import { errorMessage, successMessage } from "../generalTools";
import path from 'path'
const { shell } = require('electron')
function SystemIpc() {
// 打开指定的文件
ipcMain.on(DEFINE_STRING.SYSTEM.OPEN_FILE, async (event, value) => {
await shell.openPath(value);
});
// 试用文件资源打开指定的文件夹
ipcMain.handle(DEFINE_STRING.OPEN_FOLDER, async (event, value) => {
try {
let openFolder = null
if (value.baseProject) {
openFolder = path.join(global.config.project_path, value.folderPath)
}
else {
openFolder = value.folderPath
}
// 判断文件夹是不是存在
let isExist = await CheckFileOrDirExist(openFolder)
if (!isExist) {
throw new Error("文件夹不存在,请检查")
}
shell.openPath(openFolder)
return successMessage(null, '打开成功');
} catch (error) {
return errorMessage("打开文件夹错误,错误信息如下:" + error.message, "SystemIpc_OPEN_FOLDER")
}
});
}
export {
SystemIpc
}
+1 -1
View File
@@ -1,6 +1,6 @@
import { ipcMain } from "electron";
import { DEFINE_STRING } from '../../define/define_string'
import { VideoGenerate } from "../backPrompt/videoGenerate";
import { VideoGenerate } from "../ReverseManage/videoGenerate";
let videoGenerate = new VideoGenerate(global);
function VideoGenerateIpc() {
+1 -1
View File
@@ -4,7 +4,7 @@ import {
import { DEFINE_STRING } from '../../define/define_string'
import {
Writing
} from '../backPrompt/writing'
} from '../ReverseManage/writing'
let writing = new Writing(global);
function WritingIpc() {
+110 -25
View File
@@ -16,6 +16,8 @@ import { GPT } from "../Public/GPT";
import { TagDefine } from "../../define/tagDefine";
import { cloneDeep } from "lodash";
import { LOGGER_DEFINE } from "../../define/logger_define";
import { MJImageType } from "../../define/enum/mjEnum";
import { MJSettingService } from "../../define/db/service/SoftWare/mjSettingService";
const { v4: uuidv4 } = require('uuid');
/**
@@ -226,7 +228,7 @@ export class MJOriginalImageGenerate {
try {
value = JSON.parse(value);
let mjSetting = await this.InitMjSetting();
let request_model = mjSetting.request_model;
let request_model = mjSetting.requestModel;
let result = [];
// 浏览器生图模式
if (request_model == "browser_mj") {
@@ -260,7 +262,7 @@ export class MJOriginalImageGenerate {
result = await discordSimple.ExecuteScript(define.discordScript, `GetGeneratedMJImageAndSplit(${JSON.stringify(param)})`);
} else if (request_model == "api_mj") {
let mj_api = await this.InitMJAPIUrl(mjSetting.mj_api_url);
let mj_api = await this.InitMJAPIUrl(mjSetting.apiSetting.mjApiUrl);
let once_get_task = mj_api.mj_url.once_get_task;
// 请求
@@ -273,10 +275,10 @@ export class MJOriginalImageGenerate {
continue
}
let task_res = await this.discordAPI.GetMJAPITaskByID(element.mj_message.message_id, once_get_task, mjSetting.api_key);
let task_res = await this.discordAPI.GetMJAPITaskByID(element.mj_message.message_id, once_get_task, mjSetting.apiSetting.apiKey);
if (task_res.code == 0) {
task_res["id"] = element.id;
task_res["mj_api_url"] = mjSetting.mj_api_url;
task_res["mj_api_url"] = mjSetting.apiSetting.mjApiUrl;
this.sendChangeMessage()
}
// 判断进度是不是百分百
@@ -380,14 +382,31 @@ export class MJOriginalImageGenerate {
* @param {*} element
* @param {*} mjSetting
*/
async MJImagineRequest(element, mjSetting, prompt) {
async MJImagineRequest(element, mjSetting, prompt, tasK_id = null, batch = null) {
try {
// 获取当前的API url
let apiUrl = await this.InitMJAPIUrl(mjSetting.mj_api_url);
if (mjSetting.apiSetting == null) {
throw new Error("没有API设置,请先设置API设置");
}
let apiUrl;
if (mjSetting.requestModel == MJImageType.API_MJ) {
// 获取当前的API url
apiUrl = await this.InitMJAPIUrl(mjSetting.apiSetting.mjApiUrl);
} else if (mjSetting.requestModel == MJImageType.REMOTE_MJ) {
apiUrl = {
mj_url: {
imagine: define.remotemj_api + 'mj/submit/imagine',
once_get_task: define.remotemj_api + "mj/task/${id}/fetch"
}
}
} else {
throw new Error("未知的生图模式,请检查配置")
}
let imagine_url = apiUrl.mj_url.imagine;
let once_get_task = apiUrl.mj_url.once_get_task;
let task_count = mjSetting.task_count ? mjSetting.task_count : 3;
let mj_speed = mjSetting.mj_speed ? mjSetting.mj_speed : "relaxed";
let task_count = mjSetting.taskCount ? mjSetting.taskCount : 3;
let mj_speed = mjSetting.apiSetting.mjSpeed ? mjSetting.apiSetting.mjSpeed : "relaxed";
let res;
// 判断当前的API是哪个
if (imagine_url.includes("mjapi.deepwl.net")) {
@@ -397,7 +416,7 @@ export class MJOriginalImageGenerate {
mode: mj_speed == "fast" ? "FAST" : "RELAX",
}
let headers = {
"Authorization": mjSetting.api_key
"Authorization": mjSetting.apiSetting.apiKey
}
res = await this.discordAPI.mjApiImagine(imagine_url, data, headers);
@@ -408,7 +427,7 @@ export class MJOriginalImageGenerate {
} else if (imagine_url.includes("api.ephone.ai")) {
// ePhoneAPI
let headers = {
"Authorization": mjSetting.api_key
"Authorization": mjSetting.apiSetting.apiKey
}
let data = {
prompt: prompt,
@@ -420,15 +439,71 @@ export class MJOriginalImageGenerate {
}
}
res = await this.discordAPI.mjApiImagine(imagine_url, data, headers);
} else if (imagine_url.includes(define.remotemj_api)) {
// 代理模式
let headers = {
"mj-api-secret": define.API
}
// 判断数据是不是存在
if (!mjSetting.remoteSetting.channelId) {
throw new Error("请先设置channelId")
}
if (!mjSetting.remoteSetting.accountId) {
throw new Error("请先同步账号")
}
let data = {
prompt: prompt,
botType: "MID_JOURNEY",
accountFilter: {
channelId: mjSetting.remoteSetting.channelId,
instanceId: mjSetting.remoteSetting.accountId,
remark: this.global.machineId,
modes: [
mj_speed == "fast" ? "FAST" : "RELAX"
]
}
}
res = await this.discordAPI.mjApiImagine(imagine_url, data, headers);
}
this.global.mjGenerateQuene.setCurrentCreateItem(null);
// 错误检查
if (res.code == 23) {
throw new Error("生图队列已满,请稍后尝试");
// 任务队列已满,及结束该任务,然后开始下一个任务,并将该任务重新排序
this.global.mjGenerateQuene.removeTaskProgress((taskProgress) => {
return taskProgress.filter(item => item?.id != element.id)
});
this.sendChangeMessage({
code: 0,
status: "error",
message: "任务队列已满,任务结束会重新排序,并等待3分钟,开始后面的任务",
id: element.id
})
await this.tools.delay(40000);
// 重新将当前任务加入队列
this.global.mjGenerateQuene.enqueue(async () => {
this.global.mjGenerateQuene.setCurrentCreateItem(element)
await this.MJImagineRequest(element, mjSetting, prompt)
}, tasK_id, batch)
this.global.mjGenerateQuene.startNextTask(task_count);
return;
}
if (res.code != 1 && res.code != 22) {
throw new Error("未知错误,可联系管理员排查" + res.description);
// 未知错误,将当前任务删除,开始下一个任务
this.global.mjGenerateQuene.removeTaskProgress((taskProgress) => {
return taskProgress.filter(item => item?.id != element.id)
});
this.global.mjGenerateQuene.startNextTask(task_count);
this.sendChangeMessage({
code: 0,
status: "error",
message: "未知错误,可联系管理员排查," + res.description,
id: element.id
})
return;
}
// 创建成功,开始下一个
this.sendChangeMessage({
@@ -440,16 +515,15 @@ export class MJOriginalImageGenerate {
image_show: null,
id: element.id,
progress: 0,
mj_api_url: mjSetting.mj_api_url
mj_api_url: mjSetting.apiSetting.mjApiUrl
});
this.global.mjGenerateQuene.setCurrentCreateItem(null);
// 开始监听当前ID是不是的生图任务完成
// 这边设置一个循环监听,每隔一段时间去请求一次
let timeoutId;
let startInterval = () => {
timeoutId = setTimeout(async () => {
// 执行你的操作
let task_res = await this.discordAPI.GetMJAPITaskByID(res.result, once_get_task, mjSetting.api_key)
let task_res = await this.discordAPI.GetMJAPITaskByID(res.result, once_get_task, mjSetting.apiSetting.apiKey)
console.log(task_res)
// 判断他的状态是不是成功
if (task_res.code == 0) {
@@ -479,7 +553,7 @@ export class MJOriginalImageGenerate {
}
}
task_res['id'] = element.id;
task_res["mj_api_url"] = mjSetting.mj_api_url;
task_res["mj_api_url"] = mjSetting.apiSetting.mjApiUrl;
this.sendChangeMessage(task_res);
}, 5000);
}
@@ -521,16 +595,19 @@ export class MJOriginalImageGenerate {
let output_crop_00001 = path.join(this.global.config.project_path, `tmp\\output_crop_00001`);
await this.tools.checkFolderExistsOrCreate(output_crop_00001);
// 获取MJ配置
let mjSetting = await this.InitMjSetting();
// 获取MJ配置,从数据库中
let _mjSettingService = await MJSettingService.getInstance()
let mjSettings = _mjSettingService.GetMJSettingTreeData();
if (mjSettings.code == 0) {
throw new Error(mjSettings.message)
}
let mjSetting = mjSettings.data;
// 检查this.global中是不是又mj队列,没有的话创建一个
if (!this.global.mjGenerateQuene) {
this.global.mjGenerateQuene = new AsyncQueue(this.global, 1, true);
}
let style_ids = await this.pm.GetConfigJson(JSON.stringify(["image_style", []]), false);
// 替换风格的逻辑
let current_task = null;
@@ -542,17 +619,25 @@ export class MJOriginalImageGenerate {
// 拼接提示词
// 图生图的链接
// 获取风格词 + 命令后缀
let prompt = old_prompt + (mjSetting.image_suffix ? mjSetting.image_suffix : "");
let prompt = old_prompt + (mjSetting.imageSuffix ? mjSetting.imageSuffix : "");
// 判断当前生图模式
let request_model = mjSetting.request_model
let request_model = mjSetting.requestModel
switch (request_model) {
case "api_mj":
this.global.mjGenerateQuene.enqueue(async () => {
this.global.mjGenerateQuene.setCurrentCreateItem(element)
await this.MJImagineRequest(element, mjSetting, prompt)
await this.MJImagineRequest(element, mjSetting, prompt, tasK_id, batch)
}, tasK_id, batch)
break;
case MJImageType.REMOTE_MJ:
this.global.mjGenerateQuene.enqueue(async () => {
this.global.mjGenerateQuene.setCurrentCreateItem(element)
await this.MJImagineRequest(element, mjSetting, prompt, tasK_id, batch)
}, tasK_id, batch)
break;
case "browser_mj":
this.global.mjGenerateQuene.enqueue(async () => {
try {
@@ -575,7 +660,7 @@ export class MJOriginalImageGenerate {
}
// 判断该当前正在执行的人物队列数(小于设置的数量,开始一个任务)
this.global.mjGenerateQuene.startNextTask(mjSetting.task_count ? mjSetting.task_count : 3);
this.global.mjGenerateQuene.startNextTask(mjSetting.taskCount ? mjSetting.taskCount : 3);
this.global.requestQuene.setBatchCompletionCallback(batch, (failedTasks) => {
if (failedTasks.length > 0) {
+44
View File
@@ -1,6 +1,12 @@
import { errorMessage, successMessage } from "../generalTools";
import { LOGGER_DEFINE } from '../../define/logger_define'
import { Setting } from "../setting/setting";
import { isEmpty } from "lodash";
import fs from 'fs';
import readline from 'readline';
import { file } from '../../define/Tools/index'
import path from "path";
let fspromises = fs.promises;
export class Prompt {
constructor() {
@@ -79,4 +85,42 @@ export class Prompt {
return errorMessage(error.toString(), LOGGER_DEFINE.PROMPT.GET_PROMPT_SORT_DATA)
}
}
/**
* 获取txt文件的数据,将每行导出导致一个数组,返回一个数组
* @param {string} value txt文件的地址
*/
async OpenPromptFileTxt(value) {
try {
if (isEmpty(value)) {
throw new Error("传入的文件地址不能为空")
}
// 检查文件是不是存在
if (!file.CheckFileOrDirExist(value)) {
throw new Error("传入的文件地址对应的文件不存在");
}
async function processLineByLine() {
const fileStream = fs.createReadStream(path.normalize(value));
const rl = readline.createInterface({
input: fileStream,
crlfDelay: Infinity
});
const lines = [];
for await (const line of rl) {
lines.push(line);
}
rl.close(); // 确保关闭 readline 流
return lines;
}
let res = await processLineByLine()
// return successMessage(res, "获取数据成功", LOGGER_DEFINE.PROMPT.OPEN_PROMPT_FILE_TXT);
console.log(res);
return successMessage(res, "获取成功", LOGGER_DEFINE.PROMPT.OPEN_PROMPT_FILE_TXT)
} catch (error) {
return errorMessage(error.toString(), LOGGER_DEFINE.PROMPT.OPEN_PROMPT_FILE_TXT);
}
}
}
+63
View File
@@ -0,0 +1,63 @@
import { BookType } from "../../../define/enum/bookEnum";
import { errorMessage, successMessage } from "../../generalTools";
import BooKService from "../../../define/db/service/Book/bookService";
import { BookTaskService } from "../../../define/db/service/Book/bookTaskService";
const { v4: uuidv4 } = require('uuid');
import { define } from '../../../define/define'
import path from 'path'
import { CheckFolderExistsOrCreate } from "../../../define/Tools/file";
export class BookBasic {
constructor() {
}
/**
* 获取路径中的最后一层或两层目录
* @param {string} path 文件或目录的完整路径
* @param {number} level 需要获取的层级数(1表示最后一层,2表示最后两层)
* @returns {string} 最后的一层或两层目录
*/
getLastPathLevels(path, level = 1) {
// 根据操作系统的不同,路径分隔符可能不同
const separator = path.includes('/') ? '/' : '\\';
const parts = path.split(separator);
// 获取最后的一层或两层目录
const lastLevels = parts.slice(-level);
// 重新组合成路径字符串
return lastLevels.join(separator);
}
/**
* 新增或者是修小说数据
* @param {*} book 小说信息
* @returns
*/
async AddOrModifyBook(book) {
try {
if (book == null) {
return errorMessage('小说数据为空,无法修改');
}
// 处理一下数据,处理文件地址(删除前缀,转换为默认地址)
// 当前的小说的名字是不是在数据库中以存在
let _bookService = await BooKService.getInstance();
let res = await _bookService.AddOrModifyBook(book);
return res;
} catch (error) {
return errorMessage('修改数据错误,错误信息如下:' + error.message, 'BookBasic_AddOrModifyBook');
}
}
// 小说类型返回
GetBookType() {
return successMessage([{
label: 'SD反推',
value: BookType.SD_REVERSE
}, {
label: 'MJ反推',
value: BookType.MJ_REVERSE
}, {
label: "原创",
value: BookType.ORIGINAL
}], '获取小说类型成功');
}
}
@@ -0,0 +1,49 @@
import { successMessage, errorMessage } from "../../generalTools.js";
import { BookBasic } from "./BooKBasic.js";
import BooKService from "../../../define/db/service/Book/bookService";
import { BookTaskService } from "../../../define/db/service/Book/bookTaskService";
import { define } from '../../../define/define.js'
import path from 'path'
export class ReverseBook extends BookBasic {
constructor() {
super()
}
/**
* 获取当前的小说数据
* @param {*} bookQuery
*/
async GetBookData(bookQuery) {
try {
let _bookService = await BooKService.getInstance();
// 添加小说
let res = await _bookService.GetBookData(bookQuery)
if (res.code == 0) {
throw new Error(res.message)
}
return res
} catch (error) {
return errorMessage(error.message, 'ReverseBook_GetBookData');
}
}
/**
* 获取小说的任务列表
* @param {*} bookTaskCondition 查询任务列表的条件
*/
async GetBookTaskData(bookTaskCondition) {
try {
let _bookTaskService = await BookTaskService.getInstance();
let res = await _bookTaskService.GetBookTaskData(bookTaskCondition)
if (res.code == 0) {
throw new Error(res.message)
}
return res;
} catch (error) {
return errorMessage("获取小说对应批次错误,错误信息入校:" + error.message, 'ReverseBook_GetBookTaskData');
}
}
}
+95
View File
@@ -0,0 +1,95 @@
import path from 'path';
import fs from 'fs';
const util = require('util');
const { exec } = require('child_process');
const execAsync = util.promisify(exec);
import { define } from '../../define/define';
import BooKService from '../../define/db/service/Book/bookService';
import { TaskScheduler } from './taskScheduler';
import { LoggerStatus, LoggerType, OtherData } from '../../define/enum/softwareEnum';
import { errorMessage } from '../generalTools';
import { CheckFileOrDirExist } from '../../define/Tools/file';
import { BookTaskDetailService } from '../../define/db/service/Book/bookTaskDetailService';
const fspromises = fs.promises;
// 基础的反推(抽帧,分镜,提取字幕等)
export class BasicReverse {
constructor() {
this.taskScheduler = new TaskScheduler()
}
/**
* 分镜(通过传入的bookId)
* @param {*} bookId 传入的bookId
* @returns
*/
async GetFrameData(bookId) {
try {
let _bookService = await BooKService.getInstance();
let _bookTaskDetailService = await BookTaskDetailService.getInstance();
// 获取对应的小说小说数据,找到对应的小说视频地址
let bookQuery = {
bookId: bookId
}
let bookData = await _bookService.GetBookData(bookQuery)
if (bookData.code == 0) {
return bookData
}
if (bookData.data.book_length <= 0 || bookData.data.res_book.length <= 0) {
throw new Error("没有找到对应的小说数据,请检查bookId是否正确")
}
// 获取小说的视频地址
let book = bookData.data.res_book[0]
let oldVideoPath = book.oldVideoPath
let frameJson = oldVideoPath + '.json'
let sensitivity = 30
// 开始之前,推送日志
let log_content = `开始进行分镜操作,视频地址:${oldVideoPath},敏感度:${sensitivity},正在调用程序进行处理`
await this.taskScheduler.AddLogToDB(bookId, book.type, log_content, OtherData.DEFAULT, LoggerStatus.DOING)
// 小说进行分镜(python进行,将结果写道一个json里面)
// 使用异步的方法调用一个python程序,然后写入到指定的json文件中k
let command = `"${path.join(define.scripts_path, "Lai.exe")}" "-ka" "${oldVideoPath}" "${frameJson}" "${sensitivity}"`
const output = await execAsync(command, { maxBuffer: 1024 * 1024 * 10, encoding: 'utf-8' });
// 有错误输出
if (output.stderr != '') {
await this.taskScheduler.AddLogToDB(bookId, book.type, `分镜失败,错误信息如下:${output.stderr}`, OtherData.DEFAULT, LoggerStatus.FAIL)
throw new Error(output.stderr);
}
// 分镜成功,处理输出
let josnIsExist = CheckFileOrDirExist(frameJson)
if (!josnIsExist) {
let error_message = `分镜失败,没有找到对应的分镜输出文件:${frameJson}`
await this.taskScheduler.AddLogToDB(bookId, book.type, error_message, OtherData.DEFAULT, LoggerStatus.FAIL)
throw new Error(error_message)
}
let frameJsonData = JSON.parse(await fspromises.readFile(frameJson, 'utf-8'))
if (frameJsonData.length <= 0) {
await this.taskScheduler.AddLogToDB(bookId, book.type, `分镜失败,没有找到对应的分镜数据`, OtherData.DEFAULT, LoggerStatus.FAIL)
throw new Error("分镜失败,没有找到对应的分镜数据")
}
// 循环写入小说人物详细数据
for (let i = 0; i < frameJsonData.length; i++) {
let frameData = frameJsonData[i]
let bookTaskDetail = {
bookId: bookId,
}
await _bookTaskDetailService.AddBookTaskDetail(frameDataQuery)
}
console.log()
console.log(output.stdout)
} catch (error) {
return errorMessage(error.message, 'BasicReverse_GetFrameData');
}
}
}
View File
View File
+41
View File
@@ -0,0 +1,41 @@
import { LoggerService } from '../../define/db/service/SoftWare/loggerService';
import { DEFINE_STRING } from '../../define/define_string';
import { LoggerStatus, OtherData } from '../../define/enum/softwareEnum';
import { successMessage } from '../generalTools';
export class TaskScheduler {
constructor() {
}
/**
* 添加日志到数据库,然后返回日志信息到前端,日志记录失败不会报错
* @param {*} bookId 小说ID,必填
* @param {*} type 日志类型,必填 LoggerType
* @param {*} content 日志记录内容,必填
* @param {*} bookTaskId 小说子任务,选填,默认 OtherData.DEFAULT
* @param {*} status 状态,选填,默认 LoggerStatus.DOING
* @returns
*/
async AddLogToDB(bookId, type, content, bookTaskId = OtherData.DEFAULT, status = LoggerStatus.DOING) {
try {
let log =
{
bookId: bookId,
bookTaskId: bookTaskId,
type: type,
status: status,
content: content
}
let _loggerService = await LoggerService.getInstance();
let res = await _loggerService.AddLogger(log)
// 添加成功之后,将消息推动到前端
global.newWindow[0].win.webContents.send(DEFINE_STRING.SYSTEM.RETURN_LOGGER, successMessage(res))
return res
} catch (error) {
return errorMessage(error.message, 'TaskScheduler_AddLogToDB');
}
}
}
+3 -3
View File
@@ -104,7 +104,7 @@ export class DiscordSimple {
async GetInputPosition() {
try {
await this.InitData();
await this.tools.delay(this.mjSetting.space_time ? this.mjSetting.space_time * 1000 : 10000)
await this.tools.delay(this.mjSetting.spaceTime ? this.mjSetting.spaceTime * 1000 : 10000)
let result = await this.ExecuteScript(this.script, 'GetMessageInputPosition()');
this.x = result.mouseX;
this.y = result.mouseY;
@@ -654,7 +654,7 @@ export class DiscordSimple {
// 在将当前任务设置为空
global.mjGenerateQuene.setCurrentCreateItem(null);
// 开始下一个任务
global.mjGenerateQuene.startNextTask(this.mjSetting.task_count ? this.mjSetting.task_count : 3);
global.mjGenerateQuene.startNextTask(this.mjSetting.taskCount ? this.mjSetting.taskCount : 3);
}
@@ -704,7 +704,7 @@ export class DiscordSimple {
global.mjGenerateQuene.setCurrentCreateItem(null);
}
global.mjGenerateQuene.startNextTask(this.mjSetting.task_count ? this.mjSetting.task_count : 3);
global.mjGenerateQuene.startNextTask(this.mjSetting.taskCount ? this.mjSetting.taskCount : 3);
} catch (error) {
this.sendChangeMessage({
+19 -16
View File
@@ -1,6 +1,7 @@
import { DiscordSimple } from "./discordSimple";
import { Tools } from "../tools";
import { define } from "../../define/define";
import { MJSettingService } from "../../define/db/service/SoftWare/mjSettingService";
/**
* discord中的一些公用的方法
@@ -15,16 +16,15 @@ export class DiscordWorker {
*/
async InitData() {
if (this.mj_config) return;
// 初始化配置文件,若是没有配置文件,则创建一个配置文件
let mj_config_default = {
serviceID: null,
channelID: null,
authorization: null,
userAgent: null
// 初始化MJ配置
let _mjSettingService = await MJSettingService.getInstance();
let mjSettings = _mjSettingService.GetMJSettingTreeData();
if (mjSettings.code == 0) {
throw new Error(mjSettings.message);
}
// 判断是不是有对应的mj的配置,没有的话就返回默认值
let mj_config = await this.tools.getJsonFilePropertyValue(define.img_base, "mj_config", mj_config_default, false);
this.mj_config = mj_config;
let mjSetting = mjSettings.data;
this.mj_config = mjSetting;
}
/**
@@ -57,23 +57,26 @@ export class DiscordWorker {
await mainSimple.WaitWindowFinishLoad(discordW);
}
// 切换到指定的界面
// 获取当前配置serverID和channelID是不是当前界面是一样的
// 获取当前配置serverID和channelId是不是当前界面是一样的
await this.InitData();
let url = discordW.webContents.getURL();
const regex = /\/channels\/(\d+)\/(\d+)/;
const match = url.match(regex);
let serviceID = null;
let channelID = null;
let serviceId = null;
let channelId = null;
if (match && match[1] && match[2]) {
serviceID = match[1];
channelID = match[2];
serviceId = match[1];
channelId = match[2];
}
if (!(serviceID && channelID && this.mj_config.serviceID === serviceID && this.mj_config.channelID === channelID)) {
if (!(serviceId &&
channelId &&
this.mj_config.browserSetting.serviceId === serviceId &&
this.mj_config.browserSetting.channelId === channelId)) {
// 重新加载url
// 重新拼接url
await discordW.webContents.loadURL(`https://discord.com/channels/${this.mj_config.serviceID}/${this.mj_config.channelID}`)
await discordW.webContents.loadURL(`https://discord.com/channels/${this.mj_config.browserSetting.serviceId}/${this.mj_config.browserSetting.channelId}`)
// 等待界面加载完毕
}
return discordW;
+1
View File
@@ -879,6 +879,7 @@ async function DeleteImageTaskList(value) {
async function GetMachineId() {
try {
let id = await machineId(true);
global.machineId = id;
return {
code: 1,
value: id
+5 -5
View File
@@ -13,9 +13,10 @@ 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 { ImageGenerate } from './ReverseManage/imageGenerate.js'
import { Setting } from './setting/setting.js'
import { has, isEmpty } from 'lodash'
import { AutoSyncMJConfig2210 } from './setting/autoSync.js'
// ipc
import { DiscordIpc, RemoveDiscordIpc } from './IPCEvent/discordIpc.js'
@@ -33,7 +34,6 @@ async function InitData(gl) {
gl.config = res;
gl.requestQuene = new AsyncQueue(gl, res.task_number);
gl.fileQueue = new AsyncQueue(gl, 1);
gl.logger = new Logger(define.logger_path);
return res;
}
@@ -148,7 +148,9 @@ app.whenReady().then(async () => {
optimizer.watchWindowShortcuts(window)
})
//
global.logger = new Logger(define.logger_path);
// 同步数据
await AutoSyncMJConfig2210();
global.newWindow = [];
mainWindow = createWindow('ShowMessage', null)
@@ -399,8 +401,6 @@ ipcMain.handle(DEFINE_STRING.GET_PERMISSION, async (event) => {
}
})
// 试用文件资源打开指定的文件夹
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) => {
+1 -1
View File
@@ -10,7 +10,7 @@ export class Logger {
level: 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.printf(info => `${info.timestamp} [${info.level.toUpperCase()}] [${info.service}] ${info.message}`)
winston.format.printf(info => `${(new Date()).toLocaleString()} [${info.level.toUpperCase()}] [${info.service}] ${info.message}`)
),
transports: [
new DailyRotateFile({
+138
View File
@@ -0,0 +1,138 @@
import fs from 'fs';
import { version } from '../../../package.json'
import { define } from '../../define/define';
const fspromises = fs.promises;
import { MJSettingService } from '../../define/db/service/SoftWare/mjSettingService';
import { isEmpty } from 'lodash';
import { SoftwareService } from '../../define/db/service/SoftWare/softwareService';
//#region 2.2.10 版本 自动同步数据
/**
* 自动同步MJ配置数据
*/
export async function AutoSyncMJConfig2210() {
try {
// 判断版本
if (version != '2.2.10') {
return
}
// 同步MJ的配置到服务器中
let mjConfigJson = JSON.parse(await fspromises.readFile(define.img_base, 'utf-8'));
// 开始同步APIMJsetting
let _mjSettingService = await MJSettingService.getInstance();
if (!mjConfigJson.mj_config) {
return;
}
// 判断数据库中有没有API数据
let dbApiSetting = _mjSettingService.GetAPIMjSetting(null);
if (dbApiSetting.code == 1 && dbApiSetting.data.length <= 0) {
// 同步API请求配置
if (mjConfigJson.mj_config.mj_api_url &&
mjConfigJson.mj_config.mj_speed &&
mjConfigJson.mj_config.api_key) {
let apiSetting = {
mjApiUrl: mjConfigJson.mj_config.mj_api_url,
mjSpeed: mjConfigJson.mj_config.mj_speed,
apiKey: mjConfigJson.mj_config.api_key
};
let res = _mjSettingService.AddAPIMjSetting(apiSetting);
if (res.code == 1) {
global.logger.info("AutoSyncMJConfig2210", '自动同步MJ API 配置数据成功');
} else {
global.logger.error("AutoSyncMJConfig2210", '自动同步MJ API 配置数据失败,错误信息如下:' + '\n' + res.message);
}
}
}
// 判断数据库中是不是存在浏览器配置数据,不存在同步
let dbBrowserSetting = _mjSettingService.GetBrowserMJSetting(null);
if (dbBrowserSetting.code == 1 && dbBrowserSetting.data.length <= 0) {
// 同步浏览器配置,判断数据是不是存在
if (isEmpty(mjConfigJson.mj_config.serviceID) ||
isEmpty(mjConfigJson.mj_config.channelID) ||
isEmpty(mjConfigJson.mj_config.token) ||
(!mjConfigJson.mj_config.userAgent ||
isEmpty(mjConfigJson.mj_config.userAgent) ||
isEmpty(mjConfigJson.mj_config.userAgent.userAgent))
) {
return;
}
// 开始添加浏览器配置
let browserSetting = {
serviceId: mjConfigJson.mj_config.serviceID,
channelId: mjConfigJson.mj_config.channelID,
token: mjConfigJson.mj_config.token,
userAgent: mjConfigJson.mj_config.userAgent.userAgent
};
let res = _mjSettingService.AddBrowserMJSetting(browserSetting);
if (res.code == 1) {
global.logger.info("AutoSyncMJConfig2210", '自动同步MJ 浏览器配置数据成功');
} else {
global.logger.error("AutoSyncMJConfig2210", '自动同步MJ 浏览器配置数据失败,错误信息如下:' + '\n' + res.message);
}
}
// 判断基础数据,不存在同步
let mjSetting = _mjSettingService.GetMjSetting(null);
if (mjSetting.code == 1 && mjSetting.data.length <= 0) {
//判断数据然后选择同步
if (isEmpty(mjConfigJson.mj_config.request_model) ||
isEmpty(mjConfigJson.mj_config.select_robot) ||
isEmpty(mjConfigJson.mj_config.image_scale) ||
isEmpty(mjConfigJson.mj_config.image_model) ||
isEmpty(mjConfigJson.mj_config.image_suffix)
) {
return;
}
// 开始添加基础配置
let mjSettingData = {
requestModel: mjConfigJson.mj_config.request_model,
selectRobot: mjConfigJson.mj_config.select_robot,
imageScale: mjConfigJson.mj_config.image_scale,
imageModel: mjConfigJson.mj_config.image_model,
imageSuffix: mjConfigJson.mj_config.image_suffix,
taskCount: mjConfigJson.mj_config.task_count ? mjConfigJson.mj_config.task_count : 3,
spaceTime: mjConfigJson.mj_config.space_time ? mjConfigJson.mj_config.space_time : 5,
};
let res = _mjSettingService.AddMJSetting(mjSettingData);
if (res.code == 1) {
global.logger.info("AutoSyncMJConfig2210", '自动同步MJ 基础配置数据成功');
} else {
global.logger.error("AutoSyncMJConfig2210", '自动同步MJ 基础配置数据失败,错误信息如下:' + '\n' + res.message);
}
}
// 初始化默认数据
let _softwareService = await SoftwareService.getInstance();
let softs = await _softwareService.GetSoftwareData(null);
if (softs.code == 1 && softs.data.length <= 0) {
// 添加
let softData = {
theme: "light",
reverse_display_show: false,
reverse_show_book_striped: false,
reverse_data_table_size: "samll",
}
let res = await _softwareService.AddSfotware(softData);
if (res.code == 0) {
throw new Error(res.message)
}
global.logger.info("AutoSyncMJConfig2210", '自动同步软件配置数据成功');
}
return mjConfigJson;
} catch (error) {
// 同步数据不报错,只添加日志
global.logger.error("AutoSyncMJConfig2210", '自动同步MJ配置数据失败,错误信息如下:' + '\n' + error.toString());
}
}
//#endregion
+67
View File
@@ -0,0 +1,67 @@
import SoftwareService from "../../define/db/service/SoftWare/softwareService";
import { ComponentSize } from "../../define/enum/softwareEnum";
import { errorMessage, successMessage } from "../generalTools";
export class BasicSetting {
constructor() {
}
// 初始化数据
async init() {
this.setting = await SoftwareService.getInstance();
}
/**
* 获取修改尺寸的下拉菜单的尺寸
* @returns
*/
GetComponentSize() {
return successMessage([
{
value: ComponentSize.TINY,
key: ComponentSize.TINY,
label: "极小"
}, {
key: ComponentSize.SMALL,
value: ComponentSize.SMALL,
label: "小"
}, {
value: ComponentSize.MEDIUM,
key: ComponentSize.MEDIUM,
label: "中"
}, {
value: ComponentSize.LARGE,
key: ComponentSize.LARGE,
label: "大"
}
], "选择尺寸的下拉菜单消息", 'BasicSetting_GetComponentSize')
}
// 获取基础配置信息
async GetSoftwareSetting() {
try {
await this.init()
let res = await this.setting.GetSoftwareData();
return res;
} catch (error) {
return errorMessage(error.message, 'BasicSetting_GetSoftwareSetting');
}
}
/**
* 修改软件设置的所有的数据,直接修改全部的数据
* @param {*} paramms
* @returns
*/
async SaveSoftWareSetting(paramms) {
try {
await this.init()
let res = await this.setting.UpdateSoftware(paramms);
return res;
} catch (error) {
return errorMessage(error.message, 'BasicSetting_SaveSoftWareSetting');
}
}
}
+5
View File
@@ -0,0 +1,5 @@
export class BookSetting {
constructor() {
}
}
+155
View File
@@ -0,0 +1,155 @@
import axios from 'axios';
import { MJSettingService } from '../../define/db/service/SoftWare/mjSettingService'
import { define } from '../../define/define';
import { errorMessage, successMessage } from '../generalTools';
export class MJSetting {
constructor() {
}
/**
* 获取MJ的基础设置数据
*/
async GetMJSetting(mjSettingQuery) {
try {
let _mjSetting = await MJSettingService.getInstance()
let res = _mjSetting.GetMjSetting(mjSettingQuery);
return res
} catch (error) {
return errorMessage("获取MJ的基础配置错误,错误信息如下:" + error.toString(), "MJSetting_GetMJSetting");
}
}
/**
* 保存MJ的基础设置
* @param {*} mjSetting 保存的数据
*/
async UpdateMJSetting(mjSetting) {
try {
let _mjSetting = await MJSettingService.getInstance()
let res = _mjSetting.UpdateMJSetting(mjSetting);
return res
} catch (error) {
return errorMessage("保存MJ的基础配置错误,错误信息如下:" + error.toString(), "MJSetting_UpdateMJSetting");
}
}
/**
* 获取MJ配置的所有数据
*/
async GetMJSettingTreeData() {
try {
let _mjSetting = await MJSettingService.getInstance()
let res = _mjSetting.GetMJSettingTreeData();
return res
} catch (error) {
return errorMessage("获取MJ配置错误,详细错误信息如下:" + error.toString(), 'MJSetting_GetMJSettingTreeData');
}
}
/**
* 保存MJ设置的所有数据
* @param {*} mjSetting
*/
async SaveMJSettingTreeData(mjSetting) {
try {
let _mjSetting = await MJSettingService.getInstance()
let res = _mjSetting.SaveMJSettingTreeData(mjSetting);
return res
} catch (error) {
return errorMessage("保存MJ配置错误,详细错误信息如下:" + error.toString(), 'MJSetting_SaveMJSettingTreeData');
}
}
/**
* 同步MJ代理模式账号信息
* @param {*} value
* @returns
*/
async MjRemoteAccountSync() {
try {
// 获取账号数据
let _mjSettingService = await MJSettingService.getInstance()
let remoteMjSettings = _mjSettingService.GetRemoteMJSettings(null);
if (remoteMjSettings.data.length <= 0) {
throw new Error("没有找到保存的数据,请先保存")
}
let remoteMjSetting = remoteMjSettings.data[0]
// 判断是不是同步过,就是有没有accountId
// 判断有没有accountId
if (remoteMjSetting.accountId) {
// 查找是不是有
let accountRes = await axios.get(define.remotemj_api + `mj/account/${remoteMjSetting.accountId}/fetch`, {
headers: {
"mj-api-secret": define.API
}
});
console.log(accountRes)
// 没有找到账号信息,重新添加
if (accountRes.status == 200 && accountRes.data == "") {
// 添加账号
// 找不到的话,直接添加账号
let accountRes = await axios.post(define.remotemj_api + `mj/account/create`, remoteMjSetting, {
headers: {
"mj-api-secret": define.API
}
});
console.log(accountRes);
if (accountRes.data.code != 1) {
throw new Error(accountRes.data.description);
}
// 添加成功,修改数据,将数据返回
let accountId = accountRes.data.result;
remoteMjSetting.accountId = accountId;
let save_res = _mjSettingService.UpdateRemoteMjSetting(remoteMjSetting);
if (save_res.code != 1) {
throw new Error(save_res.message)
}
return successMessage(remoteMjSetting, "MJ新增账号同步成功", "MJSetting_MjRemoteAccountSync")
} else {
// 能找到的话,要更新一下账号信息,并重连
remoteMjSetting["weight"] = 1
let accountRes = await axios.put(define.remotemj_api + `mj/account/${remoteMjSetting.accountId}/update-reconnect`, remoteMjSetting, {
headers: {
"mj-api-secret": define.API
}
});
console.log(accountRes)
if (accountRes.data.code == 0) {
throw new Error(accountRes.description)
}
return successMessage(remoteMjSetting, "MJ账号同步成功", "MJSetting_MjRemoteAccountSync")
}
} else {
// 没有accountId,直接添加
// 添加账号
let accountRes = await axios.post(define.remotemj_api + `mj/account/create`, remoteMjSetting, {
headers: {
"mj-api-secret": define.API
}
});
console.log(accountRes);
if (accountRes.data.code != 1) {
throw new Error(accountRes.data.description);
}
// 添加成功,修改数据,将数据返回
let accountId = accountRes.data.result;
remoteMjSetting.accountId = accountId;
let save_res = _mjSettingService.UpdateRemoteMjSetting(remoteMjSetting);
if (save_res.code != 1) {
throw new Error(save_res.message)
}
return successMessage(remoteMjSetting, "MJ账号同步成功", "MJSetting_MjRemoteAccountSync")
}
} catch (error) {
return errorMessage("MJ代理模式账号同步错误,详细错误信息如下:" + error.toString(), 'MJSetting_MjRemoteAccountSync');
}
}
}
+3 -1
View File
@@ -8,6 +8,7 @@ import { ClipSetting } from "../../define/setting/clipSetting";
import { ImageSetting } from "../../define/setting/imageSetting";
import { DEFINE_STRING } from "../../define/define_string";
import { TagDefine } from "../../define/tagDefine";
import { errorMessage } from "../generalTools";
let tagDefine = new TagDefine(global);
export class Setting {
@@ -271,6 +272,8 @@ export class Setting {
let res = await axios.post('http://api.yu-zhile.com/GetMachineStatus', {
machineId: value
})
// let res = await axios.get('http://lapi.laitool.cn/api/Machine/GetMachineStatus?machineId=' + value);
if (res.status != 200) {
throw new Error("请求错误");
}
@@ -340,6 +343,5 @@ export class Setting {
return ImageSetting.SaveDefineConfigJsonByProperty(value);
}
//#endregion
}