From c9c3316437dec8fdc084118eacda8a666276adcf Mon Sep 17 00:00:00 2001 From: Lino Schmidt Date: Fri, 2 Dec 2022 21:46:26 +0100 Subject: [PATCH] New log saving system --- dependencies/blenderScript.py | 4 +- src/components/blenderController.ts | 84 ++++++------ src/components/logReader.ts | 22 +--- src/components/logger.ts | 6 +- src/components/settings.ts | 176 ++++++++++++++++++++++--- src/components/ui/mainPage.tsx | 20 ++- src/components/ui/renderFinishPage.tsx | 10 +- src/components/ui/renderingPage.tsx | 2 +- 8 files changed, 231 insertions(+), 93 deletions(-) diff --git a/dependencies/blenderScript.py b/dependencies/blenderScript.py index 3555d90..5b2c4c6 100644 --- a/dependencies/blenderScript.py +++ b/dependencies/blenderScript.py @@ -51,7 +51,7 @@ while True: stickDistance = _map(settings["stickDistance"], 0, 100, 5, 105) fps = settings["fps"] videoFormat = settings["videoFormat"] - logs = settings["logs"][1:][:-1].split("\"\"") + logs = settings["logs"] output = settings["output"] dataPath = settings["dataPath"] @@ -127,7 +127,7 @@ while True: Camera.location[0] = stickDistance/2 Camera.data.ortho_scale = stickDistance+5 scn.render.resolution_y = int(width/_map(stickDistance, 5, 105, 2, 21.6)) - bpy.context.scene.render.filepath = output + "\\" + log.split("/")[-1].split("\\")[-1].replace(".csv", "."+videoFormat) + bpy.context.scene.render.filepath = output[logNumber-1] scn.render.fps = 1000 scn.render.fps_base = FPSxxx diff --git a/src/components/blenderController.ts b/src/components/blenderController.ts index 77fa940..a41c011 100644 --- a/src/components/blenderController.ts +++ b/src/components/blenderController.ts @@ -5,9 +5,10 @@ import { setBlenderLoading, setBlenderStatus } from "./ui/menu"; import { setLogNumber, setPastTime, setRemainingTime, setRenderDisplayProgress, setStatus, setPastTimeNow, setRemainingTimeNow } from "./ui/renderingPage"; import {imageLoading, imageLoaded} from "./ui/settingsPage"; import { getLogSize, getInOutSettings, getActiveProfile } from "./settings"; -import isValid from "is-valid-path"; import { pageSetRendering, setProgress, openPage, Page } from "../renderer"; import { ipcRenderer } from "electron"; +import path from 'path'; +import fs from "fs"; // import { getDoNotDisturb } from "electron-notification-state"; export const renderInfo = { @@ -68,6 +69,42 @@ function setRenderProgress(log:number, init:boolean, frameCount:number, frame:nu } } +function getOutPath(log:string) { + let fullOutPath = path.join(getInOutSettings().output, log.substring(log.lastIndexOf("\\")).replace(".csv", "."+getActiveProfile().videoFormat)); + + if(fs.existsSync(fullOutPath)) { + let i = 1; + while(fs.existsSync(fullOutPath.replace("."+getActiveProfile().videoFormat, " ("+i+")."+getActiveProfile().videoFormat))) { + i++; + } + fullOutPath = fullOutPath.replace("."+getActiveProfile().videoFormat, " ("+i+")."+getActiveProfile().videoFormat); + } + + return fullOutPath; +} + +let outputArgs:string[] = []; + +function blenderArgs() { + const outputList:string[] = []; + getInOutSettings().logs.forEach(log => { + outputList.push(getOutPath(log)); + }); + + outputArgs = outputList; + + return JSON.stringify({ + stickMode2:getActiveProfile().stickMode2, + width:getActiveProfile().width, + stickDistance:getActiveProfile().stickDistance, + fps:getActiveProfile().fps, + videoFormat:getActiveProfile().videoFormat, + logs:getInOutSettings().logs, + output:outputList, + dataPath:dataPath + }); +} + function startBlender() { let frames = "0"; let lastFrame = "0"; @@ -156,17 +193,7 @@ function startBlender() { } else { waitingForRender = false; renderingPicture = true; - const blenderArgs = JSON.stringify({ - stickMode2:getActiveProfile().stickMode2, - width:getActiveProfile().width, - stickDistance:getActiveProfile().stickDistance, - fps:getActiveProfile().fps, - videoFormat:getActiveProfile().videoFormat, - logs:getInOutSettings().log, - output:getInOutSettings().output, - dataPath:dataPath - }); - blenderConsole.stdin.write("getRender -- "+blenderArgs+"\n"); + blenderConsole.stdin.write("getRender -- "+blenderArgs()+"\n"); setBlenderStatus("Rendering"); setBlenderLoading(true); imageLoading(); @@ -200,31 +227,19 @@ function blender(command:blenderCmd) { imageLoading(); setBlenderStatus("Rendering"); setBlenderLoading(true); - const blenderArgs = JSON.stringify({ - stickMode2:getActiveProfile().stickMode2, - width:getActiveProfile().width, - stickDistance:getActiveProfile().stickDistance, - fps:getActiveProfile().fps, - videoFormat:getActiveProfile().videoFormat, - logs:getInOutSettings().log, - output:getInOutSettings().output, - dataPath:dataPath - }); - blenderConsole.stdin.write("getRender -- "+blenderArgs+"\n"); + blenderConsole.stdin.write("getRender -- "+blenderArgs()+"\n"); } else { waitingForRender = true; } } else if(command === blenderCmd.startRendering) { if(readyToAcceptCommand) { - if(getInOutSettings().log == "") { + if(getInOutSettings().logs.length === 0) { logger.warningMSG("No log selected!"); - } else if(!isValid(getInOutSettings().log)) { - logger.warningMSG("Output path is invalid!"); } else { currentLogPortion = 0; const logSizeList:number[] = []; - getInOutSettings().logList.forEach(function (value, index) { + getInOutSettings().logs.forEach(function (value, index) { logSizeList.push(getLogSize(index)); }); @@ -243,17 +258,7 @@ function blender(command:blenderCmd) { pageSetRendering(true); setBlenderStatus("Rendering"); setBlenderLoading(true); - const blenderArgs = JSON.stringify({ - stickMode2:getActiveProfile().stickMode2, - width:getActiveProfile().width, - stickDistance:getActiveProfile().stickDistance, - fps:getActiveProfile().fps, - videoFormat:getActiveProfile().videoFormat, - logs:getInOutSettings().log, - output:getInOutSettings().output, - dataPath:dataPath - }); - blenderConsole.stdin.write("startRendering -- "+blenderArgs+"\n"); + blenderConsole.stdin.write("startRendering -- "+blenderArgs()+"\n"); renderInfo.startTime = new Date().getTime(); setPastTime("0min 0sec"); @@ -280,5 +285,6 @@ export { blender, blenderCmd, startBlender, - renderingPicture + renderingPicture, + outputArgs } \ No newline at end of file diff --git a/src/components/logReader.ts b/src/components/logReader.ts index 1381d43..a71d818 100644 --- a/src/components/logReader.ts +++ b/src/components/logReader.ts @@ -163,10 +163,8 @@ async function getLogTime(filePath:string) { async function getAllLogs() { const loadList = []; - if(getInOutSettings().log.length > 0) { - const logs = getInOutSettings().log.substring(1).slice(0, -1).split('""'); - - for(const log of logs) { + if(getInOutSettings().logs.length > 0) { + for(const log of getInOutSettings().logs) { loadList.push({ name: log.split(platformCharacter())[log.split(platformCharacter()).length - 1].replace(".csv", ""), path: log, @@ -185,9 +183,8 @@ async function reloadAllLogs() { } async function updateLogs() { - if(getInOutSettings().log.length > 0) { - const logs = getInOutSettings().log.substring(1).slice(0, -1).split('""'); - for(const log of logs) { + if(getInOutSettings().logs.length > 0) { + for(const log of getInOutSettings().logs) { if(!logList.some(x => x.path === log)) { logList.push({ name: log.split(platformCharacter())[log.split(platformCharacter()).length - 1].replace(".csv", ""), @@ -198,7 +195,7 @@ async function updateLogs() { } for(const log of logList) { - if(!logs.some(x => x === log.path)) { + if(!getInOutSettings().logs.some(x => x === log.path)) { logList.splice(logList.indexOf(log), 1); } } @@ -207,20 +204,13 @@ async function updateLogs() { } } -function getLogList() { - return getInOutSettings().log.split("\"\""); -} - function getLogSize(index:number) { - const logList = getInOutSettings().log.substring(1).slice(0, -1).split('""'); - - return fs.statSync(logList[index]).size; + return fs.statSync(getInOutSettings().logs[index]).size; } export { reloadAllLogs, logList, updateLogs, - getLogList, getLogSize }; \ No newline at end of file diff --git a/src/components/logger.ts b/src/components/logger.ts index 47c4610..0521d0d 100644 --- a/src/components/logger.ts +++ b/src/components/logger.ts @@ -40,10 +40,14 @@ const logger = { dialog.showMessageBox({ type: 'warning', - buttons: ['OK'], + buttons: ['Open Log', 'OK'], defaultId: 1, title: 'Warning!', message: message + }).then(res => { + if(res.response === 0) { + exec('start "" "' + path.join(dataPath, "logs") + '"'); + } }); } } diff --git a/src/components/settings.ts b/src/components/settings.ts index a8d0e53..c829641 100644 --- a/src/components/settings.ts +++ b/src/components/settings.ts @@ -1,6 +1,9 @@ import {SettingPath, defaultOutputPath, OLDSettingPath} from './paths'; +import {dialog} from '@electron/remote'; import logger from "./logger"; import fs from "fs"; +import {app} from 'electron'; +import { ipcRenderer } from "electron"; enum VideoFormat { mp4="mp4", @@ -22,7 +25,7 @@ type JSONProfile = { type JSONSettings = { activeProfile: string, profiles: JSONProfile[], - log: string, + logs: string[], output: string, } @@ -38,7 +41,7 @@ const defaultSettings:JSONSettings = { videoFormat: VideoFormat.webm } ], - log: '', + logs: [], output: defaultOutputPath }; @@ -57,6 +60,7 @@ function getXMLChild(doc:Document, child:string) { return String(doc.getElementsByTagName(child)[0].childNodes[0].nodeValue); } +let fetchFailed = ""; const settingList = await fetch(SettingPath).then(function(response) { return response.text(); }).catch(function(err) { @@ -64,7 +68,6 @@ const settingList = await fetch(SettingPath).then(function(response) { return "fileLoadFailed"; }).then(async function(data) { if(data === "fileLoadFailed") { - return await fetch(OLDSettingPath).then(function(response) { return response.text(); }).catch(function(err) { @@ -72,32 +75,171 @@ const settingList = await fetch(SettingPath).then(function(response) { return "fileLoadFailed"; }).then(function(data) { if(data === "fileLoadFailed") { + fetchFailed = "fileLoadFailed"; return defaultSettings; } const parser = new DOMParser(); const xmlDoc = parser.parseFromString(data, 'text/xml'); + + const allLogs = catchSetting(function() {return (getXMLChild(xmlDoc, "log") === "None")? "":getXMLChild(xmlDoc, "log");},function() { + fetchFailed === "singleSetting"? fetchFailed = "multiSetting":fetchFailed = "singleSetting"; + return "" + }); + const newLogs = defaultSettings.logs; + if(allLogs !== "") { + const allLogsList = allLogs.split("\"\""); + allLogsList.forEach(log => { + if(log !== "") { + newLogs.push(log.replace('"', '')); + } + }); + } return { activeProfile: defaultSettings.activeProfile, profiles: [ { profileName: defaultSettings.profiles[0].profileName, - fps: parseInt(catchSetting(function() {return getXMLChild(xmlDoc, "fps");},function() {return defaultSettings.profiles[0].fps.toString();})), - width: parseInt(catchSetting(function() {return getXMLChild(xmlDoc, "width");},function() {return defaultSettings.profiles[0].width.toString();})), - stickDistance: parseInt(catchSetting(function() {return getXMLChild(xmlDoc, "stickDistance");},function() {return defaultSettings.profiles[0].stickDistance.toString();})), - stickMode2: catchSetting(function() {return getXMLChild(xmlDoc, "stickMode2");},function() {return defaultSettings.profiles[0].stickMode2.toString();}) === "true", - videoFormat: catchSetting(function() {return getXMLChild(xmlDoc, "videoFormat");},function() {return defaultSettings.profiles[0].videoFormat.toString();}) as VideoFormat as VideoFormat + fps: parseInt(catchSetting(function() {return getXMLChild(xmlDoc, "fps");},function() { + fetchFailed === "singleSetting"? fetchFailed = "multiSetting":fetchFailed = "singleSetting"; + return defaultSettings.profiles[0].fps.toString(); + })), + width: parseInt(catchSetting(function() {return getXMLChild(xmlDoc, "width");},function() { + fetchFailed === "singleSetting"? fetchFailed = "multiSetting":fetchFailed = "singleSetting"; + return defaultSettings.profiles[0].width.toString(); + })), + stickDistance: parseInt(catchSetting(function() {return getXMLChild(xmlDoc, "stickDistance");},function() { + fetchFailed === "singleSetting"? fetchFailed = "multiSetting":fetchFailed = "singleSetting"; + return defaultSettings.profiles[0].stickDistance.toString(); + })), + stickMode2: catchSetting(function() {return getXMLChild(xmlDoc, "stickMode2");},function() { + fetchFailed === "singleSetting"? fetchFailed = "multiSetting":fetchFailed = "singleSetting"; + return defaultSettings.profiles[0].stickMode2.toString(); + }) === "true", + videoFormat: catchSetting(function() {return getXMLChild(xmlDoc, "videoFormat");},function() { + return defaultSettings.profiles[0].videoFormat.toString(); + }) as VideoFormat as VideoFormat } ], - log: catchSetting(function() {return (getXMLChild(xmlDoc, "log") === "None")? "":getXMLChild(xmlDoc, "log");},function() {return defaultSettings.log;}), - output: catchSetting(function() {return getXMLChild(xmlDoc, "output");},function() {return defaultSettings.output;}) + logs: newLogs, + output: catchSetting(function() {return getXMLChild(xmlDoc, "output");},function() { + fetchFailed === "singleSetting"? fetchFailed = "multiSetting":fetchFailed = "singleSetting"; + return defaultSettings.output; + }) } as JSONSettings; }); } + const parsedData = JSON.parse(data); - return JSON.parse(data) as JSONSettings; + let profiles:JSONProfile[] = []; + if(parsedData.profiles !== undefined) { + parsedData.profiles.forEach((profile:JSONProfile) => { + if(typeof profile.profileName !== "string") { + fetchFailed === "singleSetting"? fetchFailed = "multiSetting":fetchFailed = "singleSetting"; + profile.profileName = defaultSettings.profiles[0].profileName; + } + if(typeof profile.fps !== "number") { + fetchFailed === "singleSetting"? fetchFailed = "multiSetting":fetchFailed = "singleSetting"; + profile.fps = defaultSettings.profiles[0].fps; + } + if(typeof profile.width !== "number") { + fetchFailed === "singleSetting"? fetchFailed = "multiSetting":fetchFailed = "singleSetting"; + profile.width = defaultSettings.profiles[0].width; + } + if(typeof profile.stickDistance !== "number") { + fetchFailed === "singleSetting"? fetchFailed = "multiSetting":fetchFailed = "singleSetting"; + profile.stickDistance = defaultSettings.profiles[0].stickDistance; + } + if(typeof profile.stickMode2 !== "boolean") { + fetchFailed === "singleSetting"? fetchFailed = "multiSetting":fetchFailed = "singleSetting"; + profile.stickMode2 = defaultSettings.profiles[0].stickMode2; + } + if(typeof profile.videoFormat !== "string") { + fetchFailed === "singleSetting"? fetchFailed = "multiSetting":fetchFailed = "singleSetting"; + profile.videoFormat = defaultSettings.profiles[0].videoFormat; + } + + profiles.push({ + profileName: profile.profileName, + fps: profile.fps, + width: profile.width, + stickDistance: profile.stickDistance, + stickMode2: profile.stickMode2, + videoFormat: profile.videoFormat + }); + }); + } else { + fetchFailed = "multiSetting"; + profiles = defaultSettings.profiles; + } + + const logs:string[] = []; + if(parsedData.logs !== undefined) { + parsedData.logs.forEach((log:string) => { + if(typeof log === "string") { + logs.push(log); + } + }); + } else { + fetchFailed === "singleSetting"? fetchFailed = "multiSetting":fetchFailed = "singleSetting"; + } + + return { + activeProfile: catchSetting(function() {return parsedData.activeProfile;},function() { + fetchFailed === "singleSetting"? fetchFailed = "multiSetting":fetchFailed = "singleSetting"; + return defaultSettings.activeProfile; + }), + profiles, + logs, + output: catchSetting(function() {return parsedData.output;},function() { + fetchFailed === "singleSetting"? fetchFailed = "multiSetting":fetchFailed = "singleSetting"; + return defaultSettings.output; + }) + } }); +if(fetchFailed !== "") { + if(fetchFailed === "fileLoadFailed") { + dialog.showMessageBox({ + type: 'warning', + buttons: ['View Settings', 'Continue'], + defaultId: 1, + title: 'Warning!', + message: "Failed to load settings file. Using default settings. if you continue, the settings will be overwritten.", + }).then((result) => { + if(result.response === 0) { + ipcRenderer.send('closeApp'); + app.quit(); + } + }); + } else if(fetchFailed === "singleSetting") { + dialog.showMessageBox({ + type: 'warning', + buttons: ['View Settings', 'Continue'], + defaultId: 1, + title: 'Warning!', + message: "A setting failed to load. If you continue, the setting will be overwritten.", + }).then((result) => { + if(result.response === 0) { + ipcRenderer.send('closeApp'); + app.quit(); + } + }); + } else if(fetchFailed === "multiSetting") { + dialog.showMessageBox({ + type: 'warning', + buttons: ['View Settings', 'Continue'], + defaultId: 1, + title: 'Warning!', + message: "Multiple settings failed to load. If you continue, the settings will be overwritten.", + }).then((result) => { + if(result.response === 0) { + ipcRenderer.send('closeApp'); + app.quit(); + } + }); + } +} function createProfile(profileName:string, clone:boolean) { @@ -170,9 +312,9 @@ function editProfile(optiones:{fps?:number, width?:number, stickDistance?:number writeSettings(); } -function setInOutSettings(args:{log?:string, output?:string}) { - if(args.log !== undefined) { - settingList.log = args.log; +function setInOutSettings(args:{logs?:string[], output?:string}) { + if(args.logs !== undefined) { + settingList.logs = args.logs; } if(args.output !== undefined) { settingList.output = args.output; @@ -180,7 +322,7 @@ function setInOutSettings(args:{log?:string, output?:string}) { writeSettings(); } function getInOutSettings() { - return {log: settingList.log, output: settingList.output, logList:settingList.log.split("\"\"")}; + return {logs: settingList.logs, output: settingList.output}; } function removeProfile(profileName?:string) { @@ -236,9 +378,7 @@ function getActiveProfile() { } function getLogSize(index:number) { - const logList = settingList.log.substring(1).slice(0, -1).split('""'); - - return fs.statSync(logList[index]).size; + return fs.statSync(settingList.logs[index]).size; } export { diff --git a/src/components/ui/mainPage.tsx b/src/components/ui/mainPage.tsx index abaa32e..86a58aa 100644 --- a/src/components/ui/mainPage.tsx +++ b/src/components/ui/mainPage.tsx @@ -32,7 +32,7 @@ function MainPage() {
@@ -60,8 +60,8 @@ function updateLogTable(setLogTable:React.Dispatch({log.time.length.formatted}) @@ -69,7 +69,7 @@ function updateLogTable(setLogTable:React.Dispatch>) } ] }).then(async result => { - let logStr = ""; + const newLogs = getInOutSettings().logs; result.filePaths.forEach(value => { - const logToAdd = "\"" + value + "\""; - if(getInOutSettings().log.includes(logToAdd)) { - logger.warningMSG("Log " + logToAdd + " already added."); + if(getInOutSettings().logs.includes(value)) { + logger.warningMSG("Log \"" + value + "\" already added."); } else { - logStr += "\"" + String(value) + "\""; + newLogs.push(value); } }); - const newLogs = getInOutSettings().log + logStr; - setInOutSettings({log:newLogs}); + setInOutSettings({logs:newLogs}); await updateLogs(); updateLogTable(setLogTable); }).catch(err => { diff --git a/src/components/ui/renderFinishPage.tsx b/src/components/ui/renderFinishPage.tsx index 27824bc..e10067b 100644 --- a/src/components/ui/renderFinishPage.tsx +++ b/src/components/ui/renderFinishPage.tsx @@ -1,6 +1,6 @@ import React, { CSSProperties } from "react"; import {openPage, Page} from "../../renderer"; -import {renderInfo} from "../blenderController"; +import {renderInfo, outputArgs} from "../blenderController"; import openFolder from "../openFolder"; import {getInOutSettings, getActiveProfile} from "../settings"; import VideoPlayer from "./videoPlayer"; @@ -44,14 +44,14 @@ function RenderFinishPage() { const [videoSource, setVideoSource] = React.useState({src: path.join(getInOutSettings().output, logPlaying+"."+getActiveProfile().videoFormat), type: 'video/'+getActiveProfile().videoFormat.toUpperCase()}); - const OutputList = logList.map((inputLog, index) => { - const outputLogPath = path.join(getInOutSettings().output, inputLog.name+"."+getActiveProfile().videoFormat); - return + const OutputList = outputArgs.map((output, index) => { + const outputName = output.substring(output.lastIndexOf("\\")+1); + return }); React.useEffect(() => { setVideoSource({ - src: path.join(getInOutSettings().output, logPlaying+"."+getActiveProfile().videoFormat), + src: path.join(getInOutSettings().output, logPlaying.replace(".csv", "."+getActiveProfile().videoFormat)), type: 'video/'+getActiveProfile().videoFormat.toUpperCase() }); }, [logPlaying]); diff --git a/src/components/ui/renderingPage.tsx b/src/components/ui/renderingPage.tsx index 20c0f5a..d514574 100644 --- a/src/components/ui/renderingPage.tsx +++ b/src/components/ui/renderingPage.tsx @@ -34,7 +34,7 @@ function RenderingPage() { return (
-

{"Log " + logNumber + "/" + getInOutSettings().logList.length}

+

{"Log " + logNumber + "/" + getInOutSettings().logs.length}

{status}