1. refactored to use get/set instead of raw lens

2. updated webpack dev config to use python proxy api server
master
Malar Kannan 2017-07-19 16:53:24 +05:30
parent 3cc73e5404
commit c6c8655649
9 changed files with 134 additions and 65 deletions

View File

@ -17,6 +17,7 @@ const getClientEnvironment = require('./env');
const paths = require('./paths');
// 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.
// const publicPath = 'http://localhost:3000/';
const publicPath = paths.servedPath;
// Some apps do not use client-side routing with pushState.
// For these, "homepage" can be set to "." to enable relative asset paths.

View File

@ -77,7 +77,9 @@ module.exports = function(proxy, allowedHost) {
disableDotRule: true,
},
public: allowedHost,
proxy,
proxy: {
"/api":"http://localhost:5000/"
},
setup(app) {
// This lets us open files from the runtime error overlay.
app.use(errorOverlayMiddleware());

View File

@ -113,13 +113,11 @@ if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
// }
// );
startWebPackDevServer(()=>{
// child_process.spawn('webpack',['--watch','--config','config/webpack.config.flask.js'],{
// stdio:'inherit'
// });
child_process.spawn('python',['walle_server.py'],{
stdio:'inherit'
});
});
// Create the production build and print the deployment instructions.
function build(previousFileSizes) {
console.log('Creating an optimized production build...');
@ -169,10 +167,11 @@ 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();
// fs.emptyDirSync(paths.appBuild);
// fs.ensureSymlink(paths.appPng,path.resolve(paths.appBuild,'png'));
// // Merge with the public folder
// 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.
choosePort(HOST, DEFAULT_PORT)
@ -201,8 +200,9 @@ function startWebPackDevServer(pyServer){
}
if (isInteractive) {
clearConsole();
const urls = prepareUrls(protocol, HOST, '5000');
const pyurls = prepareUrls(protocol, HOST, '5000');
pyServer();
// openBrowser(pyurls.localUrlForBrowser);
openBrowser(urls.localUrlForBrowser);
}
});

View File

@ -27,7 +27,7 @@ export class Main extends React.Component<any, any> {
</Header.Content>
</Header>
</Segment>
<LexSetup {...this.props} fileName="/new_es.xml"/>
<LexSetup {...this.props} fileName="/new_es_orig.xml"/>
</div>
);
}

View File

@ -13,7 +13,7 @@ const { Box } = require('reflexbox');
const serialize = function(obj: any) {
var str = [];
for(var p in obj){
for (var p in obj) {
if (obj.hasOwnProperty(p)) {
str.push(encodeURIComponent(p) + '=' + encodeURIComponent(obj[p]));
}
@ -29,15 +29,14 @@ export class LexEdit extends React.Component<any, any> {
}
public render() {
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 lexFields = _.keys(this.props.fieldMetaMap).map(field => {
let lens = this.props.fieldMetaMap[field].lens;
let defaultText = _.get<any>(li, lens, '');
let originalText = _.get<any>(this.props.lexItem, lens, '');
let options = this.props.fieldMetaMap[field].options;
let fieldMeta = this.props.fieldMetaMap[field];
let defaultText = fieldMeta.get(li);
let originalText = fieldMeta.get(this.props.lexItem);
let options = fieldMeta.options;
let changed = defaultText !== originalText && this.props.existing;
// console.log('changed:',changed);
let sh = (e: any) => {
let eventData = {};
eventData[field] = e.target.value;
@ -48,10 +47,10 @@ export class LexEdit extends React.Component<any, any> {
return textInput(params);
} else if (this.props.fieldMetaMap[field].type === 'select') {
return selectInput(params);
} else if (this.props.fieldMetaMap[field].type === 'preview'
&& defaultText !== '') {
} else if (this.props.fieldMetaMap[field].type === 'preview') {
return imagePreview(params);
} else {
console.log('field discarded :', field);
return null;
}
});
@ -103,14 +102,18 @@ export class LexEdit extends React.Component<any, any> {
private handleOnLoad(event: any) {
// this.props.load(this.state.lexItem)
let lexItem = this.props.lexItem;
let word = _.get<any>(lexItem, this.props.fieldMetaMap.label.lens, '');
let pos = _.get<any>(lexItem, this.props.fieldMetaMap.pos.lens, '');
let args = serialize({word,pos});
fetch('/morph?'+args)
let li = this.state.lexItem;
let word = this.props.fieldMetaMap.label.get(li);
let pos = this.props.fieldMetaMap.pos.get(li);
let args = serialize({ word, pos });
let morphQuery = '/api/morph?' + args;
fetch(morphQuery)
.then((response) => response.text())
.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) => {
console.log('errored :', e);
@ -119,10 +122,9 @@ export class LexEdit extends React.Component<any, any> {
private handleOnChange(event: any) {
let type = _.keys(event)[0];
let value = _.values(event)[0];
let lens = this.props.fieldMetaMap[type].lens;
let lexItem = _.cloneDeep(this.state.lexItem);
_.set(lexItem, lens, value);
let value = _.values(event)[0] as string;
let meta = this.props.fieldMetaMap[type];
let lexItem = meta.set(this.state.lexItem, value);
this.setState({ lexItem });
}

View File

@ -10,10 +10,10 @@ const { Flex } = require('reflexbox');
// container component
export class LexEditor extends React.Component<any, any> {
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 matchedEntries = _.chain(this.props.allEntries)
.filter((q: any) => _.get<any>(q, searchLens, '') === searchText)
.filter((q: any) => searchMeta.get(q) === searchText)
.take(10)
.value();
let { fieldMetaMap: fieldMetaMap, save: save } = this.props;
@ -27,7 +27,7 @@ export class LexEditor extends React.Component<any, any> {
matchedEntries={matchedEntries}
selectionMeta={this.props.selectFields}
searchText={searchText}
searchLens={searchLens}
searchMeta={searchMeta}
/>
</div>
);
@ -91,8 +91,7 @@ function LexMatches(params: any) {
/>
);
});
let addProps = {};
_.set(addProps, props.searchLens, props.searchText);
let addProps = props.searchMeta.set({}, props.searchText);
let addEntry = (
<LexEdit
{...props}

View File

@ -4,21 +4,79 @@ import * as XML from 'xml2js';
import * as _ from 'lodash';
import { LexEditor } from './LexEditor';
function simpleAccessor(lens: string, def: string = '') {
return {
get: (li: any) => {
let val = _.get<any>(li, lens, def);
return val;
},
set: (li: any, value: string) => {
let lexItem = _.cloneDeep(li);
let ret = _.set<any>(lexItem, lens, value);
return ret;
}
};
}
const fieldMetaMap = {
label: { lens: 'label[0]', type: 'text' },
unl: { lens: 'unl[0]', type: 'text' },
synset: { lens: 'lexprops[0].wnsynset[0]', type: 'text' },
guid: { lens: 'guid[0]', type: 'text' },
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'
label: {
type: 'text',
...simpleAccessor('label[0]'),
},
stats: { lens: 'stats[0].property[0]._', type: 'text' },
lang: { lens: '$.id', type: 'select', options: ['en', 'es'] },
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) => {
@ -34,7 +92,7 @@ const xmlToEntries = (xmlData: any) => {
)
.value();
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);
return result;
});
@ -44,10 +102,9 @@ const xmlToEntries = (xmlData: any) => {
let langOpts = _.fromPairs(_.keys(fieldMetaMap).filter((s) => {
return fieldMetaMap[s].type === 'select';
}).map((s) => {
let lens = fieldMetaMap[s].lens;
let entries = _.get<any>(langEntries, lang, 'en');
let selectOptions = _.uniq(entries.map((q: any) => {
return _.get<any>(q, lens, '');
return fieldMetaMap[s].get(q);
}));
return [s, selectOptions];
}));
@ -78,12 +135,15 @@ export class LexSetup extends React.Component<any, any> {
}
render() {
return this.state.xmlLoaded ? (
<LexEditor {...xmlToEntries(this.props.xmlData)} {...this.props} />
) : (
<Dimmer active={true} inverted={true}>
<Loader inverted={true}>Loading</Loader>
</Dimmer>
);
let dimmer = (
<Dimmer active={true} inverted={true}>
<Loader inverted={true}>Loading</Loader>
</Dimmer>
);
let xmlEntries = xmlToEntries(this.props.xmlData);
let editor = (
<LexEditor {...xmlEntries} {...this.props} />
);
return this.state.xmlLoaded ? editor : dimmer;
}
}

View File

@ -82,9 +82,9 @@ export function selectInput(params: any) {
export function imagePreview(params: any) {
let { field, defaultText, changed } = params;
let imageSrc = imageRoot + defaultText;
return (
return defaultText !== '' ? (
<LexSingleInput key={field} label={changedLabel(changed, field)}>
<Image src={imageSrc} size="tiny" bordered={true} />
</LexSingleInput>
);
) : null;
}

View File

@ -1,22 +1,27 @@
from flask import Flask,send_from_directory,request
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
# from flask_cors import CORS, cross_origin
# CORS(app)
@app.route('/')
def walle_index():
return app.send_static_file('index.html')
@app.route('/test')
@app.route('/api/test')
def walle_test():
return "test"
@app.route('/morph')
@app.route('/api/morph')
def walle_morph():
word = request.args.get('word')
pos = request.args.get('pos')
return json.dumps(get_morph(word,pos))
word = request.args.get('word','water')
pos_req = request.args.get('pos','N')
pos = pos_req if pos_req != '' else 'N';
return json.dumps(get_morph_rule.get_morph(word,pos))
# hmr streaming
# import requests