From 44181748d68da12b8800175332a684fb5023cefa Mon Sep 17 00:00:00 2001 From: Malar Kannan Date: Sat, 29 Jul 2017 13:50:51 +0530 Subject: [PATCH] implemented xml file selection/save logic --- scripts/flask.js | 7 ++- src/LexSetup.tsx | 147 +++++++++++++++++++++++++++++++---------------- walle_server.py | 11 +++- 3 files changed, 112 insertions(+), 53 deletions(-) diff --git a/scripts/flask.js b/scripts/flask.js index b8bdedb..a1eb03d 100644 --- a/scripts/flask.js +++ b/scripts/flask.js @@ -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. diff --git a/src/LexSetup.tsx b/src/LexSetup.tsx index 17bd554..6282cbf 100644 --- a/src/LexSetup.tsx +++ b/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 { 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 = ( + { + 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 ? + ( + + ) : null; + let loadButton = ( + + ); + let xmlEntries = xmlToEntries(this.props.xmlData); let dimmer = ( Loading ); - 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 ? - ( - - ) : null; - let xmlEntries = xmlToEntries(this.props.xmlData); - // _.noop(saveXMLBackend); - let markDirty = () => { - this.setState({ dirty: true }); - }; let editor = (
{saveButton} + {loadButton} + {selectFile} Freespeech Lexicon Editor @@ -81,10 +80,60 @@ export class LexSetup extends React.Component { { + this.setState({ dirty: true }); + }} />
); 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 }); + }); + } } diff --git a/walle_server.py b/walle_server.py index b48b7f6..c2b94c3 100644 --- a/walle_server.py +++ b/walle_server.py @@ -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