solved timeout error via fetch response
This commit is contained in:
parent
ba9d9e6abb
commit
1d68336a06
9 changed files with 246 additions and 110 deletions
1
main.js
1
main.js
|
|
@ -44,6 +44,7 @@ function createWindow() {
|
|||
mainWindow = new BrowserWindow({
|
||||
width: 400,
|
||||
height: 600,
|
||||
icon: __dirname + '/marvin.ico',
|
||||
show: false,
|
||||
webPreferences: {
|
||||
preload: path.join(__dirname, 'preload.js'),
|
||||
|
|
|
|||
BIN
marvin.ico
Normal file
BIN
marvin.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 41 KiB |
|
|
@ -1,3 +1,3 @@
|
|||
{
|
||||
"rootDir": "/home/rbrt/Schreibtisch"
|
||||
"rootDir": "/home/rbrt/Schreibtisch/marvin"
|
||||
}
|
||||
|
|
@ -1,5 +1,3 @@
|
|||
|
||||
|
||||
// Modules
|
||||
import createReport from 'docx-templates';
|
||||
import fs from 'fs';
|
||||
|
|
@ -7,23 +5,49 @@ import { mkdir } from 'node:fs/promises';
|
|||
import path from 'path';
|
||||
import replaceSpecialCharacters from "replace-special-characters";
|
||||
|
||||
// Components
|
||||
import ObjektkatalogApi from './ObjektkatalogApi';
|
||||
|
||||
////////////////////
|
||||
// Main //
|
||||
////////////////////
|
||||
|
||||
// Fills the docx template.
|
||||
export async function fillTemplate(log, objectData) {
|
||||
// Variables
|
||||
let buffer;
|
||||
let configJson
|
||||
// Create docx document.
|
||||
|
||||
// Create docx document if there was a response.
|
||||
if (objectData.httpStatus === 200) {
|
||||
let documentInfo;
|
||||
try {
|
||||
// Load config file.
|
||||
let ConfigFile = fs.readFileSync('resources/config/config.json')
|
||||
configJson = JSON.parse(ConfigFile)
|
||||
|
||||
// Choose the template for selected document type.
|
||||
switch (objectData.dokumenttyp) {
|
||||
case 'rp':
|
||||
documentInfo = {
|
||||
documentType: 'restaurierungsprotokolle',
|
||||
templateFile: 'rp-template.docx',
|
||||
}
|
||||
break;
|
||||
case 'lbb':
|
||||
documentInfo = {
|
||||
documentType: 'leihgabenbegleitblaetter',
|
||||
templateFile: 'lbb-template.docx',
|
||||
}
|
||||
break;
|
||||
case 'a':
|
||||
documentInfo = {
|
||||
documentType: 'analysen',
|
||||
templateFile: 'a-template.docx',
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Read template.
|
||||
const template = fs.readFileSync('resources/templates/rp-template.docx');
|
||||
const template = fs.readFileSync(path.join('resources/templates/', documentInfo.templateFile));
|
||||
|
||||
// Create report.
|
||||
buffer = await createReport({
|
||||
template,
|
||||
|
|
@ -38,32 +62,40 @@ export async function fillTemplate(log, objectData) {
|
|||
}
|
||||
});
|
||||
} catch (err) {
|
||||
// Set error log.
|
||||
log = {
|
||||
...log,
|
||||
status: 'red',
|
||||
message: 'Konnte Template nicht erstellen: ' + err,
|
||||
tip: 'Ist das Template vorhanden?',
|
||||
};
|
||||
return log
|
||||
}
|
||||
const folderPath = path.join(configJson.rootDir, objectData.inventarnummer);
|
||||
// Create Folder if necessary.
|
||||
|
||||
// Create folder (if necessary).
|
||||
const objectPath = path.join(configJson.rootDir, objectData.inventarnummer);
|
||||
const documentPath = path.join(objectPath, documentInfo.documentType);
|
||||
const temporaryWorkDirPath = path.join(objectPath, 'werkstatt');
|
||||
try {
|
||||
const createDir = await mkdir(folderPath, {recursive: true});
|
||||
const createDocumentPath = await mkdir(documentPath, {recursive: true});
|
||||
const createTemporaryWorkDirPath = await mkdir(temporaryWorkDirPath, {recursive: true});
|
||||
} catch (err) {
|
||||
// Set error log.
|
||||
log = {
|
||||
...log,
|
||||
status: 'red',
|
||||
message: 'Konnte den Pfad nicht erstellen' + err,
|
||||
tip: 'Bestehen Schreibrechte auf dem Ordner?'
|
||||
}
|
||||
return log
|
||||
}
|
||||
// Write document to disk.
|
||||
|
||||
// Write document to disk.
|
||||
if (buffer) {
|
||||
const normCharacterTitle = replaceSpecialCharacters(objectData.titel)
|
||||
const normSpacingTitle = normCharacterTitle.replace(/[^A-Z0-9]+/ig, "_");
|
||||
const filename = objectData.datum + '_' + normSpacingTitle + '.docx'
|
||||
fs.writeFileSync(path.join(folderPath, filename), buffer)
|
||||
fs.writeFileSync(path.join(documentPath, filename), buffer)
|
||||
log = {
|
||||
...log,
|
||||
status: 'green',
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
const {parseString} = require("xml2js");
|
||||
|
||||
/*
|
||||
* Sends Object ID to Objektkatalog-API and receives JSON
|
||||
* Properties and functions for communication with Objektkatalog-API.
|
||||
*/
|
||||
class ObjektkatalogApi {
|
||||
|
||||
// Variables
|
||||
json;
|
||||
raw;
|
||||
receivedData = {
|
||||
|
|
@ -17,15 +19,33 @@ class ObjektkatalogApi {
|
|||
materialTechnik: '',
|
||||
titel: '',
|
||||
};
|
||||
|
||||
response;
|
||||
visibility;
|
||||
|
||||
|
||||
// Get data from objektkatalog.gnm.de.
|
||||
async getData(objectId) {
|
||||
if (objectId) {
|
||||
const response = await fetch('https://objektkatalog.gnm.de/rest_export/' + objectId);
|
||||
if (response.status === 200) {
|
||||
const responseJson = await response.json(); //extract JSON from the http response
|
||||
// RESTful GET.
|
||||
this.response = await fetch('https://objektkatalog.gnm.de/rest_export/' + objectId).then((response) => {
|
||||
if (response.status >= 400 && response.status < 600) {
|
||||
throw new Error("Bad response from server: " + response.status);
|
||||
}
|
||||
return response;
|
||||
}).then((returnedResponse) => {
|
||||
// Everything went well.
|
||||
return returnedResponse
|
||||
}).catch((error) => {
|
||||
// Error while fetch.
|
||||
return {status: 503};
|
||||
});
|
||||
|
||||
switch (this.response.status) {
|
||||
case 200:
|
||||
// Parse to json.
|
||||
const responseJson = await this.response.json(); //extract JSON from the http response
|
||||
if (responseJson.length !== 0) {
|
||||
// Json with raw data (LIDO inside!)
|
||||
this.raw = {
|
||||
eid: responseJson[0]['eid'],
|
||||
allgemeineBezeichnung: responseJson[0]['fc6392714594e73ddb2fa363815a8fdf'],
|
||||
|
|
@ -53,8 +73,9 @@ class ObjektkatalogApi {
|
|||
vitrinentext: responseJson[0]['fe5e3ff18aedf1d25c639dc79fb24ad1'],
|
||||
zustandsbeschreibung: responseJson[0]['f54b6da6006ea444c33a348b8c4370a8']
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
// No JSON
|
||||
// No json, no data form.
|
||||
this.receivedData = {
|
||||
...this.receivedData,
|
||||
httpStatus: 404,
|
||||
|
|
@ -62,17 +83,33 @@ class ObjektkatalogApi {
|
|||
this.visibility = false
|
||||
return [this.receivedData, this.visibility]
|
||||
}
|
||||
} else {
|
||||
// No response
|
||||
case 408:
|
||||
// No response, no data form.
|
||||
this.receivedData = {
|
||||
...this.receivedData,
|
||||
httpStatus: 404,
|
||||
httpStatus: 408,
|
||||
}
|
||||
this.visibility = false
|
||||
return [this.receivedData, this.visibility]
|
||||
case 503:
|
||||
// Objektkatalog not reachable.
|
||||
this.receivedData = {
|
||||
...this.receivedData,
|
||||
httpStatus: 503,
|
||||
}
|
||||
this.visibility = false
|
||||
return [this.receivedData, this.visibility]
|
||||
default:
|
||||
// Any other error
|
||||
this.receivedData = {
|
||||
...this.receivedData,
|
||||
httpStatus: 500,
|
||||
}
|
||||
this.visibility = false
|
||||
return [this.receivedData, this.visibility]
|
||||
}
|
||||
} else {
|
||||
// No ObjectId
|
||||
// No ObjectId, no data form.
|
||||
this.receivedData = {
|
||||
...this.receivedData,
|
||||
httpStatus: 500,
|
||||
|
|
@ -84,7 +121,8 @@ class ObjektkatalogApi {
|
|||
// Datum
|
||||
// Default date of today
|
||||
let today = new Date()
|
||||
let todayFormat = today.getFullYear() + '-' + (String(today.getMonth() + 1).padStart(2, '0')) + '-' + String(today.getDate()).padStart(2, '0'); ;
|
||||
let todayFormat = today.getFullYear() + '-' + (String(today.getMonth() + 1).padStart(2, '0')) + '-' + String(today.getDate()).padStart(2, '0');
|
||||
;
|
||||
|
||||
// Inventarnummer
|
||||
let inventarnummer;
|
||||
|
|
@ -102,7 +140,7 @@ class ObjektkatalogApi {
|
|||
titel = 'unbekannt';
|
||||
}
|
||||
|
||||
// Hersteller
|
||||
// Hersteller (LIDO format!)
|
||||
let herstellerArray = [];
|
||||
let hersteller;
|
||||
|
||||
|
|
@ -141,7 +179,7 @@ class ObjektkatalogApi {
|
|||
materialTechnik = 'unbekannt';
|
||||
}
|
||||
|
||||
// Maße
|
||||
// Maße (LIDO format!)
|
||||
let masse;
|
||||
if (this.raw.masse.length !== 0) {
|
||||
parseString(this.raw.masse[0].value, (err, result) => {
|
||||
|
|
@ -149,6 +187,7 @@ class ObjektkatalogApi {
|
|||
})
|
||||
}
|
||||
|
||||
// Json with important data.
|
||||
this.receivedData = {
|
||||
...this.receivedData,
|
||||
datum: todayFormat,
|
||||
|
|
|
|||
|
|
@ -167,6 +167,7 @@ label {
|
|||
|
||||
.open {
|
||||
height: 550px;
|
||||
overflow: hidden;
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ export const App = () => {
|
|||
const [objectData, setObjectData] = useState(
|
||||
{
|
||||
datum: '',
|
||||
dokumenttyp: '',
|
||||
hersteller: '',
|
||||
herstellungsdatum: '',
|
||||
herstellungsort: '',
|
||||
|
|
@ -57,64 +58,110 @@ export const App = () => {
|
|||
);
|
||||
|
||||
// Handler
|
||||
|
||||
// Get userinput from main form, ask Objektkatalog API for Data and fill check up form.
|
||||
const getDataAndAskForCheckUpClickHandler = async (e) => {
|
||||
// Show loading widget.
|
||||
setIsLoading(true)
|
||||
|
||||
// Prevent page reload.
|
||||
e.preventDefault()
|
||||
let objectId = ''
|
||||
objectId = e.target.form.objectId.value
|
||||
// Get objectId from user input.
|
||||
|
||||
// Get objectId and document type from user input.
|
||||
let objectId = e.target.form.objectId.value
|
||||
let documentType = e.target.form.documentType.value
|
||||
|
||||
// Set object state.
|
||||
await setObjectData((prevState) => {
|
||||
return {
|
||||
...prevState,
|
||||
inventarnummer: objectId,
|
||||
dokumenttyp: documentType,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
if (objectId) {
|
||||
// Get object data from objektkatalog.gnm.de
|
||||
// Get object data from objektkatalog.gnm.de.
|
||||
const [receivedObjectData, receivedVisibility] = await objektkatalogApi.getData(objectId);
|
||||
if (receivedObjectData.httpStatus !== 200) {
|
||||
// If no response from Objektkatalog.
|
||||
switch (receivedObjectData.httpStatus) {
|
||||
// Server not reachable.
|
||||
case 503:
|
||||
await setLogState({
|
||||
log: {
|
||||
status: 'red',
|
||||
message: 'Kein Objekt mit dieser Inventarnummer gefunden!',
|
||||
code: '',
|
||||
tip: '',
|
||||
message: 'Objektkatalog nicht erreichbar!',
|
||||
code: '503',
|
||||
tip: 'Sind sie mit dem Internet verbunden und ist der Objektkatalog online?',
|
||||
}, // with message, code, tip
|
||||
logClass: 'active'
|
||||
})
|
||||
await setCheckUpVisibility(false)
|
||||
} else {
|
||||
// Fill and open check up form
|
||||
await setObjectData(receivedObjectData)
|
||||
// Hide Loading
|
||||
setIsLoading(false)
|
||||
return;
|
||||
case 200:
|
||||
// Fill and open check up form.
|
||||
await setObjectData(prevState => {
|
||||
return {
|
||||
...prevState,
|
||||
...receivedObjectData
|
||||
}
|
||||
})
|
||||
// Show check up form.
|
||||
await setCheckUpVisibility(true)
|
||||
|
||||
// Set success log but hide.
|
||||
await setLogState({
|
||||
log: {
|
||||
status: '',
|
||||
message: '',
|
||||
code: '',
|
||||
tip: '',
|
||||
}, // with message, code, tip
|
||||
},
|
||||
logClass: 'inactive'
|
||||
})
|
||||
break;
|
||||
default:
|
||||
// Set error log state.
|
||||
await setLogState({
|
||||
log: {
|
||||
status: 'red',
|
||||
message: 'Kein Objekt mit dieser Inventarnummer gefunden!',
|
||||
code: '',
|
||||
tip: 'Groß-/Kleinschreibung beachten und keine Leerzeichen verwenden!',
|
||||
}, // with message, code, tip
|
||||
logClass: 'active'
|
||||
})
|
||||
// Hide Loading
|
||||
setIsLoading(false)
|
||||
// Hide check up form.
|
||||
await setCheckUpVisibility(false)
|
||||
|
||||
}
|
||||
} else {
|
||||
// Set error log.
|
||||
await setLogState({
|
||||
log: {
|
||||
status: 'red',
|
||||
message: 'Bitte Inventarnummer eingeben!',
|
||||
code: '',
|
||||
tip: '',
|
||||
}, // with message, code, tip
|
||||
},
|
||||
logClass: 'active'
|
||||
})
|
||||
// Hide check up form.
|
||||
await setCheckUpVisibility(false)
|
||||
}
|
||||
// Hide loading widget.
|
||||
setIsLoading(false)
|
||||
}
|
||||
// Component with
|
||||
// * Navigation (Nav) *
|
||||
// * Main form (this)*
|
||||
// * Loading widget (LoadingIcon)*
|
||||
// * Checkup form (DataForm)*
|
||||
// * Log (Log)*
|
||||
|
||||
return (
|
||||
<div className="App">
|
||||
|
|
@ -128,10 +175,10 @@ export const App = () => {
|
|||
<form id={"object-id-form"} className={"flex-wrap"}>
|
||||
<div className={"center column flex justify-content-space-between "}>
|
||||
<label htmlFor="document-type" className={"center cut v-distance"}>Dokumenttyp:</label>
|
||||
<select name="document-type" id="document-type" className={"input-field center cut"}>
|
||||
<option value="restaurierungsprotokoll">Restaurierungsprotokoll</option>
|
||||
<option value="leihgabenbegleitblatt">Leihgabenbegleitblatt</option>
|
||||
<option value="analyse">Analyse</option>
|
||||
<select name="documentType" id="document-type" className={"input-field center cut"}>
|
||||
<option value="rp">Restaurierungsprotokoll</option>
|
||||
<option value="lbb">Leihgabenbegleitblatt</option>
|
||||
<option value="a">Analyse</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className={"center column flex full justify-content-space-between"}>
|
||||
|
|
|
|||
|
|
@ -8,10 +8,17 @@ import React from 'react'
|
|||
// Main //
|
||||
////////////////////
|
||||
|
||||
|
||||
// Renders check up form and gives the possibility to change received values.
|
||||
export const DataForm = ({checkUpVisibility, objectData, setObjectData, logState, setLogState}) => {
|
||||
|
||||
// Variables
|
||||
let log;
|
||||
|
||||
// Handlers
|
||||
// Change handler response to every keystroke!
|
||||
|
||||
// Change date.
|
||||
const datumChangeHandler = (e) => {
|
||||
setObjectData((prevState) => {
|
||||
return {
|
||||
|
|
@ -20,7 +27,7 @@ export const DataForm = ({checkUpVisibility, objectData, setObjectData, logState
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Change identifier.
|
||||
const inventarnummerChangeHandler = (e) => {
|
||||
setObjectData((prevState) => {
|
||||
return {
|
||||
|
|
@ -29,7 +36,7 @@ export const DataForm = ({checkUpVisibility, objectData, setObjectData, logState
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Change title.
|
||||
const titelChangeHandler = (e) => {
|
||||
setObjectData((prevState) => {
|
||||
return {
|
||||
|
|
@ -39,6 +46,7 @@ export const DataForm = ({checkUpVisibility, objectData, setObjectData, logState
|
|||
})
|
||||
}
|
||||
|
||||
// Change creator.
|
||||
const herstellerChangeHandler = (e) => {
|
||||
setObjectData((prevState) => {
|
||||
return {
|
||||
|
|
@ -47,7 +55,7 @@ export const DataForm = ({checkUpVisibility, objectData, setObjectData, logState
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Change creation place.
|
||||
const herstellungsortChangeHandler = (e) => {
|
||||
setObjectData((prevState) => {
|
||||
return {
|
||||
|
|
@ -57,6 +65,7 @@ export const DataForm = ({checkUpVisibility, objectData, setObjectData, logState
|
|||
})
|
||||
}
|
||||
|
||||
// Change creation date.
|
||||
const herstellungsdatumChangeHandler = (e) => {
|
||||
setObjectData((prevState) => {
|
||||
return {
|
||||
|
|
@ -66,6 +75,7 @@ export const DataForm = ({checkUpVisibility, objectData, setObjectData, logState
|
|||
})
|
||||
}
|
||||
|
||||
// Change material and technic.
|
||||
const materialTechnikChangeHandler = (e) => {
|
||||
setObjectData((prevState) => {
|
||||
return {
|
||||
|
|
@ -75,6 +85,7 @@ export const DataForm = ({checkUpVisibility, objectData, setObjectData, logState
|
|||
})
|
||||
}
|
||||
|
||||
// Change sizes.
|
||||
const masseChangeHandler = (e) => {
|
||||
setObjectData((prevState) => {
|
||||
return {
|
||||
|
|
@ -84,6 +95,7 @@ export const DataForm = ({checkUpVisibility, objectData, setObjectData, logState
|
|||
})
|
||||
}
|
||||
|
||||
// Fill the template and save it.
|
||||
const fillTemplateClickHandler = async (e) => {
|
||||
e.preventDefault();
|
||||
log = await fillTemplate(logState, objectData);
|
||||
|
|
@ -94,6 +106,7 @@ export const DataForm = ({checkUpVisibility, objectData, setObjectData, logState
|
|||
});
|
||||
}
|
||||
|
||||
// Renders data form
|
||||
return (<div className={'checkup ' + (checkUpVisibility ? 'open' : 'closed')}>
|
||||
<form className={'flex column '}>
|
||||
<div >
|
||||
|
|
|
|||
|
|
@ -42,11 +42,14 @@ module.exports = {
|
|||
],
|
||||
devtool: 'cheap-source-map',
|
||||
devServer: {
|
||||
static: path.resolve(__dirname, 'dist'),
|
||||
// Tell the server where to serve the content from.
|
||||
static: {
|
||||
directory: path.resolve(__dirname, 'dist'),
|
||||
},
|
||||
onBeforeSetupMiddleware() {
|
||||
spawn(
|
||||
'electron',
|
||||
['.'],
|
||||
['--trace-warnings .'],
|
||||
{ shell: true, env: process.env, stdio: 'inherit' }
|
||||
)
|
||||
.on('close', code => process.exit(0))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue