1. refactored to use get/set instead of raw lens
2. updated webpack dev config to use python proxy api servermaster
parent
3cc73e5404
commit
c6c8655649
|
|
@ -17,6 +17,7 @@ const getClientEnvironment = require('./env');
|
||||||
const paths = require('./paths');
|
const paths = require('./paths');
|
||||||
// Webpack uses `publicPath` to determine where the app is being served from.
|
// Webpack uses `publicPath` to determine where the app is being served from.
|
||||||
// It requires a trailing slash, or the file assets will get an incorrect path.
|
// It requires a trailing slash, or the file assets will get an incorrect path.
|
||||||
|
// const publicPath = 'http://localhost:3000/';
|
||||||
const publicPath = paths.servedPath;
|
const publicPath = paths.servedPath;
|
||||||
// Some apps do not use client-side routing with pushState.
|
// Some apps do not use client-side routing with pushState.
|
||||||
// For these, "homepage" can be set to "." to enable relative asset paths.
|
// For these, "homepage" can be set to "." to enable relative asset paths.
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,9 @@ module.exports = function(proxy, allowedHost) {
|
||||||
disableDotRule: true,
|
disableDotRule: true,
|
||||||
},
|
},
|
||||||
public: allowedHost,
|
public: allowedHost,
|
||||||
proxy,
|
proxy: {
|
||||||
|
"/api":"http://localhost:5000/"
|
||||||
|
},
|
||||||
setup(app) {
|
setup(app) {
|
||||||
// This lets us open files from the runtime error overlay.
|
// This lets us open files from the runtime error overlay.
|
||||||
app.use(errorOverlayMiddleware());
|
app.use(errorOverlayMiddleware());
|
||||||
|
|
|
||||||
|
|
@ -113,13 +113,11 @@ if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
|
||||||
// }
|
// }
|
||||||
// );
|
// );
|
||||||
startWebPackDevServer(()=>{
|
startWebPackDevServer(()=>{
|
||||||
// child_process.spawn('webpack',['--watch','--config','config/webpack.config.flask.js'],{
|
|
||||||
// stdio:'inherit'
|
|
||||||
// });
|
|
||||||
child_process.spawn('python',['walle_server.py'],{
|
child_process.spawn('python',['walle_server.py'],{
|
||||||
stdio:'inherit'
|
stdio:'inherit'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create the production build and print the deployment instructions.
|
// Create the production build and print the deployment instructions.
|
||||||
function build(previousFileSizes) {
|
function build(previousFileSizes) {
|
||||||
console.log('Creating an optimized production build...');
|
console.log('Creating an optimized production build...');
|
||||||
|
|
@ -169,10 +167,11 @@ 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.emptyDirSync(paths.appBuild);
|
||||||
fs.ensureSymlink(paths.appPng,path.resolve(paths.appBuild,'png'));
|
// 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.
|
||||||
choosePort(HOST, DEFAULT_PORT)
|
choosePort(HOST, DEFAULT_PORT)
|
||||||
|
|
@ -201,8 +200,9 @@ function startWebPackDevServer(pyServer){
|
||||||
}
|
}
|
||||||
if (isInteractive) {
|
if (isInteractive) {
|
||||||
clearConsole();
|
clearConsole();
|
||||||
const urls = prepareUrls(protocol, HOST, '5000');
|
const pyurls = prepareUrls(protocol, HOST, '5000');
|
||||||
pyServer();
|
pyServer();
|
||||||
|
// openBrowser(pyurls.localUrlForBrowser);
|
||||||
openBrowser(urls.localUrlForBrowser);
|
openBrowser(urls.localUrlForBrowser);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ export class Main extends React.Component<any, any> {
|
||||||
</Header.Content>
|
</Header.Content>
|
||||||
</Header>
|
</Header>
|
||||||
</Segment>
|
</Segment>
|
||||||
<LexSetup {...this.props} fileName="/new_es.xml"/>
|
<LexSetup {...this.props} fileName="/new_es_orig.xml"/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ const { Box } = require('reflexbox');
|
||||||
|
|
||||||
const serialize = function(obj: any) {
|
const serialize = function(obj: any) {
|
||||||
var str = [];
|
var str = [];
|
||||||
for(var p in obj){
|
for (var p in obj) {
|
||||||
if (obj.hasOwnProperty(p)) {
|
if (obj.hasOwnProperty(p)) {
|
||||||
str.push(encodeURIComponent(p) + '=' + encodeURIComponent(obj[p]));
|
str.push(encodeURIComponent(p) + '=' + encodeURIComponent(obj[p]));
|
||||||
}
|
}
|
||||||
|
|
@ -29,15 +29,14 @@ export class LexEdit extends React.Component<any, any> {
|
||||||
}
|
}
|
||||||
public render() {
|
public render() {
|
||||||
let li = this.state.lexItem;
|
let li = this.state.lexItem;
|
||||||
let editLang = _.get<any>(li, this.props.fieldMetaMap.lang.lens, 'en');
|
let editLang = this.props.fieldMetaMap.lang.get(li);
|
||||||
let langSelOpts = _.get<any>(this.props.selectionMeta, editLang, []);
|
let langSelOpts = _.get<any>(this.props.selectionMeta, editLang, []);
|
||||||
let lexFields = _.keys(this.props.fieldMetaMap).map(field => {
|
let lexFields = _.keys(this.props.fieldMetaMap).map(field => {
|
||||||
let lens = this.props.fieldMetaMap[field].lens;
|
let fieldMeta = this.props.fieldMetaMap[field];
|
||||||
let defaultText = _.get<any>(li, lens, '');
|
let defaultText = fieldMeta.get(li);
|
||||||
let originalText = _.get<any>(this.props.lexItem, lens, '');
|
let originalText = fieldMeta.get(this.props.lexItem);
|
||||||
let options = this.props.fieldMetaMap[field].options;
|
let options = fieldMeta.options;
|
||||||
let changed = defaultText !== originalText && this.props.existing;
|
let changed = defaultText !== originalText && this.props.existing;
|
||||||
// console.log('changed:',changed);
|
|
||||||
let sh = (e: any) => {
|
let sh = (e: any) => {
|
||||||
let eventData = {};
|
let eventData = {};
|
||||||
eventData[field] = e.target.value;
|
eventData[field] = e.target.value;
|
||||||
|
|
@ -48,10 +47,10 @@ export class LexEdit extends React.Component<any, any> {
|
||||||
return textInput(params);
|
return textInput(params);
|
||||||
} else if (this.props.fieldMetaMap[field].type === 'select') {
|
} else if (this.props.fieldMetaMap[field].type === 'select') {
|
||||||
return selectInput(params);
|
return selectInput(params);
|
||||||
} else if (this.props.fieldMetaMap[field].type === 'preview'
|
} else if (this.props.fieldMetaMap[field].type === 'preview') {
|
||||||
&& defaultText !== '') {
|
|
||||||
return imagePreview(params);
|
return imagePreview(params);
|
||||||
} else {
|
} else {
|
||||||
|
console.log('field discarded :', field);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -103,14 +102,18 @@ export class LexEdit extends React.Component<any, any> {
|
||||||
|
|
||||||
private handleOnLoad(event: any) {
|
private handleOnLoad(event: any) {
|
||||||
// this.props.load(this.state.lexItem)
|
// this.props.load(this.state.lexItem)
|
||||||
let lexItem = this.props.lexItem;
|
let li = this.state.lexItem;
|
||||||
let word = _.get<any>(lexItem, this.props.fieldMetaMap.label.lens, '');
|
let word = this.props.fieldMetaMap.label.get(li);
|
||||||
let pos = _.get<any>(lexItem, this.props.fieldMetaMap.pos.lens, '');
|
let pos = this.props.fieldMetaMap.pos.get(li);
|
||||||
let args = serialize({word,pos});
|
let args = serialize({ word, pos });
|
||||||
fetch('/morph?'+args)
|
let morphQuery = '/api/morph?' + args;
|
||||||
|
fetch(morphQuery)
|
||||||
.then((response) => response.text())
|
.then((response) => response.text())
|
||||||
.then((jsonMorph) => {
|
.then((jsonMorph) => {
|
||||||
console.log(jsonMorph);
|
let morphDict = JSON.parse(jsonMorph);
|
||||||
|
let morphMeta = this.props.fieldMetaMap.morphclass;
|
||||||
|
let lexItem = morphMeta.set(this.state.lexItem, morphDict.morphclass);
|
||||||
|
this.setState({ lexItem });
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
console.log('errored :', e);
|
console.log('errored :', e);
|
||||||
|
|
@ -119,10 +122,9 @@ export class LexEdit extends React.Component<any, any> {
|
||||||
|
|
||||||
private handleOnChange(event: any) {
|
private handleOnChange(event: any) {
|
||||||
let type = _.keys(event)[0];
|
let type = _.keys(event)[0];
|
||||||
let value = _.values(event)[0];
|
let value = _.values(event)[0] as string;
|
||||||
let lens = this.props.fieldMetaMap[type].lens;
|
let meta = this.props.fieldMetaMap[type];
|
||||||
let lexItem = _.cloneDeep(this.state.lexItem);
|
let lexItem = meta.set(this.state.lexItem, value);
|
||||||
_.set(lexItem, lens, value);
|
|
||||||
this.setState({ lexItem });
|
this.setState({ lexItem });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,10 @@ const { Flex } = require('reflexbox');
|
||||||
// container component
|
// container component
|
||||||
export class LexEditor extends React.Component<any, any> {
|
export class LexEditor extends React.Component<any, any> {
|
||||||
public render() {
|
public render() {
|
||||||
let searchLens = this.props.fieldMetaMap[this.props.searchState.searchType].lens;
|
let searchMeta = this.props.fieldMetaMap[this.props.searchState.searchType];
|
||||||
let searchText = this.props.searchState.searchValue;
|
let searchText = this.props.searchState.searchValue;
|
||||||
let matchedEntries = _.chain(this.props.allEntries)
|
let matchedEntries = _.chain(this.props.allEntries)
|
||||||
.filter((q: any) => _.get<any>(q, searchLens, '') === searchText)
|
.filter((q: any) => searchMeta.get(q) === searchText)
|
||||||
.take(10)
|
.take(10)
|
||||||
.value();
|
.value();
|
||||||
let { fieldMetaMap: fieldMetaMap, save: save } = this.props;
|
let { fieldMetaMap: fieldMetaMap, save: save } = this.props;
|
||||||
|
|
@ -27,7 +27,7 @@ export class LexEditor extends React.Component<any, any> {
|
||||||
matchedEntries={matchedEntries}
|
matchedEntries={matchedEntries}
|
||||||
selectionMeta={this.props.selectFields}
|
selectionMeta={this.props.selectFields}
|
||||||
searchText={searchText}
|
searchText={searchText}
|
||||||
searchLens={searchLens}
|
searchMeta={searchMeta}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
@ -91,8 +91,7 @@ function LexMatches(params: any) {
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
let addProps = {};
|
let addProps = props.searchMeta.set({}, props.searchText);
|
||||||
_.set(addProps, props.searchLens, props.searchText);
|
|
||||||
let addEntry = (
|
let addEntry = (
|
||||||
<LexEdit
|
<LexEdit
|
||||||
{...props}
|
{...props}
|
||||||
|
|
|
||||||
100
src/LexSetup.tsx
100
src/LexSetup.tsx
|
|
@ -4,21 +4,79 @@ import * as XML from 'xml2js';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import { LexEditor } from './LexEditor';
|
import { LexEditor } from './LexEditor';
|
||||||
|
|
||||||
const fieldMetaMap = {
|
function simpleAccessor(lens: string, def: string = '') {
|
||||||
label: { lens: 'label[0]', type: 'text' },
|
return {
|
||||||
unl: { lens: 'unl[0]', type: 'text' },
|
get: (li: any) => {
|
||||||
synset: { lens: 'lexprops[0].wnsynset[0]', type: 'text' },
|
let val = _.get<any>(li, lens, def);
|
||||||
guid: { lens: 'guid[0]', type: 'text' },
|
return val;
|
||||||
pos: { lens: 'pos[0]', type: 'select' },
|
|
||||||
image: { lens: 'image[0]', type: 'preview' },
|
|
||||||
relations: { lens: 'relations[0]', type: 'text' },
|
|
||||||
frame: { lens: 'syntacticprops[0].property[0]._', type: 'select' },
|
|
||||||
morphclass: {
|
|
||||||
lens: 'lexprops[0].morphology[0].morph[0]._',
|
|
||||||
type: 'select'
|
|
||||||
},
|
},
|
||||||
stats: { lens: 'stats[0].property[0]._', type: 'text' },
|
set: (li: any, value: string) => {
|
||||||
lang: { lens: '$.id', type: 'select', options: ['en', 'es'] },
|
let lexItem = _.cloneDeep(li);
|
||||||
|
let ret = _.set<any>(lexItem, lens, value);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const fieldMetaMap = {
|
||||||
|
label: {
|
||||||
|
type: 'text',
|
||||||
|
...simpleAccessor('label[0]'),
|
||||||
|
},
|
||||||
|
unl: { type: 'text', ...simpleAccessor('unl[0]'), },
|
||||||
|
synset: { type: 'text', ...simpleAccessor('lexprops[0].wnsynset[0]'), },
|
||||||
|
guid: { type: 'text', ...simpleAccessor('guid[0]'), },
|
||||||
|
pos: { type: 'select', ...simpleAccessor('pos[0]'), },
|
||||||
|
image: { type: 'text', ...simpleAccessor('image[0]'), },
|
||||||
|
relations: { type: 'text', ...simpleAccessor('relations[0]'), },
|
||||||
|
frame: { type: 'select', ...simpleAccessor('syntacticprops[0].property[0]._'), },
|
||||||
|
morphclass: {
|
||||||
|
type: 'select',
|
||||||
|
get: (li: any) => {
|
||||||
|
let lens = 'lexprops[0].morphology[0].morph';
|
||||||
|
let def = [{ _: '', $: { form: 'morphclass' } }];
|
||||||
|
let morphProps = _.get<any>(li, lens, def);
|
||||||
|
let prop = _.filter<any>(morphProps, (m) => {
|
||||||
|
return m.$.form === 'morphclass';
|
||||||
|
});
|
||||||
|
let mcls = _.get<any>(prop, '[0]._', '');
|
||||||
|
return mcls;
|
||||||
|
},
|
||||||
|
set: (li: any, value: string) => {
|
||||||
|
let lexItem = _.cloneDeep(li);
|
||||||
|
let lens = 'lexprops[0].morphology[0].morph';
|
||||||
|
let morphProps = _.get<any>(lexItem, lens, []);
|
||||||
|
if (morphProps.length > 0) {
|
||||||
|
let prop = _.filter<any>(morphProps, (m) => {
|
||||||
|
return m.$.form === 'morphclass';
|
||||||
|
});
|
||||||
|
if (prop.length > 0) {
|
||||||
|
_.set(prop[0], '_', value);
|
||||||
|
} else {
|
||||||
|
let def = { _: value, $: { form: 'morphclass' } };
|
||||||
|
morphProps.push(def);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let def = [{ _: value, $: { form: 'morphclass' } }];
|
||||||
|
_.set(lexItem, lens, def);
|
||||||
|
}
|
||||||
|
return lexItem;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
morphexceptions: {
|
||||||
|
type: 'list',
|
||||||
|
get: (li: any) => {
|
||||||
|
let lens = 'lexprops[0].morphology[0].morph';
|
||||||
|
let def = [{ _: 'M0', $: { form: 'morphclass' } }];
|
||||||
|
let morphProps = _.get<any>(li, lens, def);
|
||||||
|
let morphExps = _.filter<any>(morphProps, (m) => {
|
||||||
|
return m.$.form !== 'morphclass';
|
||||||
|
});
|
||||||
|
return morphExps;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
stats: { type: 'text', ...simpleAccessor('stats[0].property[0]._'), },
|
||||||
|
lang: { type: 'select', options: ['en', 'es'], ...simpleAccessor('$.id', 'en'), },
|
||||||
};
|
};
|
||||||
|
|
||||||
const xmlToEntries = (xmlData: any) => {
|
const xmlToEntries = (xmlData: any) => {
|
||||||
|
|
@ -34,7 +92,7 @@ const xmlToEntries = (xmlData: any) => {
|
||||||
)
|
)
|
||||||
.value();
|
.value();
|
||||||
let langReducer = ((result: any, q: any) => {
|
let langReducer = ((result: any, q: any) => {
|
||||||
let lang = _.get<any>(q, fieldMetaMap.lang.lens, 'en');
|
let lang = fieldMetaMap.lang.get(q);
|
||||||
(result[lang] || (result[lang] = [])).push(q);
|
(result[lang] || (result[lang] = [])).push(q);
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
|
|
@ -44,10 +102,9 @@ const xmlToEntries = (xmlData: any) => {
|
||||||
let langOpts = _.fromPairs(_.keys(fieldMetaMap).filter((s) => {
|
let langOpts = _.fromPairs(_.keys(fieldMetaMap).filter((s) => {
|
||||||
return fieldMetaMap[s].type === 'select';
|
return fieldMetaMap[s].type === 'select';
|
||||||
}).map((s) => {
|
}).map((s) => {
|
||||||
let lens = fieldMetaMap[s].lens;
|
|
||||||
let entries = _.get<any>(langEntries, lang, 'en');
|
let entries = _.get<any>(langEntries, lang, 'en');
|
||||||
let selectOptions = _.uniq(entries.map((q: any) => {
|
let selectOptions = _.uniq(entries.map((q: any) => {
|
||||||
return _.get<any>(q, lens, '');
|
return fieldMetaMap[s].get(q);
|
||||||
}));
|
}));
|
||||||
return [s, selectOptions];
|
return [s, selectOptions];
|
||||||
}));
|
}));
|
||||||
|
|
@ -78,12 +135,15 @@ export class LexSetup extends React.Component<any, any> {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return this.state.xmlLoaded ? (
|
let dimmer = (
|
||||||
<LexEditor {...xmlToEntries(this.props.xmlData)} {...this.props} />
|
|
||||||
) : (
|
|
||||||
<Dimmer active={true} inverted={true}>
|
<Dimmer active={true} inverted={true}>
|
||||||
<Loader inverted={true}>Loading</Loader>
|
<Loader inverted={true}>Loading</Loader>
|
||||||
</Dimmer>
|
</Dimmer>
|
||||||
);
|
);
|
||||||
|
let xmlEntries = xmlToEntries(this.props.xmlData);
|
||||||
|
let editor = (
|
||||||
|
<LexEditor {...xmlEntries} {...this.props} />
|
||||||
|
);
|
||||||
|
return this.state.xmlLoaded ? editor : dimmer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,9 +82,9 @@ export function selectInput(params: any) {
|
||||||
export function imagePreview(params: any) {
|
export function imagePreview(params: any) {
|
||||||
let { field, defaultText, changed } = params;
|
let { field, defaultText, changed } = params;
|
||||||
let imageSrc = imageRoot + defaultText;
|
let imageSrc = imageRoot + defaultText;
|
||||||
return (
|
return defaultText !== '' ? (
|
||||||
<LexSingleInput key={field} label={changedLabel(changed, field)}>
|
<LexSingleInput key={field} label={changedLabel(changed, field)}>
|
||||||
<Image src={imageSrc} size="tiny" bordered={true} />
|
<Image src={imageSrc} size="tiny" bordered={true} />
|
||||||
</LexSingleInput>
|
</LexSingleInput>
|
||||||
);
|
) : null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,27 @@
|
||||||
from flask import Flask,send_from_directory,request
|
from flask import Flask,send_from_directory,request
|
||||||
app = Flask(__name__,static_url_path='',static_folder='build')
|
app = Flask(__name__,static_url_path='',static_folder='build')
|
||||||
from freespeech_walle.get_morph_rule import get_morph
|
# from freespeech_walle.get_morph_rule import get_morph
|
||||||
|
from freespeech_walle.wizard_helpers import get_morph_rule,get_frequency
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
# from flask_cors import CORS, cross_origin
|
||||||
|
# CORS(app)
|
||||||
|
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
def walle_index():
|
def walle_index():
|
||||||
return app.send_static_file('index.html')
|
return app.send_static_file('index.html')
|
||||||
|
|
||||||
|
|
||||||
@app.route('/test')
|
@app.route('/api/test')
|
||||||
def walle_test():
|
def walle_test():
|
||||||
return "test"
|
return "test"
|
||||||
|
|
||||||
@app.route('/morph')
|
@app.route('/api/morph')
|
||||||
def walle_morph():
|
def walle_morph():
|
||||||
word = request.args.get('word')
|
word = request.args.get('word','water')
|
||||||
pos = request.args.get('pos')
|
pos_req = request.args.get('pos','N')
|
||||||
return json.dumps(get_morph(word,pos))
|
pos = pos_req if pos_req != '' else 'N';
|
||||||
|
return json.dumps(get_morph_rule.get_morph(word,pos))
|
||||||
|
|
||||||
# hmr streaming
|
# hmr streaming
|
||||||
# import requests
|
# import requests
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue