diff options
Diffstat (limited to 'app/client')
22 files changed, 703 insertions, 93 deletions
diff --git a/app/client/api/crud.fetch.js b/app/client/api/crud.fetch.js index 421510b..716ab3e 100644 --- a/app/client/api/crud.fetch.js +++ b/app/client/api/crud.fetch.js @@ -10,7 +10,7 @@ export function crud_fetch(type, tag) { }, show: id => { - return fetch(uri + id) + return fetch(uri + id, _get_headers(), _get_headers()) .then(req => req.json()) .catch(error) }, @@ -45,15 +45,17 @@ function _get_url(_url, data) { function _get_headers() { return { method: 'GET', + credentials: 'same-origin', headers: { 'Accept': 'application/json', }, } } -function post(data) { +export function post(data) { return { method: 'POST', body: JSON.stringify(data), + credentials: 'same-origin', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' @@ -64,25 +66,28 @@ export function postBody(data) { return { method: 'POST', body: data, + credentials: 'same-origin', headers: { 'Accept': 'application/json', }, } } -function put(data) { +export function put(data) { return { method: 'PUT', body: JSON.stringify(data), + credentials: 'same-origin', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' }, } } -function destroy(data) { +export function destroy(data) { return { method: 'DELETE', body: JSON.stringify(data), + credentials: 'same-origin', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' diff --git a/app/client/auth/auth.actions.js b/app/client/auth/auth.actions.js new file mode 100644 index 0000000..c4d9b52 --- /dev/null +++ b/app/client/auth/auth.actions.js @@ -0,0 +1,86 @@ +import types from '../types' +import { put } from '../api/crud.fetch' + +export const setToken = (data) => { + return { type: types.auth.set_token, data } +} +export const setReturnTo = (data) => { + return { type: types.auth.set_return_to, data } +} +export const setError = (data) => { + return { type: types.auth.set_error, data } +} +export const setCurrentUser = (data) => { + return { type: types.auth.set_current_user, data } +} +export function logout() { + return { type: types.auth.logout_user } +} +export function initialized() { + return { type: types.auth.initialized } +} +export function loading() { + return { type: types.auth.loading } +} + +export function InvalidCredentialsException(message) { + this.message = message + this.name = 'InvalidCredentialsException' +} + +const api = { + login: '/api/login', + logout: '/api/logout', + signup: '/api/signup', + checkin: '/api/checkin', +} + +export function login(username, password) { + return (dispatch) => { + dispatch(loading()) + fetch(api.login, put({ + username, + password + })) + .then(req => req.json()) + .then(data => { + console.log(data) + dispatch(setCurrentUser(data.user)) + }) + .catch(error => { + console.error(error) + dispatch(setError(true)) + }) + } +} + +export function signup(data) { + return (dispatch) => { + dispatch(loading()) + fetch(api.signup, put(data)) + .then(req => req.json()) + .then(data => { + console.log(data) + dispatch(setCurrentUser(data.user)) + }) + .catch(error => { + console.error(error) + dispatch(initialized()) + }) + } +} + +export function checkin() { + return (dispatch) => { + dispatch(loading()) + fetch(api.checkin, put({})) + .then(req => req.json()) + .then(data => { + dispatch(setCurrentUser(data.user)) + }) + .catch(error => { + console.error(error) + dispatch(initialized()) + }) + } +} diff --git a/app/client/auth/auth.gate.js b/app/client/auth/auth.gate.js new file mode 100644 index 0000000..087dfc6 --- /dev/null +++ b/app/client/auth/auth.gate.js @@ -0,0 +1,63 @@ +import { h, Component } from 'preact'; +// import PropTypes from 'prop-types'; +import { BrowserRouter, Route, Switch, Redirect, withRouter } from 'react-router-dom' +import { bindActionCreators } from 'redux'; +import { connect } from 'react-redux'; + +import * as authActions from './auth.actions'; + +import Login from './login.component'; +import Logout from './logout.component'; +import Signup from './signup.component'; + +import { randint } from '../util/math' + +class AuthRouter extends Component { + render(){ + return ( + <BrowserRouter> + <div> + <div className="diamond"></div> + <Switch> + <Route exact path='/' component={Login} /> + <Route exact path='/login' component={Login} /> + <Route exact path='/logout' component={Logout} /> + <Route exact path='/signup' component={Signup} /> + <Route component={props => { + this.props.actions.setReturnTo(props.location.pathname) + return ( + <Redirect to="/login" /> + ) + }} /> + </Switch> + </div> + </BrowserRouter> + ) + } + componentDidMount(){ + document.querySelector('.diamond').style.backgroundImage = 'linear-gradient(' + (randint(40)-5) + 'deg, #fde, #ffe)' + } +} + +class AuthGate extends Component { + render(){ + if (!this.props.auth.initialized) { + return <div className='loading'>Loading</div> + } + if (this.props.auth.isAuthenticated) return <div>{this.props.children}</div> + return <AuthRouter {...this.props} /> + } + componentDidMount(){ + this.props.actions.checkin() + } +} + +const mapStateToProps = (state) => ({ + auth: state.auth +}); + +const mapDispatchToProps = (dispatch) => ({ + actions: bindActionCreators(authActions, dispatch) +}); + +export default connect(mapStateToProps, mapDispatchToProps)(AuthGate); diff --git a/app/client/auth/auth.reducer.js b/app/client/auth/auth.reducer.js new file mode 100644 index 0000000..80b1ec5 --- /dev/null +++ b/app/client/auth/auth.reducer.js @@ -0,0 +1,92 @@ +import types from '../types' + +const authInitialState = { + token: null, + user: {}, + groups: {}, + initialized: false, + loading: false, + isAuthenticated: false, + returnTo: null, +} + +const auth = (state = authInitialState, action) => { + switch(action.type) { + case types.auth.set_token: + return { + ...state, + token: action.data, + isAuthenticated: !!action.data, + loading: false, + error: null, + } + + case types.auth.initialized: + return { + ...state, + loading: false, + initialized: true, + error: null, + } + + case types.auth.loading: + return { + ...state, + loading: true, + error: null, + } + + case types.auth.set_current_user: + return { + ...state, + loading: false, + initialized: true, + isAuthenticated: true, + user: action.data, + error: null, + } + + case types.auth.set_return_to: + return { + ...state, + returnTo: action.data, + } + + case types.auth.logout_user: + return { + ...authInitialState + } + + case types.auth.set_error: + return { + ...state, + loading: false, + error: action.data, + } + + case types.auth.loading: + // const initial_state_el = document.querySelector('#initial_state') + // if (initial_state_el) { + // try { + // const initial_state = JSON.parse(initial_state_el.innerHTML) + // if (initial_state && initial_state.auth && initial_state.auth.user) { + // console.log(initial_state.auth.user) + // return { + // ...state, + // user: { + // ...initial_state.auth.user, + // } + // } + // } + // } catch (e) { + // console.error("error loading initial state") + // } + // } + return state + + default: + return state + } +} + +export default auth diff --git a/app/client/auth/index.js b/app/client/auth/index.js new file mode 100644 index 0000000..5e6b2b0 --- /dev/null +++ b/app/client/auth/index.js @@ -0,0 +1,11 @@ +import Gate from './auth.gate'; +import Login from './login.component'; +import Logout from './logout.component'; +import Signup from './signup.component'; + +export default { + Gate, + Login, + Logout, + Signup, +}
\ No newline at end of file diff --git a/app/client/auth/login.component.js b/app/client/auth/login.component.js new file mode 100644 index 0000000..2ef01a6 --- /dev/null +++ b/app/client/auth/login.component.js @@ -0,0 +1,89 @@ +import { h, Component } from 'preact'; +// import PropTypes from 'prop-types'; +import { bindActionCreators } from 'redux'; +import { connect } from 'react-redux'; +import { Redirect } from 'react-router-dom'; +// import { Link } from 'react-router-dom'; +import * as authActions from './auth.actions'; + +import { Group, Param, TextInput, Button } from '../common'; + +class Login extends Component { + state = { + username: '', + password: '', + } + constructor() { + super() + this.handleChange = this.handleChange.bind(this) + this.handleSubmit = this.handleSubmit.bind(this) + } + handleChange(value, name) { + this.setState({ + [name]: value, + error: null, + }) + } + handleSubmit(e) { + e.preventDefault() + if (this.props.auth.loading) return + this.props.actions.login(this.state.username, this.state.password) + } + render(){ + if (this.props.auth.isAuthenticated) { + let { returnTo } = this.props.auth + if (!returnTo || returnTo.match(/(login|logout|signup)/i)) { + returnTo = '/' + } + return <Redirect to={returnTo} /> + } + return ( + <form onSubmit={this.handleSubmit}> + <h1>Log in</h1><br /> + <Group> + <TextInput + autofocus + autocapitalize="off" + autocomplete="off" + title="Username" + name="username" + type="text" + value={this.state.username} + onInput={this.handleChange} + /> + <TextInput + title="Password" + name="password" + type="password" + value={this.state.password} + onInput={this.handleChange} + /> + <Button + loading={this.props.auth.loading} + > + Login + </Button> + {this.renderAuthError()} + </Group> + </form> + ) + } + renderAuthError(){ + if (this.props.auth.error) { + return ( + <div className='form-input-hint'>{"There was an error logging you in (bad password?)"}</div> + ) + } + return null + } +} + +const mapStateToProps = (state) => ({ + auth: state.auth, +}); + +const mapDispatchToProps = (dispatch) => ({ + actions: bindActionCreators(authActions, dispatch) +}); + +export default connect(mapStateToProps, mapDispatchToProps)(Login); diff --git a/app/client/auth/logout.component.js b/app/client/auth/logout.component.js new file mode 100644 index 0000000..bcc3bce --- /dev/null +++ b/app/client/auth/logout.component.js @@ -0,0 +1,24 @@ +import { h, Component } from 'preact'; +// import PropTypes from 'prop-types'; +import { bindActionCreators } from 'redux'; +import { connect } from 'react-redux'; +import { Redirect } from 'react-router-dom'; +import * as authActions from './auth.actions'; + +class Logout extends Component { + componentWillMount(props){ + this.props.actions.logout() + } + render(){ + return <Redirect to="/" /> + } +} + +const mapStateToProps = (state) => ({ +}); + +const mapDispatchToProps = (dispatch) => ({ + actions: bindActionCreators(authActions, dispatch) +}); + +export default connect(mapStateToProps, mapDispatchToProps)(Logout); diff --git a/app/client/auth/signup.component.js b/app/client/auth/signup.component.js new file mode 100644 index 0000000..4882681 --- /dev/null +++ b/app/client/auth/signup.component.js @@ -0,0 +1,104 @@ +import { h, Component } from 'preact'; +import { bindActionCreators } from 'redux'; +import { connect } from 'react-redux'; +import { Redirect } from 'react-router-dom'; +import * as actions from './auth.actions'; + +import { Group, Param, TextInput, Button } from '../common'; + +class Signup extends Component { + state = { + username: '', + password: '', + password2: '', + } + constructor() { + super() + this.handleChange = this.handleChange.bind(this) + this.handleSubmit = this.handleSubmit.bind(this) + } + handleChange(value, name) { + this.setState({ + [name]: value, + }) + } + validate(){ + if (!this.state.password || this.state.password !== this.state.password2) { + return false + } + return true + } + handleSubmit(e) { + e.preventDefault() + if (this.props.auth.loading) return + if (!this.validate()) { + return this.props.actions.setError('bad password') + } + let { ...user } = this.state + this.props.actions.signup(user) + } + render(){ + if (this.props.auth.isAuthenticated) { + let { returnTo } = this.props.auth + if (!returnTo || returnTo.match(/(api|login|logout|signup)/i)) { + returnTo = '/' + } + return <Redirect to={returnTo} /> + } + return ( + <form onSubmit={this.handleSubmit}> + <h1>New account</h1><br /> + <Group> + <TextInput + autofocus + autocapitalize="off" + autocomplete="off" + title="Username" + name="username" + type="text" + value={this.state.username} + onInput={this.handleChange} + /> + <TextInput + title="Password" + name="password" + type="password" + value={this.state.password} + onInput={this.handleChange} + /> + <TextInput + title="Password again :)" + name="password2" + type="password" + value={this.state.password2} + onInput={this.handleChange} + /> + <Button + loading={this.props.auth.loading} + > + Sign up + </Button> + {this.renderAuthError()} + </Group> + </form> + ) + } + renderAuthError(){ + if (this.props.auth.error) { + return ( + <div className='form-input-hint'>{"Please doublecheck the form (o=_o~~)"}</div> + ) + } + return <div className='form-input-hint'></div> + } +} + +const mapStateToProps = (state) => ({ + auth: state.auth, +}); + +const mapDispatchToProps = (dispatch) => ({ + actions: bindActionCreators({ ...actions }, dispatch) +}); + +export default connect(mapStateToProps, mapDispatchToProps)(Signup); diff --git a/app/client/common/augmentationGrid.component.js b/app/client/common/augmentationGrid.component.js new file mode 100644 index 0000000..af77f6c --- /dev/null +++ b/app/client/common/augmentationGrid.component.js @@ -0,0 +1,47 @@ +import { h, Component } from 'preact' + +import Group from './group.component' +import Param from './param.component' +import Button from './button.component' +import ButtonGrid from './buttonGrid.component' + +export default class AugmentationGrid extends Component { + state = { + x: 0, y: 0, sum: 0, + } + render() { + let { + make, take, checkpoint, + onTrain, onAugment, + } = this.props + let { + x, y, sum + } = this.state + let rows = [] + return ( + <Group className='augmentationGrid'> + <ButtonGrid + x={make} + y={take} + max={5000} + onHover={(x, y) => this.setState({ x, y })} + onClick={(x, y) => { + this.setState({ sum: sum + x * y }) + onAugment(y, x) + }} + /> + <Param title='Name'>{checkpoint.name}</Param> + <Param title='Take'>{y}</Param> + <Param title='Make'>{x}</Param> + <Param title='Will add to dataset'>{x * y}</Param> + <Param title='Total added this epoch'>{sum}</Param> + <Param title='Sequence length'>{checkpoint.sequenceCount}</Param> + <Param title='Dataset size'>{checkpoint.datasetCount}</Param> + <Button onClick={() => { + this.setState({ sum: 0 }) + onTrain() + }}>Train</Button> + </Group> + ) + } +} diff --git a/app/client/common/buttonGrid.component.js b/app/client/common/buttonGrid.component.js new file mode 100644 index 0000000..6c7c105 --- /dev/null +++ b/app/client/common/buttonGrid.component.js @@ -0,0 +1,51 @@ +import { h, Component } from 'preact' + +export default class ButtonGrid extends Component { + state = { + x: 0, y: 0, + } + + render() { + const { + x: _x, + y: _y, + } = this.state + const { + x: X, + y: Y, + max = Infinity, + onClick, + onHover, + } = this.props + return ( + <table className='buttonGrid'> + <tr className='row'> + <th>{" "}</th> + {X.map(x => ( + <th className={x === _x && 'bold'}>{x}</th> + ))} + </tr> + {Y.map(y => ( + <tr className='row'> + <th className={y === _y && 'bold'}>{y}</th> + {X.map(x => ( + <td> + {x * y > max ? " " : + <button + onClick={() => onClick(x, y)} + onMouseEnter={() => { + this.setState({ x, y }) + onHover(x, y) + }} + > + {" "} + </button> + } + </td> + ))} + </tr> + ))} + </table> + ) + } +} diff --git a/app/client/common/currentTask.component.js b/app/client/common/currentTask.component.js index a4d9750..3c71a88 100644 --- a/app/client/common/currentTask.component.js +++ b/app/client/common/currentTask.component.js @@ -22,10 +22,10 @@ function CurrentTask ({ cpu, gpu, processor }) { const { last_message, pid, task } = p const { activity, epoch, epochs, dataset, module } = task return ( - <div> + <div className='currentTask'> #{pid}: <b>{module} {activity}</b> <i>{dataset}</i> - {epochs - ? <span>{epoch} epoch{util.courtesy_s(epoch)}</span> + {!!epochs + ? <span>{epochs} epoch{util.courtesy_s(epochs)}</span> : ""} {epoch ? <span>(currently #{epoch})</span> diff --git a/app/client/common/index.js b/app/client/common/index.js index 13b3189..e6baafc 100644 --- a/app/client/common/index.js +++ b/app/client/common/index.js @@ -1,4 +1,7 @@ +import AudioPlayer from './audioPlayer/audioPlayer.component' +import AugmentationGrid from './augmentationGrid.component' import Button from './button.component' +import ButtonGrid from './buttonGrid.component' import Checkbox from './checkbox.component' import CurrentTask from './currentTask.component' import { FileList, FileRow } from './fileList.component' @@ -22,11 +25,12 @@ import * as Views from './views' export { Views, - Loading, Progress, Header, + Loading, Progress, Header, AudioPlayer, FolderList, FileList, FileRow, FileUpload, Gallery, Player, Group, ParamGroup, Param, TextInput, NumberInput, Slider, Select, SelectGroup, Button, Checkbox, CurrentTask, TaskList, + ButtonGrid, AugmentationGrid, }
\ No newline at end of file diff --git a/app/client/common/taskList.component.js b/app/client/common/taskList.component.js index 710753f..c1ed38a 100644 --- a/app/client/common/taskList.component.js +++ b/app/client/common/taskList.component.js @@ -27,7 +27,7 @@ class TaskList extends Component { const task = pair[1] const { dataset } = task let dataset_link, label = dataset; - console.log(task) + // console.log(task) switch (task.activity) { case 'train': if (task.epoch === 0) { diff --git a/app/client/common/textInput.component.js b/app/client/common/textInput.component.js index d429944..d3b16ad 100644 --- a/app/client/common/textInput.component.js +++ b/app/client/common/textInput.component.js @@ -34,6 +34,9 @@ class TextInput extends Component { value={this.state.changed ? this.state.value : this.props.value} onInput={this.handleInput} onKeydown={this.handleKeydown} + autofocus={this.props.autofocus} + autoComplete={this.props.autocomplete} + autoCapitalize={this.props.autocapitalize || 'off'} placeholder={this.props.placeholder} autofocus={this.props.autofocus} className={this.props.className || ''} diff --git a/app/client/index.jsx b/app/client/index.jsx index fd4679c..9c18251 100644 --- a/app/client/index.jsx +++ b/app/client/index.jsx @@ -1,14 +1,14 @@ import { h, render } from 'preact' import { Provider } from 'react-redux' -import { BrowserRouter, Route } from 'react-router-dom' +import { BrowserRouter, Switch, Route, Redirect } from 'react-router-dom' // import client from './client' import { store, history } from './store' import * as socket from './socket' import util from './util' -import Header from './common/header.component' -import AudioPlayer from './common/audioPlayer/audioPlayer.component' +import Auth from './auth' +import { Header, AudioPlayer } from './common' import System from './system/system.component' import Dashboard from './dashboard/dashboard.component' import modules from './modules' @@ -22,16 +22,20 @@ const module_list = Object.keys(modules).map(name => { const app = ( <Provider store={store}> - <BrowserRouter> - <div> - <Route exact path='/' component={Dashboard} /> - <Route path='/system/' component={System} /> - <Route path='/dashboard/' component={Dashboard} /> - {module_list} - <Route path='/' component={Header} /> - <AudioPlayer /> - </div> - </BrowserRouter> + <Auth.Gate> + <BrowserRouter> + <Switch> + <Route exact path='/' component={Dashboard} /> + <Route exact path='/system/' component={System} /> + <Route exact path='/dashboard/' component={Dashboard} /> + <Route exact path='/logout/' component={Auth.Logout} /> + {module_list} + <Route exact path='/' component={Header} /> + <Route component={() => <Redirect to="/" />} /> + </Switch> + </BrowserRouter> + <AudioPlayer /> + </Auth.Gate> </Provider> ) diff --git a/app/client/modules/pix2pixhd/pix2pixhd.actions.js b/app/client/modules/pix2pixhd/pix2pixhd.actions.js index c1cd2b1..a17eeab 100644 --- a/app/client/modules/pix2pixhd/pix2pixhd.actions.js +++ b/app/client/modules/pix2pixhd/pix2pixhd.actions.js @@ -200,4 +200,30 @@ export const list_epochs = (checkpoint_name) => (dispatch) => { }, }) }) +} + +export const count_dataset = (checkpoint_name) => (dispatch) => { + const module = pix2pixhdModule.name + util.allProgress([ + actions.socket.count_directory({ module, dir: 'sequences/' + checkpoint_name + '/' }), + actions.socket.count_directory({ module, dir: 'datasets/' + checkpoint_name + '/train_A/' }), + ], (percent, i, n) => { + console.log('pix2pixhd load progress', i, n) + dispatch({ + type: types.app.load_progress, + progress: { i, n }, + data: { module: 'pix2pixhd' }, + }) + }).then(res => { + const [sequenceCount, datasetCount] = res //, datasets, results, output, datasetUsage, lossReport] = res + console.log(sequenceCount, datasetCount) + dispatch({ + type: types.pix2pixhd.load_dataset_count, + data: { + name: checkpoint_name, + sequenceCount, + datasetCount, + } + }) + }) }
\ No newline at end of file diff --git a/app/client/modules/pix2pixhd/pix2pixhd.reducer.js b/app/client/modules/pix2pixhd/pix2pixhd.reducer.js index c3d52a3..5a2afc0 100644 --- a/app/client/modules/pix2pixhd/pix2pixhd.reducer.js +++ b/app/client/modules/pix2pixhd/pix2pixhd.reducer.js @@ -8,6 +8,11 @@ const pix2pixhdInitialState = { folder_id: 0, data: null, results: null, + checkpoint: { + name: '', + sequenceCount: 0, + datasetCount: 0, + } } const pix2pixhdReducer = (state = pix2pixhdInitialState, action) => { @@ -21,6 +26,11 @@ const pix2pixhdReducer = (state = pix2pixhdInitialState, action) => { ...state, results: action.results, } + case types.pix2pixhd.load_dataset_count: + return { + ...state, + checkpoint: action.data, + } case types.file.destroy: console.log('file destroy', state.results) return { diff --git a/app/client/modules/pix2pixhd/views/pix2pixhd.train.js b/app/client/modules/pix2pixhd/views/pix2pixhd.train.js index 9c8aacc..06caa5a 100644 --- a/app/client/modules/pix2pixhd/views/pix2pixhd.train.js +++ b/app/client/modules/pix2pixhd/views/pix2pixhd.train.js @@ -11,7 +11,8 @@ import { FileList, FileRow, Select, SelectGroup, Group, Param, Button, TextInput, NumberInput, - CurrentTask, TaskList + CurrentTask, TaskList, + AugmentationGrid, } from '../../../common' import DatasetForm from '../../../dataset/dataset.form' import NewDatasetForm from '../../../dataset/dataset.new' @@ -32,30 +33,6 @@ class Pix2PixHDTrain extends Component { augment_take: 100, augment_make: 20, } - this.short_presets = [ - { augment_take: 100, augment_make: 5 }, - { augment_take: 200, augment_make: 5 }, - { augment_take: 200, augment_make: 3 }, - { augment_take: 50, augment_make: 10 }, - { augment_take: 100, augment_make: 10 }, - { augment_take: 1000, augment_make: 1 }, - ] - this.medium_presets = [ - { augment_take: 30, augment_make: 20 }, - { augment_take: 20, augment_make: 30 }, - { augment_take: 30, augment_make: 30 }, - { augment_take: 50, augment_make: 20 }, - { augment_take: 20, augment_make: 50 }, - { augment_take: 15, augment_make: 70 }, - ] - this.long_presets = [ - { augment_take: 2, augment_make: 100 }, - { augment_take: 2, augment_make: 200 }, - { augment_take: 5, augment_make: 100 }, - { augment_take: 5, augment_make: 200 }, - { augment_take: 10, augment_make: 100 }, - { augment_take: 10, augment_make: 200 }, - ] } componentWillMount(){ const id = this.props.match.params.id || localStorage.getItem('pix2pixhd.last_id') @@ -75,6 +52,7 @@ class Pix2PixHDTrain extends Component { if (prevState.checkpoint_name !== this.state.checkpoint_name) { this.setState({ epoch: 'latest' }) this.props.actions.list_epochs(this.state.checkpoint_name) + this.props.actions.count_dataset(this.state.checkpoint_name) } } handleChange(name, value){ @@ -84,7 +62,6 @@ class Pix2PixHDTrain extends Component { interrupt(){ this.props.actions.queue.stop_task('gpu') } - render(){ if (this.props.pix2pixhd.loading) { return <Loading progress={this.props.pix2pixhd.progress} /> @@ -164,52 +141,41 @@ class Pix2PixHDTrain extends Component { <Button title="Make a movie without augmenting" value="Generate" - onClick={() => this.props.remote.augment_task(this.state.checkpoint_name, { ...this.state, no_symlinks: true, mov: true, folder_id: this.props.pix2pixhd.data.resultsFolder.id })} - /> - </Group> - <Group title='Augmentation Presets'> - <Param title="Short Recursion"> - <div> - {this.short_presets.map(p => ( - <button onClick={() => this.props.remote.augment_task(this.state.checkpoint_name, p)}> - {p.augment_take}{'x'}{p.augment_make} - </button> - ))} - </div> - </Param> - <Param title="Medium Recursion"> - <div> - {this.medium_presets.map(p => ( - <button onClick={() => this.props.remote.augment_task(this.state.checkpoint_name, p)}> - {p.augment_take}{'x'}{p.augment_make} - </button> - ))} - </div> - </Param> - <Param title="Long Recursion"> - <div> - {this.long_presets.map(p => ( - <button onClick={() => this.props.remote.augment_task(this.state.checkpoint_name, p)}> - {p.augment_take}{'x'}{p.augment_make} - </button> - ))} - </div> - </Param> - </Group> - - <Group title='Train'> - <Button - title="Train one epoch" - value="Train" - onClick={() => this.props.remote.train_task(this.state.checkpoint_name, pix2pixhd.folder_id, 1)} + onClick={() => { + this.props.remote.augment_task(this.state.checkpoint_name, { + ...this.state, + no_symlinks: true, + mov: true, + folder_id: this.props.pix2pixhd.data.resultsFolder.id + }) + }} /> </Group> - - <Group title='Clear'> - <Button - title="Delete recursive frames" - value="Clear" - onClick={() => this.props.remote.clear_recursive_task(this.state.checkpoint_name)} + <Group title='Augmentation Grid'> + <AugmentationGrid + checkpoint={this.props.pix2pixhd.checkpoint} + take={[1,2,3,4,5,10,15,20,25,50,75,100,200,300,400,500,1000]} + make={[1,2,3,4,5,10,15,20,25,50,75,100,200,]} + onAugment={(augment_take, augment_make) => { + this.props.remote.augment_task(this.state.checkpoint_name, { + ...this.state, + augment_take, + augment_make, + }) + }} + onTrain={() => { + this.props.remote.train_task(this.state.checkpoint_name, pix2pixhd.folder_id, 1) + setTimeout(() => { // auto-generate epoch demo + this.props.remote.augment_task(this.state.checkpoint_name, { + ...this.state, + augment_take: 10, + augment_make: 150, + no_symlinks: true, + mov: true, + folder_id: this.props.pix2pixhd.data.resultsFolder.id + }) + }, 250) + }} /> </Group> diff --git a/app/client/socket/socket.actions.js b/app/client/socket/socket.actions.js index 78b0517..b80a0fa 100644 --- a/app/client/socket/socket.actions.js +++ b/app/client/socket/socket.actions.js @@ -4,6 +4,7 @@ import { socket } from './socket.connection' export const run_system_command = opt => syscall_async('run_system_command', opt) export const disk_usage = opt => syscall_async('run_system_command', { cmd: 'du', ...opt }) export const list_directory = opt => syscall_async('list_directory', opt).then(res => res.files) +export const count_directory = opt => syscall_async('count_directory', opt).then(res => res.count) export const list_sequences = opt => syscall_async('list_sequences', opt).then(res => res.sequences) export const run_script = opt => syscall_async('run_script', opt) export const upload_file = opt => syscall_async('upload_file', opt) diff --git a/app/client/store.js b/app/client/store.js index 8ffab15..654b22d 100644 --- a/app/client/store.js +++ b/app/client/store.js @@ -6,6 +6,7 @@ import createHistory from 'history/createBrowserHistory' import { routerReducer } from 'react-router-redux' // import navReducer from './nav.reducer' +import authReducer from './auth/auth.reducer' import systemReducer from './system/system.reducer' import dashboardReducer from './dashboard/dashboard.reducer' import liveReducer from './live/live.reducer' @@ -15,6 +16,7 @@ import audioPlayerReducer from './common/audioPlayer/audioPlayer.reducer' import { moduleReducer } from './modules/module.reducer' const appReducer = combineReducers({ + auth: authReducer, system: systemReducer, dashboard: dashboardReducer, live: liveReducer, diff --git a/app/client/system/system.actions.js b/app/client/system/system.actions.js index a34bd58..ccd9acd 100644 --- a/app/client/system/system.actions.js +++ b/app/client/system/system.actions.js @@ -25,6 +25,17 @@ export const listDirectory = (opt) => (dispatch) => { }) } +export const countDirectory = (opt) => (dispatch) => { + dispatch({ type: types.system.counting_directory, opt }) + socket.actions.count_directory(opt) + .then(data => { + dispatch({ + type: types.system.count_directory, + data: data, + }) + }) +} + export const changeTool = (tool) => { localStorage.setItem('system.last_tool', tool) return { type: types.app.change_tool, tool } diff --git a/app/client/types.js b/app/client/types.js index 2df494b..cfb590a 100644 --- a/app/client/types.js +++ b/app/client/types.js @@ -11,6 +11,8 @@ export default { rpc_disconnected: 'SYSTEM_RPC_DISCONNECTED', list_directory: 'SYSTEM_LIST_DIRECTORY', listing_directory: 'SYSTEM_LISTING_DIRECTORY', + count_directory: 'SYSTEM_COUNT_DIRECTORY', + counting_directory: 'SYSTEM_COUNTING_DIRECTORY', stdout: 'SYSTEM_STDOUT', stderr: 'SYSTEM_STDERR', }, @@ -34,6 +36,15 @@ export default { 'progress', 'epoch', ]), + auth: crud_type('auth', [ + 'set_token', + 'set_error', + 'set_current_user', + 'logout_user', + 'loading', + 'initialized', + 'set_return_to', + ]), socket: { connect: 'SOCKET_CONNECT', connect_error: 'SOCKET_CONNECT_ERROR', @@ -108,7 +119,7 @@ export default { 'init', 'set_folder' ]), pix2pixhd: with_type('pix2pixhd', [ - 'init', 'set_folder', 'load_results' + 'init', 'set_folder', 'load_results', 'load_dataset_count' ]), pix2wav: with_type('pix2wav', [ 'init', 'set_folder' |
