implemented xml file selection/save logic
parent
43ba287b5e
commit
44181748d6
|
|
@ -156,6 +156,8 @@ function build(previousFileSizes) {
|
|||
}
|
||||
|
||||
function copyPublicFolder() {
|
||||
fs.emptyDirSync(paths.appBuild);
|
||||
fs.ensureSymlink(paths.appPng,path.resolve(paths.appBuild,'png'));
|
||||
fs.copySync(paths.appPublic, paths.appBuild, {
|
||||
dereference: true,
|
||||
filter: file => file !== paths.appHtml && file !== paths.appPng,
|
||||
|
|
@ -167,10 +169,9 @@ function copyPublicFolder() {
|
|||
function startWebPackDevServer(pyServer){
|
||||
const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000;
|
||||
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
|
||||
// copyPublicFolder();
|
||||
copyPublicFolder();
|
||||
|
||||
// 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.
|
||||
|
|
|
|||
147
src/LexSetup.tsx
147
src/LexSetup.tsx
|
|
@ -1,77 +1,76 @@
|
|||
import * as React from 'react';
|
||||
import {
|
||||
Dimmer, Loader, Header, Icon, Segment, Button
|
||||
Dimmer, Loader, Header, Icon, Segment, Button, Dropdown
|
||||
} from 'semantic-ui-react';
|
||||
import * as XML from 'xml2js';
|
||||
// import * as _ from 'lodash';
|
||||
import { xmlToEntries } from './LexAccessors';
|
||||
import { LexEditor } from './LexEditor';
|
||||
|
||||
export class LexSetup extends React.Component<any, any> {
|
||||
xmlBuilder = new XML.Builder();
|
||||
fileName = 'new_es_orig.xml';
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
this.state = { xmlLoaded: false, dirty: false };
|
||||
this.state = {
|
||||
xmlLoaded: false, dirty: false, xmlFiles: [], xmlFileName: 'new_es.xml'
|
||||
};
|
||||
}
|
||||
public componentDidMount() {
|
||||
fetch(this.fileName)
|
||||
.then((response) => response.text())
|
||||
.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);
|
||||
});
|
||||
this.getXMLFiles();
|
||||
this.loadXML();
|
||||
}
|
||||
|
||||
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 = (
|
||||
<Dimmer active={true} inverted={true}>
|
||||
<Loader inverted={true}>Loading</Loader>
|
||||
</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 = (
|
||||
<div>
|
||||
<Segment inverted={true} size="tiny" attached={true}>
|
||||
<Header color="teal" size="mini">
|
||||
{saveButton}
|
||||
{loadButton}
|
||||
{selectFile}
|
||||
<Icon name="edit" size="small" />
|
||||
<Header.Content>
|
||||
Freespeech Lexicon Editor
|
||||
|
|
@ -81,10 +80,60 @@ export class LexSetup extends React.Component<any, any> {
|
|||
<LexEditor
|
||||
{...xmlEntries}
|
||||
{...this.props}
|
||||
markDirty={markDirty}
|
||||
markDirty={() => {
|
||||
this.setState({ dirty: true });
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
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
|
||||
import json
|
||||
import codecs
|
||||
import glob
|
||||
import os
|
||||
xmlDir = 'public/'
|
||||
# from flask_cors import CORS, cross_origin
|
||||
# CORS(app)
|
||||
|
||||
|
|
@ -28,10 +31,16 @@ def walle_save():
|
|||
xmlData = request.form.get('file',None);
|
||||
xmlFileName = request.form.get('name','new_es_saved.xml');
|
||||
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);
|
||||
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
|
||||
# import requests
|
||||
# from flask import Response,stream_with_context
|
||||
|
|
|
|||
Loading…
Reference in New Issue