Partial export processing
This commit is contained in:
@@ -7,7 +7,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-svg-core": "^1.2.28",
|
"@fortawesome/fontawesome-svg-core": "^1.2.28",
|
||||||
"@fortawesome/free-solid-svg-icons": "^5.13.0",
|
"@fortawesome/free-solid-svg-icons": "^5.13.0",
|
||||||
"@fortawesome/react-fontawesome": "^0.1.9",
|
"@fortawesome/react-fontawesome": "^0.1.11",
|
||||||
"@reduxjs/toolkit": "^1.3.4",
|
"@reduxjs/toolkit": "^1.3.4",
|
||||||
"auto-launch": "^5.0.5",
|
"auto-launch": "^5.0.5",
|
||||||
"axios": "^0.19.2",
|
"axios": "^0.19.2",
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
"node-schedule": "^1.3.2",
|
"node-schedule": "^1.3.2",
|
||||||
"randomstring": "^1.1.5",
|
"randomstring": "^1.1.5",
|
||||||
"react": "^16.13.1",
|
"react": "^16.13.1",
|
||||||
|
"react-checkbox-tree": "^1.6.0",
|
||||||
"react-dom": "^16.13.1",
|
"react-dom": "^16.13.1",
|
||||||
"react-loader-spinner": "^3.1.5",
|
"react-loader-spinner": "^3.1.5",
|
||||||
"react-redux": "^7.2.0",
|
"react-redux": "^7.2.0",
|
||||||
|
|||||||
23
src/App.js
23
src/App.js
@@ -36,6 +36,7 @@ import {createModalConditionally} from './utils';
|
|||||||
import SkynetImport from './containers/SkynetImport/SkynetImport';
|
import SkynetImport from './containers/SkynetImport/SkynetImport';
|
||||||
import {displaySkynetImport} from './redux/actions/skynet_actions';
|
import {displaySkynetImport} from './redux/actions/skynet_actions';
|
||||||
import ApplicationBusy from './components/ApplicationBusy/ApplicationBusy';
|
import ApplicationBusy from './components/ApplicationBusy/ApplicationBusy';
|
||||||
|
import SkynetExport from './containers/SkynetExport/SkynetExport';
|
||||||
|
|
||||||
const Constants = require('./constants');
|
const Constants = require('./constants');
|
||||||
const Scheduler = require('node-schedule');
|
const Scheduler = require('node-schedule');
|
||||||
@@ -162,12 +163,23 @@ class App extends IPCContainer {
|
|||||||
!showUpgrade &&
|
!showUpgrade &&
|
||||||
this.props.DisplayImport;
|
this.props.DisplayImport;
|
||||||
|
|
||||||
const configDisplay = createModalConditionally(showConfig, <Configuration version={selectedVersion}
|
const showSkynetExport = !showConfig &&
|
||||||
|
!showDependencies &&
|
||||||
|
!this.props.DownloadActive &&
|
||||||
|
!showNewReleases &&
|
||||||
|
!this.props.RebootRequired &&
|
||||||
|
!this.props.DisplaySelectAppPlatform &&
|
||||||
|
!showUpgrade &&
|
||||||
|
this.props.DisplayExport;
|
||||||
|
|
||||||
|
const configDisplay = createModalConditionally(showConfig, <Configuration
|
||||||
|
version={selectedVersion}
|
||||||
remoteSupported={remoteSupported}/>);
|
remoteSupported={remoteSupported}/>);
|
||||||
const confirmDisplay = createModalConditionally(this.props.DisplayConfirmYesNo, <YesNo/>);
|
const confirmDisplay = createModalConditionally(this.props.DisplayConfirmYesNo, <YesNo/>);
|
||||||
const dependencyDisplay = createModalConditionally(showDependencies,
|
const dependencyDisplay = createModalConditionally(showDependencies,
|
||||||
<DependencyList/>, false, this.props.InstallActive);
|
<DependencyList/>, false, this.props.InstallActive);
|
||||||
const downloadDisplay = createModalConditionally(this.props.DownloadActive, <DownloadProgress/>, false, true);
|
const downloadDisplay = createModalConditionally(this.props.DownloadActive,
|
||||||
|
<DownloadProgress/>, false, true);
|
||||||
const errorDisplay = createModalConditionally(this.props.DisplayError, <ErrorDetails/>, true);
|
const errorDisplay = createModalConditionally(this.props.DisplayError, <ErrorDetails/>, true);
|
||||||
const infoDisplay = createModalConditionally(this.props.DisplayInfo, <InfoDetails/>, true);
|
const infoDisplay = createModalConditionally(this.props.DisplayInfo, <InfoDetails/>, true);
|
||||||
const newReleasesDisplay = createModalConditionally(showNewReleases, <NewReleases/>);
|
const newReleasesDisplay = createModalConditionally(showNewReleases, <NewReleases/>);
|
||||||
@@ -175,7 +187,10 @@ class App extends IPCContainer {
|
|||||||
const selectAppPlatformDisplay = createModalConditionally(this.props.DisplaySelectAppPlatform,
|
const selectAppPlatformDisplay = createModalConditionally(this.props.DisplaySelectAppPlatform,
|
||||||
<SelectAppPlatform/>);
|
<SelectAppPlatform/>);
|
||||||
const upgradeDisplay = createModalConditionally(showUpgrade, <UpgradeUI/>);
|
const upgradeDisplay = createModalConditionally(showUpgrade, <UpgradeUI/>);
|
||||||
const importDisplay = createModalConditionally(showSkynetImport, <SkynetImport version={selectedVersion}/>);
|
const importDisplay = createModalConditionally(showSkynetImport, <SkynetImport
|
||||||
|
version={selectedVersion}/>);
|
||||||
|
const exportDisplay = createModalConditionally(showSkynetExport, <SkynetExport
|
||||||
|
version={selectedVersion}/>)
|
||||||
const appBusyDisplay = createModalConditionally(this.props.AppBusy,
|
const appBusyDisplay = createModalConditionally(this.props.AppBusy,
|
||||||
<ApplicationBusy/>, false, true, this.props.AppBusyTransparent);
|
<ApplicationBusy/>, false, true, this.props.AppBusyTransparent);
|
||||||
|
|
||||||
@@ -246,6 +261,7 @@ class App extends IPCContainer {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{importDisplay}
|
{importDisplay}
|
||||||
|
{exportDisplay}
|
||||||
{newReleasesDisplay}
|
{newReleasesDisplay}
|
||||||
{selectAppPlatformDisplay}
|
{selectAppPlatformDisplay}
|
||||||
{dependencyDisplay}
|
{dependencyDisplay}
|
||||||
@@ -274,6 +290,7 @@ const mapStateToProps = state => {
|
|||||||
DisplayConfiguration: state.mounts.DisplayConfiguration,
|
DisplayConfiguration: state.mounts.DisplayConfiguration,
|
||||||
DisplayConfirmYesNo: state.common.DisplayConfirmYesNo,
|
DisplayConfirmYesNo: state.common.DisplayConfirmYesNo,
|
||||||
DisplayError: state.error.DisplayError,
|
DisplayError: state.error.DisplayError,
|
||||||
|
DisplayExport: state.skynet.DisplayExport,
|
||||||
DisplayImport: state.skynet.DisplayImport,
|
DisplayImport: state.skynet.DisplayImport,
|
||||||
DisplayInfo: state.error.DisplayInfo,
|
DisplayInfo: state.error.DisplayInfo,
|
||||||
DisplaySelectAppPlatform: state.common.DisplaySelectAppPlatform,
|
DisplaySelectAppPlatform: state.common.DisplaySelectAppPlatform,
|
||||||
|
|||||||
@@ -99,6 +99,9 @@ exports.IPC_Download_File = 'download_file';
|
|||||||
exports.IPC_Download_File_Complete = 'download_file_complete';
|
exports.IPC_Download_File_Complete = 'download_file_complete';
|
||||||
exports.IPC_Download_File_Progress = 'download_file_progress';
|
exports.IPC_Download_File_Progress = 'download_file_progress';
|
||||||
|
|
||||||
|
exports.IPC_Export_Skylinks = 'export_skylinks';
|
||||||
|
exports.IPC_Export_Skylinks_Reply = 'export_skylinks_reply';
|
||||||
|
|
||||||
exports.IPC_Extract_Release = 'extract_release';
|
exports.IPC_Extract_Release = 'extract_release';
|
||||||
exports.IPC_Extract_Release_Complete = 'extract_release_complete';
|
exports.IPC_Extract_Release_Complete = 'extract_release_complete';
|
||||||
|
|
||||||
@@ -114,6 +117,9 @@ exports.IPC_Get_Platform_Reply = 'get_platform_reply';
|
|||||||
exports.IPC_Get_State = 'get_state';
|
exports.IPC_Get_State = 'get_state';
|
||||||
exports.IPC_Get_State_Reply = 'get_state_reply';
|
exports.IPC_Get_State_Reply = 'get_state_reply';
|
||||||
|
|
||||||
|
exports.IPC_Grab_Skynet_Tree = 'grab_skynet_tree';
|
||||||
|
exports.IPC_Grab_Skynet_Tree_Reply = 'grab_skynet_tree_reply';
|
||||||
|
|
||||||
exports.IPC_Import_Skylinks = 'import_skylinks';
|
exports.IPC_Import_Skylinks = 'import_skylinks';
|
||||||
exports.IPC_Import_Skylinks_Reply = 'import_skylinks_reply';
|
exports.IPC_Import_Skylinks_Reply = 'import_skylinks_reply';
|
||||||
|
|
||||||
|
|||||||
4
src/containers/SkynetExport/SkynetExport.css
Normal file
4
src/containers/SkynetExport/SkynetExport.css
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
.SkynetExportHeading {
|
||||||
|
text-align: center;
|
||||||
|
padding-bottom: var(--default_spacing);
|
||||||
|
}
|
||||||
144
src/containers/SkynetExport/SkynetExport.js
Normal file
144
src/containers/SkynetExport/SkynetExport.js
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import './SkynetExport.css';
|
||||||
|
import CheckboxTree from 'react-checkbox-tree';
|
||||||
|
import {connect} from 'react-redux';
|
||||||
|
import IPCContainer from '../IPCContainer/IPCContainer';
|
||||||
|
import {notifyApplicationBusy} from '../../redux/actions/common_actions';
|
||||||
|
import {notifyError} from '../../redux/actions/error_actions';
|
||||||
|
import Box from '../../components/UI/Box/Box';
|
||||||
|
import {displaySkynetExport} from '../../redux/actions/skynet_actions';
|
||||||
|
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
|
||||||
|
import {
|
||||||
|
faCheckSquare, faChevronDown,
|
||||||
|
faChevronRight, faFile, faFolder, faFolderOpen,
|
||||||
|
faHSquare, faMinusSquare, faPlusSquare,
|
||||||
|
faSquare, faSquareFull, faSquareRootAlt
|
||||||
|
} from '@fortawesome/free-solid-svg-icons';
|
||||||
|
|
||||||
|
const Constants = require('../../constants');
|
||||||
|
|
||||||
|
const mapStateToProps = state => {
|
||||||
|
return {
|
||||||
|
AppBusy: state.common.AppBusy,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapDispatchToProps = dispatch => {
|
||||||
|
return {
|
||||||
|
displaySkynetExport: display => dispatch(displaySkynetExport(display)),
|
||||||
|
notifyApplicationBusy: busy => dispatch(notifyApplicationBusy(busy, true)),
|
||||||
|
notifyError: msg => dispatch(notifyError(msg)),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(class extends IPCContainer {
|
||||||
|
state = {
|
||||||
|
checked: [],
|
||||||
|
expanded: [],
|
||||||
|
nodes: [],
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.setRequestHandler(Constants.IPC_Grab_Skynet_Tree_Reply, this.onGrabSkynetTreeReply);
|
||||||
|
this.setRequestHandler(Constants.IPC_Export_Skylinks_Reply, this.onExportSkylinksReply);
|
||||||
|
this.sendRequest(Constants.IPC_Grab_Skynet_Tree, {Version: this.props.version});
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
super.componentWillUnmount();
|
||||||
|
}
|
||||||
|
|
||||||
|
createNodes = items => {
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
name: '',
|
||||||
|
path: '',
|
||||||
|
directory: true/false,
|
||||||
|
children: [],
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
const ret = [];
|
||||||
|
for (const item of items) {
|
||||||
|
const treeItem = {
|
||||||
|
label: item.name,
|
||||||
|
path: item.path,
|
||||||
|
value: item.name === '/' ? 0 : JSON.stringify(item),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (item.directory) {
|
||||||
|
treeItem.children = this.createNodes(item.children);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret.push(treeItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
onGrabSkynetTreeReply = (_, arg) => {
|
||||||
|
if (arg.data.Success) {
|
||||||
|
this.setState({
|
||||||
|
checked: [],
|
||||||
|
expanded: [0],
|
||||||
|
nodes: this.createNodes(arg.data.Result),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.setState({
|
||||||
|
checked: [],
|
||||||
|
expanded: [],
|
||||||
|
nodes: [],
|
||||||
|
}, () => {
|
||||||
|
this.props.notifyError(arg.data.Error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onExportSkylinksReply = (_, arg) => {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
console.log(this.state.expanded);
|
||||||
|
return this.props.AppBusy ? (<div/>) : (
|
||||||
|
<Box dxDark dxStyle={{
|
||||||
|
height: '90vh',
|
||||||
|
padding: 'var(--default_spacing)',
|
||||||
|
width: 'calc(100vw - (var(--default_spacing) * 4)'
|
||||||
|
}}>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
float: 'right',
|
||||||
|
margin: 0,
|
||||||
|
padding: 0,
|
||||||
|
marginTop: '-4px',
|
||||||
|
boxSizing: 'border-box',
|
||||||
|
display: 'block'
|
||||||
|
}}>
|
||||||
|
<a href={'#'}
|
||||||
|
onClick={() => this.props.displaySkynetExport(false)}
|
||||||
|
style={{cursor: 'pointer'}}>X</a>
|
||||||
|
</div>
|
||||||
|
<h1 className={'SkynetExportHeading'}>{'Export Files'}</h1>
|
||||||
|
<CheckboxTree checked={this.state.checked}
|
||||||
|
expanded={this.state.expanded}
|
||||||
|
icons={{
|
||||||
|
check: <FontAwesomeIcon icon={faCheckSquare}/>,
|
||||||
|
uncheck: <FontAwesomeIcon icon={faSquare}/>,
|
||||||
|
halfCheck: <FontAwesomeIcon icon={faHSquare}/>,
|
||||||
|
expandClose: <FontAwesomeIcon icon={faChevronRight}/>,
|
||||||
|
expandOpen: <FontAwesomeIcon icon={faChevronDown}/>,
|
||||||
|
expandAll: <FontAwesomeIcon icon={faPlusSquare}/>,
|
||||||
|
collapseAll: <FontAwesomeIcon icon={faMinusSquare}/>,
|
||||||
|
parentClose: <FontAwesomeIcon icon={faFolder}
|
||||||
|
color={'var(--heading_text_color)'}/>,
|
||||||
|
parentOpen: <FontAwesomeIcon icon={faFolderOpen}
|
||||||
|
color={'var(--heading_text_color)'}/>,
|
||||||
|
leaf: <FontAwesomeIcon icon={faFile} color={'var(--heading_text_color)'}/>
|
||||||
|
}}
|
||||||
|
nodes={this.state.nodes}
|
||||||
|
onCheck={checked => this.setState({checked})}
|
||||||
|
onExpand={expanded => this.setState({expanded})}/>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -166,12 +166,20 @@ export default connect(mapStateToProps, mapDispatchToProps)(class extends IPCCon
|
|||||||
width: 'calc(100vw - (var(--default_spacing) * 4)'
|
width: 'calc(100vw - (var(--default_spacing) * 4)'
|
||||||
}}>
|
}}>
|
||||||
<div
|
<div
|
||||||
style={{float: 'right', margin: 0, padding: 0, marginTop: '-4px', boxSizing: 'border-box', display: 'block'}}>
|
style={{
|
||||||
|
float: 'right',
|
||||||
|
margin: 0,
|
||||||
|
padding: 0,
|
||||||
|
marginTop: '-4px',
|
||||||
|
boxSizing: 'border-box',
|
||||||
|
display: 'block'
|
||||||
|
}}>
|
||||||
<a href={'#'}
|
<a href={'#'}
|
||||||
onClick={() => this.props.displaySkynetImport(false)}
|
onClick={() => this.props.displaySkynetImport(false)}
|
||||||
style={{cursor: 'pointer'}}>X</a>
|
style={{cursor: 'pointer'}}>X</a>
|
||||||
</div>
|
</div>
|
||||||
<h1 className={'SkynetImportHeading'}>{this.state.second_stage ? 'Verify Imports' : 'Import List'}</h1>
|
<h1
|
||||||
|
className={'SkynetImportHeading'}>{this.state.second_stage ? 'Verify Imports' : 'Import List'}</h1>
|
||||||
{
|
{
|
||||||
this.state.second_stage ? (
|
this.state.second_stage ? (
|
||||||
<ImportList imports_array={this.state.imports_array}/>
|
<ImportList imports_array={this.state.imports_array}/>
|
||||||
@@ -186,7 +194,8 @@ export default connect(mapStateToProps, mapDispatchToProps)(class extends IPCCon
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
<div className={'SkynetImportButtons'}>
|
<div className={'SkynetImportButtons'}>
|
||||||
<Button buttonStyles={{height: 'auto', marginTop: 'var(--default_spacing)', width: 'auto'}}
|
<Button
|
||||||
|
buttonStyles={{height: 'auto', marginTop: 'var(--default_spacing)', width: 'auto'}}
|
||||||
clicked={this.displaySyntax}>Import Syntax...</Button>
|
clicked={this.displaySyntax}>Import Syntax...</Button>
|
||||||
<div className={'SkynetActionButtons'}>
|
<div className={'SkynetActionButtons'}>
|
||||||
{
|
{
|
||||||
@@ -206,7 +215,8 @@ export default connect(mapStateToProps, mapDispatchToProps)(class extends IPCCon
|
|||||||
marginLeft: 'var(--default_spacing)',
|
marginLeft: 'var(--default_spacing)',
|
||||||
marginTop: 'var(--default_spacing)',
|
marginTop: 'var(--default_spacing)',
|
||||||
width: 'auto'
|
width: 'auto'
|
||||||
}} clicked={this.handleNavigation}>{this.state.second_stage ? 'Import' : 'Next'}</Button>
|
}}
|
||||||
|
clicked={this.handleNavigation}>{this.state.second_stage ? 'Import' : 'Next'}</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
133
src/helpers.js
133
src/helpers.js
@@ -9,7 +9,6 @@ const Constants = require('./constants');
|
|||||||
const RandomString = require('randomstring');
|
const RandomString = require('randomstring');
|
||||||
|
|
||||||
let vcRuntimeExists;
|
let vcRuntimeExists;
|
||||||
|
|
||||||
const _vcRuntimeExists = () => {
|
const _vcRuntimeExists = () => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (os.platform() !== 'win32') {
|
if (os.platform() !== 'win32') {
|
||||||
@@ -19,7 +18,7 @@ const _vcRuntimeExists = () => {
|
|||||||
resolve(true);
|
resolve(true);
|
||||||
} else {
|
} else {
|
||||||
const cmd = path.join(process.env.windir, 'system32', 'reg.exe');
|
const cmd = path.join(process.env.windir, 'system32', 'reg.exe');
|
||||||
const args = ["QUERY", "HKLM\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall"];
|
const args = ['QUERY', 'HKLM\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'];
|
||||||
_execProcessGetOutput(cmd, null, args)
|
_execProcessGetOutput(cmd, null, args)
|
||||||
.then(lines => {
|
.then(lines => {
|
||||||
const parseLine = index => {
|
const parseLine = index => {
|
||||||
@@ -62,7 +61,93 @@ const _vcRuntimeExists = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const _executeProcess = (command, working, args=[]) => {
|
// https://stackoverflow.com/questions/19531453/transform-file-directory-structure-into-tree-in-javascript
|
||||||
|
const _createTreeNodes = fileList => {
|
||||||
|
let tree = {}
|
||||||
|
|
||||||
|
const directorySort = (a, b) => {
|
||||||
|
return !!a.directory === !!b.directory ? a.name.localeCompare(b.name) : a.directory ? -1 : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
const addNode = obj => {
|
||||||
|
const fullPath = path.join(obj.directory, obj.filename).replace(/\\/g, '/');
|
||||||
|
const pathParts = fullPath.replace(/^\/|\/$/g, '').split('/');
|
||||||
|
let ptr = tree;
|
||||||
|
for (let i = 0; i < pathParts.length; i++) {
|
||||||
|
const node = {
|
||||||
|
directory: true,
|
||||||
|
name: pathParts[i],
|
||||||
|
};
|
||||||
|
if (i === pathParts.length - 1) {
|
||||||
|
node.directory = false;
|
||||||
|
node.path = fullPath;
|
||||||
|
}
|
||||||
|
ptr[pathParts[i]] = ptr[pathParts[i]] || node;
|
||||||
|
ptr[pathParts[i]].children = ptr[pathParts[i]].children || {};
|
||||||
|
ptr = ptr[pathParts[i]].children;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const objectToArray = node => {
|
||||||
|
Object.keys(node || {}).map((k) => {
|
||||||
|
if (node[k].children) {
|
||||||
|
objectToArray(node[k])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (node.children) {
|
||||||
|
node.children = Object.values(node.children);
|
||||||
|
node.children.forEach(objectToArray)
|
||||||
|
node.children = node.children.sort(directorySort);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fileList.map(addNode);
|
||||||
|
objectToArray(tree);
|
||||||
|
return Object.values(tree).sort(directorySort);
|
||||||
|
};
|
||||||
|
|
||||||
|
const _exportAllSkylinks = version => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const repertoryExec = _getRepertoryExec(version);
|
||||||
|
const processOptions = {
|
||||||
|
cwd: repertoryExec.working,
|
||||||
|
detached: true,
|
||||||
|
shell: false,
|
||||||
|
windowsHide: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
const args = _getDefaultRepertoryArgs('Skynet');
|
||||||
|
args.push('-ea');
|
||||||
|
|
||||||
|
let result = '';
|
||||||
|
const process = new spawn(repertoryExec.cmd, args, processOptions);
|
||||||
|
|
||||||
|
process.on('error', (err) => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
process.stdout.on('data', (d) => {
|
||||||
|
result += d;
|
||||||
|
});
|
||||||
|
|
||||||
|
process.stderr.on('data', (d) => {
|
||||||
|
result += d;
|
||||||
|
});
|
||||||
|
|
||||||
|
process.on('exit', code => {
|
||||||
|
if (code === 0) {
|
||||||
|
result = result.substr(result.indexOf('{'));
|
||||||
|
resolve(JSON.parse(result));
|
||||||
|
} else {
|
||||||
|
reject(new Error('Failed to import: ' + code + ':' + result));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
process.unref();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const _executeProcess = (command, working, args = []) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let processOptions = {
|
let processOptions = {
|
||||||
detached: true,
|
detached: true,
|
||||||
@@ -392,7 +477,7 @@ module.exports.executeAndWait = (command, ignoreResult) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.executeAsync = (command, args=[]) => {
|
module.exports.executeAsync = (command, args = []) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const launchProcess = (count, timeout) => {
|
const launchProcess = (count, timeout) => {
|
||||||
let cmd = path.basename(command);
|
let cmd = path.basename(command);
|
||||||
@@ -416,7 +501,7 @@ module.exports.executeAsync = (command, args=[]) => {
|
|||||||
reject(err, pid);
|
reject(err, pid);
|
||||||
} else {
|
} else {
|
||||||
clearTimeout(timeout);
|
clearTimeout(timeout);
|
||||||
setTimeout(()=> launchProcess(count, setTimeout(() => resolve(), 3000)), 1000);
|
setTimeout(() => launchProcess(count, setTimeout(() => resolve(), 3000)), 1000);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -458,7 +543,7 @@ module.exports.executeScript = script => {
|
|||||||
reject(err);
|
reject(err);
|
||||||
});
|
});
|
||||||
|
|
||||||
process.stdout.on('data', (d)=> {
|
process.stdout.on('data', (d) => {
|
||||||
result += d;
|
result += d;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -510,6 +595,8 @@ module.exports.executeMount = (version, provider, remote, location, exitCallback
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module.exports.exportAllSkylinks = _exportAllSkylinks;
|
||||||
|
|
||||||
module.exports.getConfig = (version, provider, remote) => {
|
module.exports.getConfig = (version, provider, remote) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const repertoryExec = _getRepertoryExec(version);
|
const repertoryExec = _getRepertoryExec(version);
|
||||||
@@ -530,7 +617,7 @@ module.exports.getConfig = (version, provider, remote) => {
|
|||||||
reject(err);
|
reject(err);
|
||||||
});
|
});
|
||||||
|
|
||||||
process.stdout.on('data', (d)=> {
|
process.stdout.on('data', (d) => {
|
||||||
result += d;
|
result += d;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -574,7 +661,7 @@ module.exports.getConfigTemplate = (version, provider, remote) => {
|
|||||||
reject(err);
|
reject(err);
|
||||||
});
|
});
|
||||||
|
|
||||||
process.stdout.on('data', (d)=> {
|
process.stdout.on('data', (d) => {
|
||||||
result += d;
|
result += d;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -666,7 +753,7 @@ module.exports.getMissingDependencies = dependencies => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (const dependency of dependencies) {
|
for (const dependency of dependencies) {
|
||||||
checkRegistry(dependency,0);
|
checkRegistry(dependency, 0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (const dep of dependencies) {
|
for (const dep of dependencies) {
|
||||||
@@ -683,6 +770,22 @@ module.exports.getMissingDependencies = dependencies => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
module.exports.grabSkynetFileTree = version => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
_exportAllSkylinks(version)
|
||||||
|
.then(results => {
|
||||||
|
resolve([{
|
||||||
|
name: '/',
|
||||||
|
directory: true,
|
||||||
|
children: _createTreeNodes(results.success),
|
||||||
|
}]);
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
reject(e);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
module.exports.importSkylinks = (version, jsonArray) => {
|
module.exports.importSkylinks = (version, jsonArray) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const repertoryExec = _getRepertoryExec(version);
|
const repertoryExec = _getRepertoryExec(version);
|
||||||
@@ -704,11 +807,11 @@ module.exports.importSkylinks = (version, jsonArray) => {
|
|||||||
reject(err);
|
reject(err);
|
||||||
});
|
});
|
||||||
|
|
||||||
process.stdout.on('data', (d)=> {
|
process.stdout.on('data', (d) => {
|
||||||
result += d;
|
result += d;
|
||||||
});
|
});
|
||||||
|
|
||||||
process.stderr.on('data', (d)=> {
|
process.stderr.on('data', (d) => {
|
||||||
result += d;
|
result += d;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -726,7 +829,7 @@ module.exports.importSkylinks = (version, jsonArray) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
//https://stackoverflow.com/questions/31645738/how-to-create-full-path-with-nodes-fs-mkdirsync
|
//https://stackoverflow.com/questions/31645738/how-to-create-full-path-with-nodes-fs-mkdirsync
|
||||||
module.exports.mkDirByPathSync = (targetDir, { isRelativeToScript = false } = {}) => {
|
module.exports.mkDirByPathSync = (targetDir, {isRelativeToScript = false} = {}) => {
|
||||||
const sep = path.sep;
|
const sep = path.sep;
|
||||||
const initDir = path.isAbsolute(targetDir) ? sep : '';
|
const initDir = path.isAbsolute(targetDir) ? sep : '';
|
||||||
const baseDir = isRelativeToScript ? __dirname : '.';
|
const baseDir = isRelativeToScript ? __dirname : '.';
|
||||||
@@ -761,7 +864,7 @@ module.exports.performWindowsUninstall = names => {
|
|||||||
reject('Windows OS is not being used');
|
reject('Windows OS is not being used');
|
||||||
} else {
|
} else {
|
||||||
const cmd = path.join(process.env.windir, 'system32', 'reg.exe');
|
const cmd = path.join(process.env.windir, 'system32', 'reg.exe');
|
||||||
const args = ["QUERY", "HKLM\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall"];
|
const args = ['QUERY', 'HKLM\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall'];
|
||||||
_execProcessGetOutput(cmd, null, args)
|
_execProcessGetOutput(cmd, null, args)
|
||||||
.then(lines => {
|
.then(lines => {
|
||||||
const parseLine = index => {
|
const parseLine = index => {
|
||||||
@@ -780,7 +883,7 @@ module.exports.performWindowsUninstall = names => {
|
|||||||
if (names.includes(value)) {
|
if (names.includes(value)) {
|
||||||
const items = line.split('\\');
|
const items = line.split('\\');
|
||||||
const productCode = items[items.length - 1];
|
const productCode = items[items.length - 1];
|
||||||
_executeProcess('msiexec.exe', null,['/x', productCode, '/norestart'])
|
_executeProcess('msiexec.exe', null, ['/x', productCode, '/norestart'])
|
||||||
.then(code => {
|
.then(code => {
|
||||||
if ((code === 0) || (code === 3010) || (code === 1641)) {
|
if ((code === 0) || (code === 3010) || (code === 1641)) {
|
||||||
resolve(true);
|
resolve(true);
|
||||||
@@ -807,7 +910,7 @@ module.exports.performWindowsUninstall = names => {
|
|||||||
};
|
};
|
||||||
parseLine(0);
|
parseLine(0);
|
||||||
})
|
})
|
||||||
.catch( err => {
|
.catch(err => {
|
||||||
reject(err);
|
reject(err);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {Provider} from 'react-redux';
|
|||||||
import {setActiveRelease} from './redux/actions/release_version_actions';
|
import {setActiveRelease} from './redux/actions/release_version_actions';
|
||||||
import {setProviderState} from './redux/actions/mount_actions';
|
import {setProviderState} from './redux/actions/mount_actions';
|
||||||
import * as serviceWorker from './serviceWorker';
|
import * as serviceWorker from './serviceWorker';
|
||||||
|
import 'react-checkbox-tree/lib/react-checkbox-tree.css';
|
||||||
|
|
||||||
const Constants = require('./constants');
|
const Constants = require('./constants');
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,19 @@ const addListeners = (ipcMain, {standardIPCReply}) => {
|
|||||||
standardIPCReply(event, Constants.IPC_Import_Skylinks_Reply, {}, error);
|
standardIPCReply(event, Constants.IPC_Import_Skylinks_Reply, {}, error);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipcMain.on(Constants.IPC_Grab_Skynet_Tree, (event, data) => {
|
||||||
|
helpers
|
||||||
|
.grabSkynetFileTree(data.Version)
|
||||||
|
.then(result => {
|
||||||
|
standardIPCReply(event, Constants.IPC_Grab_Skynet_Tree_Reply, {
|
||||||
|
Result: result,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
standardIPCReply(event, Constants.IPC_Grab_Skynet_Tree_Reply, {}, error);
|
||||||
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|||||||
Reference in New Issue
Block a user