implemented xml file selection/save logic
parent
43ba287b5e
commit
44181748d6
|
|
@ -156,6 +156,8 @@ function build(previousFileSizes) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function copyPublicFolder() {
|
function copyPublicFolder() {
|
||||||
|
fs.emptyDirSync(paths.appBuild);
|
||||||
|
fs.ensureSymlink(paths.appPng,path.resolve(paths.appBuild,'png'));
|
||||||
fs.copySync(paths.appPublic, paths.appBuild, {
|
fs.copySync(paths.appPublic, paths.appBuild, {
|
||||||
dereference: true,
|
dereference: true,
|
||||||
filter: file => file !== paths.appHtml && file !== paths.appPng,
|
filter: file => file !== paths.appHtml && file !== paths.appPng,
|
||||||
|
|
@ -167,10 +169,9 @@ function copyPublicFolder() {
|
||||||
function startWebPackDevServer(pyServer){
|
function startWebPackDevServer(pyServer){
|
||||||
const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000;
|
const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000;
|
||||||
const HOST = process.env.HOST || '0.0.0.0';
|
const HOST = process.env.HOST || '0.0.0.0';
|
||||||
// fs.emptyDirSync(paths.appBuild);
|
|
||||||
// fs.ensureSymlink(paths.appPng,path.resolve(paths.appBuild,'png'));
|
|
||||||
// // Merge with the public folder
|
// // Merge with the public folder
|
||||||
// copyPublicFolder();
|
copyPublicFolder();
|
||||||
|
|
||||||
// We attempt to use the default port but if it is busy, we offer the user to
|
// We attempt to use the default port but if it is busy, we offer the user to
|
||||||
// run on a different port. `detect()` Promise resolves to the next free port.
|
// run on a different port. `detect()` Promise resolves to the next free port.
|
||||||
|
|
|
||||||
147
src/LexSetup.tsx
147
src/LexSetup.tsx
|
|
@ -1,77 +1,76 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {
|
import {
|
||||||
Dimmer, Loader, Header, Icon, Segment, Button
|
Dimmer, Loader, Header, Icon, Segment, Button, Dropdown
|
||||||
} from 'semantic-ui-react';
|
} from 'semantic-ui-react';
|
||||||
import * as XML from 'xml2js';
|
import * as XML from 'xml2js';
|
||||||
// import * as _ from 'lodash';
|
|
||||||
import { xmlToEntries } from './LexAccessors';
|
import { xmlToEntries } from './LexAccessors';
|
||||||
import { LexEditor } from './LexEditor';
|
import { LexEditor } from './LexEditor';
|
||||||
|
|
||||||
export class LexSetup extends React.Component<any, any> {
|
export class LexSetup extends React.Component<any, any> {
|
||||||
xmlBuilder = new XML.Builder();
|
xmlBuilder = new XML.Builder();
|
||||||
fileName = 'new_es_orig.xml';
|
|
||||||
constructor(props: any) {
|
constructor(props: any) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = { xmlLoaded: false, dirty: false };
|
this.state = {
|
||||||
|
xmlLoaded: false, dirty: false, xmlFiles: [], xmlFileName: 'new_es.xml'
|
||||||
|
};
|
||||||
}
|
}
|
||||||
public componentDidMount() {
|
public componentDidMount() {
|
||||||
fetch(this.fileName)
|
this.getXMLFiles();
|
||||||
.then((response) => response.text())
|
this.loadXML();
|
||||||
.then((xmlString) => {
|
|
||||||
XML.parseString(xmlString, (err, xmlData) => {
|
|
||||||
// let props = this.props;
|
|
||||||
// _.noop(props);
|
|
||||||
this.props.addXmlData(xmlData);
|
|
||||||
this.setState({ xmlLoaded: true });
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch((e) => {
|
|
||||||
console.log('errored :', e);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
let files: string[] = [].concat(this.state.xmlFiles);
|
||||||
|
if (files.indexOf(this.state.xmlFileName as string) === -1) {
|
||||||
|
files.push(this.state.xmlFileName);
|
||||||
|
}
|
||||||
|
let dropOptions = files.map((k: any, i: any, c: any) => {
|
||||||
|
return { key: i, value: k, text: k };
|
||||||
|
});
|
||||||
|
let selectFile = (
|
||||||
|
<Dropdown
|
||||||
|
options={dropOptions}
|
||||||
|
onChange={(e, d) => {
|
||||||
|
this.setState({ xmlFileName: d.value as string });
|
||||||
|
}}
|
||||||
|
onAddItem={(e, d) => {
|
||||||
|
this.setState({ xmlFileName: d.value as string });
|
||||||
|
}}
|
||||||
|
value={this.state.xmlFileName}
|
||||||
|
compact={true}
|
||||||
|
selection={true}
|
||||||
|
search={true}
|
||||||
|
allowAdditions={true}
|
||||||
|
style={{
|
||||||
|
width: '10em', float: 'right',
|
||||||
|
['min-height']: '0.3em', 'padding': '0.5em'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
let saveButton = this.state.dirty ?
|
||||||
|
(
|
||||||
|
<Button floated="right" size="mini" onClick={() => { this.saveXML(); }}>
|
||||||
|
Save
|
||||||
|
</Button>
|
||||||
|
) : null;
|
||||||
|
let loadButton = (
|
||||||
|
<Button floated="right" size="mini" onClick={() => { this.loadXML(); }}>
|
||||||
|
Load
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
let xmlEntries = xmlToEntries(this.props.xmlData);
|
||||||
let dimmer = (
|
let dimmer = (
|
||||||
<Dimmer active={true} inverted={true}>
|
<Dimmer active={true} inverted={true}>
|
||||||
<Loader inverted={true}>Loading</Loader>
|
<Loader inverted={true}>Loading</Loader>
|
||||||
</Dimmer>
|
</Dimmer>
|
||||||
);
|
);
|
||||||
let saveXMLBackend = (ev: any, d: any) => {
|
|
||||||
// this.setState({ xmlLoaded: false });
|
|
||||||
let xmlText = this.xmlBuilder.buildObject(this.props.xmlData);
|
|
||||||
let data = new FormData();
|
|
||||||
data.append('file', xmlText);
|
|
||||||
data.append('name', 'new_es_s.xml'); // this.fileName
|
|
||||||
fetch('/api/save', {
|
|
||||||
method: 'POST',
|
|
||||||
body: data
|
|
||||||
})
|
|
||||||
.then((response) => response.text())
|
|
||||||
.then((rsptext) => {
|
|
||||||
console.log('response', rsptext);
|
|
||||||
this.setState({ dirty: false });
|
|
||||||
})
|
|
||||||
.catch((e) => {
|
|
||||||
// console.log('errored :', e);
|
|
||||||
this.setState({ dirty: true });
|
|
||||||
});
|
|
||||||
};
|
|
||||||
let saveButton = this.state.dirty ?
|
|
||||||
(
|
|
||||||
<Button floated="right" size="mini" onClick={saveXMLBackend}>
|
|
||||||
Save
|
|
||||||
</Button>
|
|
||||||
) : null;
|
|
||||||
let xmlEntries = xmlToEntries(this.props.xmlData);
|
|
||||||
// _.noop(saveXMLBackend);
|
|
||||||
let markDirty = () => {
|
|
||||||
this.setState({ dirty: true });
|
|
||||||
};
|
|
||||||
let editor = (
|
let editor = (
|
||||||
<div>
|
<div>
|
||||||
<Segment inverted={true} size="tiny" attached={true}>
|
<Segment inverted={true} size="tiny" attached={true}>
|
||||||
<Header color="teal" size="mini">
|
<Header color="teal" size="mini">
|
||||||
{saveButton}
|
{saveButton}
|
||||||
|
{loadButton}
|
||||||
|
{selectFile}
|
||||||
<Icon name="edit" size="small" />
|
<Icon name="edit" size="small" />
|
||||||
<Header.Content>
|
<Header.Content>
|
||||||
Freespeech Lexicon Editor
|
Freespeech Lexicon Editor
|
||||||
|
|
@ -81,10 +80,60 @@ export class LexSetup extends React.Component<any, any> {
|
||||||
<LexEditor
|
<LexEditor
|
||||||
{...xmlEntries}
|
{...xmlEntries}
|
||||||
{...this.props}
|
{...this.props}
|
||||||
markDirty={markDirty}
|
markDirty={() => {
|
||||||
|
this.setState({ dirty: true });
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
return this.state.xmlLoaded ? editor : dimmer;
|
return this.state.xmlLoaded ? editor : dimmer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private loadXML() {
|
||||||
|
this.setState({ xmlLoaded: false });
|
||||||
|
fetch(this.state.xmlFileName)
|
||||||
|
.then((response) => response.text())
|
||||||
|
.then((xmlString) => {
|
||||||
|
XML.parseString(xmlString, (err, xmlData) => {
|
||||||
|
this.props.addXmlData(xmlData);
|
||||||
|
this.setState({ xmlLoaded: true });
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
console.log('errored :', e);
|
||||||
|
this.props.addXmlData({});
|
||||||
|
this.setState({ xmlLoaded: true });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private getXMLFiles() {
|
||||||
|
fetch('api/xmlfiles')
|
||||||
|
.then((response) => response.text())
|
||||||
|
.then((jsonStr) => {
|
||||||
|
let xmlFiles = JSON.parse(jsonStr);
|
||||||
|
this.setState({ xmlFiles });
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
console.log('errored :', e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private saveXML() {
|
||||||
|
let xmlText = this.xmlBuilder.buildObject(this.props.xmlData);
|
||||||
|
let data = new FormData();
|
||||||
|
data.append('file', xmlText);
|
||||||
|
data.append('name', this.state.xmlFileName);
|
||||||
|
fetch('/api/save', {
|
||||||
|
method: 'POST',
|
||||||
|
body: data
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (response.status === 200) {
|
||||||
|
this.setState({ dirty: false });
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
this.setState({ dirty: true });
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,9 @@ from freespeech_walle.get_morph_rule import get_morph
|
||||||
# from freespeech_walle.wizard_helpers import get_morph_rule,get_frequency
|
# from freespeech_walle.wizard_helpers import get_morph_rule,get_frequency
|
||||||
import json
|
import json
|
||||||
import codecs
|
import codecs
|
||||||
|
import glob
|
||||||
|
import os
|
||||||
|
xmlDir = 'public/'
|
||||||
# from flask_cors import CORS, cross_origin
|
# from flask_cors import CORS, cross_origin
|
||||||
# CORS(app)
|
# CORS(app)
|
||||||
|
|
||||||
|
|
@ -28,10 +31,16 @@ def walle_save():
|
||||||
xmlData = request.form.get('file',None);
|
xmlData = request.form.get('file',None);
|
||||||
xmlFileName = request.form.get('name','new_es_saved.xml');
|
xmlFileName = request.form.get('name','new_es_saved.xml');
|
||||||
if xmlData:
|
if xmlData:
|
||||||
with codecs.open('build/'+xmlFileName,'wb','utf-8') as xmlF:
|
with codecs.open(xmlDir+xmlFileName,'wb','utf-8') as xmlF:
|
||||||
|
print("saved as ",xmlFileName)
|
||||||
xmlF.write(xmlData);
|
xmlF.write(xmlData);
|
||||||
return 'ok'
|
return 'ok'
|
||||||
|
|
||||||
|
@app.route('/api/xmlfiles')
|
||||||
|
def walle_xmlfiles():
|
||||||
|
xml_files = map(os.path.basename,glob.glob(xmlDir+'*.xml'))
|
||||||
|
return json.dumps(xml_files)
|
||||||
|
|
||||||
# hmr streaming
|
# hmr streaming
|
||||||
# import requests
|
# import requests
|
||||||
# from flask import Response,stream_with_context
|
# from flask import Response,stream_with_context
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue