removed warnings and errors

This commit is contained in:
Robert Nasarek 2022-09-19 23:10:07 +02:00
parent fc1b0a36a9
commit d27e3ecf01
9 changed files with 136 additions and 62 deletions

View file

@ -0,0 +1,29 @@
const path = require('path');
const rootPath = path.resolve(__dirname, '../..');
const srcPath = path.resolve(rootPath, 'src');
const srcMainPath = path.resolve(srcPath, 'main');
const srcRendererPath = path.resolve(srcPath, 'renderer');
const appPackagePath = path.resolve(rootPath, 'package.json');
const appNodeModulesPath = path.resolve(rootPath, 'node_modules');
const distPath = path.resolve(rootPath, 'dist');
const distMainPath = path.resolve(distPath, 'main');
const distRendererPath = path.resolve(distPath, 'renderer');
const buildPath = path.resolve(rootPath, 'build');
export default {
rootPath,
srcPath,
srcMainPath,
srcRendererPath,
appPackagePath,
appNodeModulesPath,
distPath,
distMainPath,
distRendererPath,
buildPath,
};

43
main.js
View file

@ -3,14 +3,19 @@
// Import parts of electron to use // Import parts of electron to use
const {app, BrowserWindow, dialog, ipcMain, Menu, screen, Tray} = require('electron') const {app, BrowserWindow, dialog, ipcMain, Menu, screen, Tray} = require('electron')
const openAboutWindow = require('about-window').default const openAboutWindow = require('about-window').default
const path = require('path') const path = require('path');
const url = require('url') const fs = require('fs');
const url = require('url');
// Keep a global reference of the window object, if you don't, the window will // Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected. // be closed automatically when the JavaScript object is garbage collected.
let mainWindow, tray; let mainWindow, tray;
let devBrowserProperties = {}; let devBrowserProperties = {};
const ASSET_PATH = app.isPackaged
? path.resolve(process.resourcesPath, 'app/src/assets')
: path.resolve(__dirname, 'src/assets');
let trayMenu = Menu.buildFromTemplate([ let trayMenu = Menu.buildFromTemplate([
{ {
label: 'Öffnen', label: 'Öffnen',
@ -27,8 +32,10 @@ let trayMenu = Menu.buildFromTemplate([
} }
]) ])
const RESSOURCE_PATH= fs.existsSync(ASSET_PATH) ? ASSET_PATH : 'resources/files' ;
function createTray() { function createTray() {
tray = new Tray('./resources/files/images/marvin16x16.png'); tray = new Tray(path.resolve(RESSOURCE_PATH, 'images/marvin16x16.png'));
tray.setToolTip('Marvin') tray.setToolTip('Marvin')
tray.setContextMenu(trayMenu); tray.setContextMenu(trayMenu);
tray.on('click', function() { tray.on('click', function() {
@ -60,12 +67,18 @@ if (process.platform === 'win32') {
async function handleFileOpen() { async function handleFileOpen() {
const {canceled, filePaths} = await dialog.showOpenDialog(mainWindow, {properties: ['openDirectory']}) const {canceled, filePaths} = await dialog.showOpenDialog(mainWindow, {properties: ['openDirectory']})
if (canceled) { if (canceled) {
return return false
} else { } else {
return filePaths[0] return filePaths[0]
} }
} }
// Constants
const getAssetPath = async (assetPath) => {
return path.resolve(ASSET_PATH, assetPath);
};
// Build main menu from file. // Build main menu from file.
let mainMenu = Menu.buildFromTemplate( let mainMenu = Menu.buildFromTemplate(
[ [
@ -142,22 +155,11 @@ let mainMenu = Menu.buildFromTemplate(
] ]
) )
const RESOURCES_PATH = app.isPackaged
? path.join(process.resourcesPath, 'assets')
: path.join(__dirname, '../../assets');
console.log(process.resourcesPath);
console.log(__dirname);
const getAssetPath = (paths) => {
return path.join(RESOURCES_PATH, paths);
};
function createWindow(dimensions) { function createWindow(dimensions) {
if (dev !== true) { if (dev !== true) {
devBrowserProperties = { devBrowserProperties = {
fullscreenable: false, fullscreenable: false,
resizable: false, resizable: true,
} }
} }
@ -173,7 +175,7 @@ function createWindow(dimensions) {
y: 0, y: 0,
width: appWidth, width: appWidth,
height: appHeight, height: appHeight,
icon: __dirname + '/marvin.ico', icon: path.resolve(RESSOURCE_PATH, 'images/marvin.ico'),
show: false, show: false,
webPreferences: { webPreferences: {
preload: path.join(__dirname, 'preload.js'), preload: path.join(__dirname, 'preload.js'),
@ -221,11 +223,13 @@ function createWindow(dimensions) {
.catch(err => console.log('Error loading React DevTools: ', err)) .catch(err => console.log('Error loading React DevTools: ', err))
mainWindow.webContents.openDevTools() mainWindow.webContents.openDevTools()
} }
mainWindow.webContents.openDevTools()
}) })
mainWindow.on('close', function (e) { mainWindow.on('close', function (e) {
if(mainWindow.isMinimized()) { if(mainWindow.isMinimized()) {
app.quit() app.quit()
app.quit()
} else { } else {
e.preventDefault() e.preventDefault()
mainWindow.minimize(); mainWindow.minimize();
@ -235,6 +239,7 @@ function createWindow(dimensions) {
mainWindow.on('closed', function () { mainWindow.on('closed', function () {
mainWindow = null; mainWindow = null;
}) })
} }
// This method will be called when Electron has finished // This method will be called when Electron has finished
@ -242,6 +247,10 @@ function createWindow(dimensions) {
// Some APIs can only be used after this event occurs. // Some APIs can only be used after this event occurs.
app.on('ready', () => { app.on('ready', () => {
ipcMain.handle('dialog:openFile', handleFileOpen) ipcMain.handle('dialog:openFile', handleFileOpen)
ipcMain.handle('assetPath:getAssetPath', async (event, assetPath) => {
return await getAssetPath(assetPath)
})
const display = screen.getPrimaryDisplay(); const display = screen.getPrimaryDisplay();
const dimensions = display.size; const dimensions = display.size;
createWindow(dimensions); createWindow(dimensions);

View file

@ -33,9 +33,9 @@
"prod": "cross-env NODE_ENV=production webpack --mode production --config webpack.build.config.js && electron --noDevServer .", "prod": "cross-env NODE_ENV=production webpack --mode production --config webpack.build.config.js && electron --noDevServer .",
"start": "cross-env NODE_ENV=development webpack serve --hot --host 0.0.0.0 --config=./webpack.dev.config.js --mode development", "start": "cross-env NODE_ENV=development webpack serve --hot --host 0.0.0.0 --config=./webpack.dev.config.js --mode development",
"build": "cross-env NODE_ENV=production webpack --config webpack.build.config.js --mode production", "build": "cross-env NODE_ENV=production webpack --config webpack.build.config.js --mode production",
"pack:installer": "electron-builder build -lw", "pack:installer": "electron-builder build -l",
"package": "npm run build", "package": "npm run build",
"postpackage": "electron-packager ./ --ignore \"(resources|builds|installer)\" --out=./builds --overwrite --platform win32,linux --icon marvin.ico --extra-resource 'resources/files'" "postpackage": "electron-packager ./ --ignore \"(resources|builds|installer)\" --out=./builds --overwrite --platform linux --icon marvin.ico"
}, },
"dependencies": { "dependencies": {
"@emotion/react": "^11.10.0", "@emotion/react": "^11.10.0",

View file

@ -1,11 +1,11 @@
// Modules // Modules
import createReport from 'docx-templates'; import createReport from 'docx-templates';
import fs, {writeFile} from 'fs';
import {mkdir} from 'node:fs/promises'; import {mkdir} from 'node:fs/promises';
import path from 'path'; import path from 'path';
import replaceSpecialCharacters from "replace-special-characters"; import replaceSpecialCharacters from "replace-special-characters";
import {parseString, Builder} from 'xml2js'; import {parseString, Builder} from 'xml2js';
import {FileLoader} from "./FileLoader";
//////////////////// ////////////////////
@ -24,9 +24,11 @@ class DocCreator {
// Get DateTime. // Get DateTime.
this.today = new Date(); this.today = new Date();
// FileLoader
this.fileLoader = new FileLoader()
// Get config file and parse to json. // Get config file and parse to json.
this.configFile = fs.readFileSync('/resources/files/config/config.json') this.configFile = this.fileLoader.getConfigFile()
this.configJson = JSON.parse(this.configFile.toString())
// Choose the template for selected document type. // Choose the template for selected document type.
switch (objectData.dokumenttyp) { switch (objectData.dokumenttyp) {
@ -53,19 +55,21 @@ class DocCreator {
// Title normalisation // Title normalisation
const replaceEszettTitle = objectData.titel.replace("ß", "-ss-"); const replaceEszettTitle = objectData.titel.replace("ß", "-ss-");
let replaceUmlauteTitle = replaceEszettTitle.replace(/[^Ä]+/ig, "Ae"); let replaceUmlauteTitle = replaceEszettTitle.replace("Ä", "Ae");
replaceUmlauteTitle = replaceUmlauteTitle.replace(/[^ä]+/ig, "ae"); replaceUmlauteTitle = replaceUmlauteTitle.replace("ä", "ae");
replaceUmlauteTitle = replaceUmlauteTitle.replace(/[^Ö]+/ig, "Oe"); replaceUmlauteTitle = replaceUmlauteTitle.replace("Ö", "Oe");
replaceUmlauteTitle = replaceUmlauteTitle.replace(/[^ö]+/ig, "oe"); replaceUmlauteTitle = replaceUmlauteTitle.replace("ö", "oe");
replaceUmlauteTitle = replaceUmlauteTitle.replace(/[^Ü]+/ig, "Ue"); replaceUmlauteTitle = replaceUmlauteTitle.replace("Ü", "Ue");
replaceUmlauteTitle = replaceUmlauteTitle.replace(/[^ü]+/ig, "ue"); replaceUmlauteTitle = replaceUmlauteTitle.replace("ü", "ue");
const normCharacterTitle = replaceSpecialCharacters(replaceUmlauteTitle); const normCharacterTitle = replaceSpecialCharacters(replaceUmlauteTitle);
const normSingleSpaceTitle = normCharacterTitle.replace("__", "_"); const normSingleSpaceTitle = normCharacterTitle.replace("__", "_");
const normSpacingTitle = normSingleSpaceTitle.replace(/[^A-Z0-9\-]+/ig, "_"); const normSpacingTitle = normSingleSpaceTitle.replace(/[^A-Z0-9\-]+/ig, "_");
this.normTitle = normSpacingTitle.slice(0, 50); this.normTitle = normSpacingTitle.slice(0, 50);
const folderName = this.normObjectId + '__' + this.normTitle const folderName = this.normObjectId + '__' + this.normTitle
this.objectPath = path.join(this.configJson.rootDir, folderName);
this.objectPath = path.join(this.configFile.rootDir, folderName);
this.documentPath = path.join(this.objectPath, this.documentInfo.documentType, objectData.datum); this.documentPath = path.join(this.objectPath, this.documentInfo.documentType, objectData.datum);
this.filename = this.normObjectId + '__' + this.normTitle + '__' + this.objectData.datum + '__' + this.objectData.dokumenttyp; this.filename = this.normObjectId + '__' + this.normTitle + '__' + this.objectData.datum + '__' + this.objectData.dokumenttyp;
this.filenameWithExtension = this.filename + '.docx' this.filenameWithExtension = this.filename + '.docx'
@ -78,13 +82,12 @@ class DocCreator {
async fillTemplate() { async fillTemplate() {
// Variables // Variables
let buffer; let buffer;
let configJson
// Create docx document if there was a response. // Create docx document if there was a response.
if (this.objectData.httpStatus === 200) { if (this.objectData.httpStatus === 200) {
try { try {
// Read template. // Read template.
const template = fs.readFileSync(path.join('/resources/files/templates/', this.documentInfo.templateFile)); const template = fs.readFileSync(path.resolve(this.fileLoader.getTemplateDir(), this.documentInfo.templateFile));
// Create report. // Create report.
buffer = await createReport({ buffer = await createReport({
@ -110,8 +113,8 @@ class DocCreator {
} }
try { try {
const createDocumentPath = await mkdir(this.documentPath, {recursive: true}); await mkdir(this.documentPath, {recursive: true});
const createTemporaryWorkDirPath = await mkdir(this.temporaryWorkDirPath, {recursive: true}); await mkdir(this.temporaryWorkDirPath, {recursive: true});
} catch (err) { } catch (err) {
// Set error log. // Set error log.
this.log = { this.log = {
@ -148,15 +151,7 @@ class DocCreator {
<mets:mets <mets:mets
xmlns:mets="http://www.loc.gov/METS/" xmlns:mets="http://www.loc.gov/METS/"
xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
xsi:schemaLocation="info:lc/xmlns/premis-v2
http://www.loc.gov/standards/premis/v2/premis-v2-0.xsd
http://www.loc.gov/mods/v3
http://www.loc.gov/standards/mods/v3/mods-3-6.xsd
http://www.loc.gov/METS/
http://www.loc.gov/standards/mets/version17/mets.v1-7.xsd
http://www.loc.gov/mix/v10
http://www.loc.gov/standards/mix/mix10/mix10.xsd">
<mets:metsHdr createDate="${this.today}"> <mets:metsHdr createDate="${this.today}">
<mets:agent <mets:agent
type="other" type="other"
@ -455,11 +450,9 @@ class DocCreator {
metModsXml = result; metModsXml = result;
} }
); );
console.log(metModsXml, 'from string');
const builder = new Builder() const builder = new Builder()
metModsXml = builder.buildObject(metModsJson); metModsXml = builder.buildObject(metModsJson);
console.log(metModsXml, 'from Json')
const fileName = `.metsMods__${this.normObjectId}__${this.normTitle}.xml` const fileName = `.metsMods__${this.normObjectId}__${this.normTitle}.xml`
fs.writeFileSync(path.join(this.documentPath,fileName),metModsXml.toString(), fs.writeFileSync(path.join(this.documentPath,fileName),metModsXml.toString(),

35
src/FileLoader.js Normal file
View file

@ -0,0 +1,35 @@
import fs from "fs";
import path from "path";
class FileLoader {
assetPath;
devAssetPath = 'src/assets';
buildAssetPath = 'resources/app/src/assets';
packedAssetPath = 'resources/files/';
getPackedStructure() {
if (fs.existsSync(this.packedAssetPath)) {
this.assetPath = this.packedAssetPath;
} else if (fs.existsSync(this.buildAssetPath)) {
this.assetPath = this.packedAssetPath;
} else {
this.assetPath = this.devAssetPath;
}
}
getConfigFile() {
this.getPackedStructure()
console.log(this.assetPath)
const ConfigFile = fs.readFileSync(path.resolve(this.assetPath, 'config/config.json'))
return JSON.parse(ConfigFile.toString())
}
getTemplateDir() {
return path.resolve(this.assetPath, 'templates');
}
}
export {FileLoader}

View file

@ -1,3 +1,3 @@
{ {
"rootDir": "/home/rbrt/Schreibtisch/boehler" "rootDir": "/home/rbrt/Schreibtisch/marvin"
} }

View file

@ -86,7 +86,7 @@ export const App = () => {
if (objectId) { if (objectId) {
// Get object data from objektkatalog.gnm.de. // Get object data from objektkatalog.gnm.de.
const [receivedObjectData, receivedVisibility] = await objektkatalogApi.getData(objectId); const receivedObjectData = await objektkatalogApi.getData(objectId);
// If no response from Objektkatalog. // If no response from Objektkatalog.
switch (receivedObjectData.httpStatus) { switch (receivedObjectData.httpStatus) {
// Server not reachable. // Server not reachable.

View file

@ -1,6 +1,6 @@
import React from "react"; import React from "react";
export const Input = ({config}) => { export const Input = ({configFile}) => {
return ( return (
<span className={'settings-div '}> {config.rootDir} </span>) <span className={'settings-div '}> {configFile.rootDir} </span>)
} }

View file

@ -1,8 +1,9 @@
// Modules // Modules
import path from "path"; import {FileLoader} from "../FileLoader";
// Config // Electron
import configImport from '/src/assets/config/config.json' const electron = window.require('electron');
const ipcRenderer = electron.ipcRenderer;
// Icons // Icons
import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIos'; import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIos';
@ -20,11 +21,17 @@ import {writeFile} from "fs";
//////////////////// ////////////////////
export default function Settings() { export default function Settings() {
// States const fileLoader = new FileLoader()
const [config, setConfig] = useState( const initialConfig = fileLoader.getConfigFile()
configImport console.log(initialConfig)
) const getConfigPath = async (path) => {
return await ipcRenderer.invoke('assetPath:getAssetPath', path)
}
// States
const [configFile, setConfigFile] = useState(
initialConfig
)
const [restart, setRestart] = useState( const [restart, setRestart] = useState(
false false
) )
@ -33,13 +40,13 @@ export default function Settings() {
async function selectFolderHandler(e) { async function selectFolderHandler(e) {
e.preventDefault() e.preventDefault()
const rootDirFromWindow = await window.openFile(); const rootDirFromWindow = await window.openFile();
setConfig((prevState) => { setConfigFile((prevState) => {
return { return {
...prevState, ...prevState,
rootDir: rootDirFromWindow rootDir: rootDirFromWindow
} }
}) })
const saveResult = await saveInputClickHandler(rootDirFromWindow) await saveInputClickHandler(rootDirFromWindow)
} }
// Handler // Handler
@ -48,9 +55,9 @@ export default function Settings() {
rootDir: rootDirFromWindow rootDir: rootDirFromWindow
} }
if (rootDirFromWindow) { if (rootDirFromWindow) {
console.log(__dirname);
let message; let message;
await writeFile('/resources/files/config/config.json', JSON.stringify(config2Safe, null, 2), (err) => { const configPath = await getConfigPath('config/config.json')
await writeFile(configPath, JSON.stringify(config2Safe, null, 2), (err) => {
if (err) { if (err) {
message = err; message = err;
} else { } else {
@ -59,6 +66,7 @@ export default function Settings() {
return message return message
}) })
setRestart(true) setRestart(true)
return restart;
} }
} }
@ -76,7 +84,7 @@ export default function Settings() {
Hauptverzeichnis Hauptverzeichnis
</label> </label>
<div className="align-items-center flex"> <div className="align-items-center flex">
<Input config={config} setConfig={setConfig}/> <Input configFile={configFile}/>
<button type="submit" className="edit-button text-end"> <button type="submit" className="edit-button text-end">
<i className="fas fa-edit d-block"> <i className="fas fa-edit d-block">
<EditIcon sx={{fontSize: 16}} color={'#d5d5d5'}/> <EditIcon sx={{fontSize: 16}} color={'#d5d5d5'}/>