added handler for creating save files

This commit is contained in:
majormjr
2016-04-24 21:38:06 -04:00
parent 96139c8cad
commit a19dbef3f6
11 changed files with 484 additions and 102 deletions
+274 -64
View File
@@ -72,11 +72,11 @@
var _SavesContent2 = _interopRequireDefault(_SavesContent);
var _ConfigContent = __webpack_require__(239);
var _ConfigContent = __webpack_require__(241);
var _ConfigContent2 = _interopRequireDefault(_ConfigContent);
var _Index = __webpack_require__(241);
var _Index = __webpack_require__(243);
var _Index2 = _interopRequireDefault(_Index);
@@ -26882,6 +26882,14 @@
var _SavesList2 = _interopRequireDefault(_SavesList);
var _CreateSave = __webpack_require__(239);
var _CreateSave2 = _interopRequireDefault(_CreateSave);
var _UploadSave = __webpack_require__(240);
var _UploadSave2 = _interopRequireDefault(_UploadSave);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
@@ -26983,6 +26991,24 @@
_react2.default.createElement(
'section',
{ className: 'content' },
_react2.default.createElement(
'div',
{ className: 'row' },
_react2.default.createElement(
'div',
{ className: 'col-md-6' },
_react2.default.createElement(_CreateSave2.default, {
getSaves: this.getSaves
})
),
_react2.default.createElement(
'div',
{ className: 'col-md-6' },
_react2.default.createElement(_UploadSave2.default, {
getSaves: this.getSaves
})
)
),
_react2.default.createElement(_SavesList2.default, _extends({}, this.state, {
dlSave: this.dlSave,
getSaves: this.getSaves
@@ -27034,7 +27060,6 @@
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(SavesList).call(this, props));
_this.updateSavesList = _this.updateSavesList.bind(_this);
_this.uploadFile = _this.uploadFile.bind(_this);
_this.removeSave = _this.removeSave.bind(_this);
return _this;
}
@@ -27044,25 +27069,6 @@
value: function updateSavesList() {
this.props.getSaves();
}
}, {
key: 'uploadFile',
value: function uploadFile(e) {
var fd = new FormData();
fd.append('savefile', this.refs.file.files[0]);
$.ajax({
url: "/api/saves/upload",
type: "POST",
data: fd,
processData: false,
contentType: false,
success: function success(data) {
alert(data);
}
});
e.preventDefault();
this.updateSavesList();
}
}, {
key: 'removeSave',
value: function removeSave(saveName, e) {
@@ -27094,42 +27100,6 @@
_react2.default.createElement(
'div',
{ className: 'box-body' },
_react2.default.createElement(
'div',
{ className: 'box' },
_react2.default.createElement(
'div',
{ className: 'box-header' },
_react2.default.createElement(
'h4',
{ className: 'box-title' },
'Upload Save File'
)
),
_react2.default.createElement(
'div',
{ className: 'box-body' },
_react2.default.createElement(
'form',
{ ref: 'uploadForm', className: 'form-inline', encType: 'multipart/form-data' },
_react2.default.createElement(
'div',
{ className: 'form-group' },
_react2.default.createElement(
'label',
{ 'for': 'savefile' },
'Upload Save File...'
),
_react2.default.createElement('input', { className: 'form-control btn btn-default', ref: 'file', type: 'file', name: 'savefile', id: 'savefile' })
),
_react2.default.createElement(
'div',
{ className: 'form-group' },
_react2.default.createElement('input', { className: 'form-control btn btn-default', type: 'button', ref: 'button', value: 'Upload', onClick: this.uploadFile })
)
)
)
),
_react2.default.createElement(
'div',
{ className: 'table-responsive' },
@@ -27302,6 +27272,137 @@
/***/ },
/* 239 */
/***/ function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(1);
var _react2 = _interopRequireDefault(_react);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var CreateSave = function (_React$Component) {
_inherits(CreateSave, _React$Component);
function CreateSave(props) {
_classCallCheck(this, CreateSave);
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(CreateSave).call(this, props));
_this.createSaveFile = _this.createSaveFile.bind(_this);
_this.updateSavesList = _this.updateSavesList.bind(_this);
_this.state = {
loading: false
};
return _this;
}
_createClass(CreateSave, [{
key: "updateSavesList",
value: function updateSavesList() {
this.props.getSaves();
}
}, {
key: "createSaveFile",
value: function createSaveFile(e) {
var _this2 = this;
this.setState({ loading: true });
$.ajax({
url: "/api/saves/create/" + this.refs.savename.value,
dataType: "json",
success: function success(data) {
console.log(data);
if (data.success === true) {
alert(data.data);
_this2.updateSavesList();
_this2.setState({ loading: false });
} else {
alert(data.data);
document.getElementById('uploadsave').removeChild(loading);
_this2.setState({ loading: false });
}
}
});
}
}, {
key: "render",
value: function render() {
var loadingOverlay;
if (this.state.loading) {
loadingOverlay = _react2.default.createElement(
"div",
{ className: "overlay" },
_react2.default.createElement("i", { className: "fa fa-refresh fa-spin" })
);
} else {
loadingOverlay = "";
}
return _react2.default.createElement(
"div",
{ className: "box", id: "uploadsave" },
_react2.default.createElement(
"div",
{ className: "box-header" },
_react2.default.createElement(
"h4",
{ className: "box-title" },
"Create Save File"
)
),
_react2.default.createElement(
"div",
{ className: "box-body" },
_react2.default.createElement(
"form",
null,
_react2.default.createElement(
"div",
{ className: "form-group" },
_react2.default.createElement(
"label",
{ "for": "savefile" },
"Enter Savefile Name... "
),
_react2.default.createElement("input", { className: "form-control", ref: "savename", type: "text", name: "savefile", id: "savefilename" })
),
_react2.default.createElement(
"div",
{ className: "form-group" },
_react2.default.createElement("input", { className: "form-control btn btn-default", type: "button", ref: "button", value: "Create", onClick: this.createSaveFile })
)
)
),
loadingOverlay
);
}
}]);
return CreateSave;
}(_react2.default.Component);
CreateSave.propTypes = {
getSaves: _react2.default.PropTypes.func.isRequired
};
exports.default = CreateSave;
/***/ },
/* 240 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
@@ -27316,7 +27417,119 @@
var _react2 = _interopRequireDefault(_react);
var _Settings = __webpack_require__(240);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var UploadSave = function (_React$Component) {
_inherits(UploadSave, _React$Component);
function UploadSave(props) {
_classCallCheck(this, UploadSave);
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(UploadSave).call(this, props));
_this.updateSavesList = _this.updateSavesList.bind(_this);
_this.uploadFile = _this.uploadFile.bind(_this);
return _this;
}
_createClass(UploadSave, [{
key: 'updateSavesList',
value: function updateSavesList() {
this.props.getSaves();
}
}, {
key: 'uploadFile',
value: function uploadFile(e) {
var fd = new FormData();
fd.append('savefile', this.refs.file.files[0]);
$.ajax({
url: "/api/saves/upload",
type: "POST",
data: fd,
processData: false,
contentType: false,
success: function success(data) {
alert(data);
}
});
e.preventDefault();
this.updateSavesList();
}
}, {
key: 'render',
value: function render() {
return _react2.default.createElement(
'div',
{ className: 'box' },
_react2.default.createElement(
'div',
{ className: 'box-header' },
_react2.default.createElement(
'h4',
{ className: 'box-title' },
'Upload Save File'
)
),
_react2.default.createElement(
'div',
{ className: 'box-body' },
_react2.default.createElement(
'form',
{ ref: 'uploadForm', className: 'form-inline', encType: 'multipart/form-data' },
_react2.default.createElement(
'div',
{ className: 'form-group' },
_react2.default.createElement(
'label',
{ 'for': 'savefile' },
'Upload Save File...'
),
_react2.default.createElement('input', { className: 'form-control btn btn-default', ref: 'file', type: 'file', name: 'savefile', id: 'savefile' })
),
_react2.default.createElement(
'div',
{ className: 'form-group' },
_react2.default.createElement('input', { className: 'form-control btn btn-default', type: 'button', ref: 'button', value: 'Upload', onClick: this.uploadFile })
)
)
)
);
}
}]);
return UploadSave;
}(_react2.default.Component);
UploadSave.propTypes = {
getSaves: _react2.default.PropTypes.func.isRequired
};
exports.default = UploadSave;
/***/ },
/* 241 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(1);
var _react2 = _interopRequireDefault(_react);
var _Settings = __webpack_require__(242);
var _Settings2 = _interopRequireDefault(_Settings);
@@ -27477,7 +27690,7 @@
exports.default = ConfigContent;
/***/ },
/* 240 */
/* 242 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
@@ -27486,8 +27699,6 @@
value: true
});
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = __webpack_require__(1);
@@ -27518,7 +27729,6 @@
'tbody',
null,
Object.keys(this.props.config).map(function (key) {
console.log(typeof key === 'undefined' ? 'undefined' : _typeof(key));
return _react2.default.createElement(
'tr',
{ key: key },
@@ -27549,7 +27759,7 @@
exports.default = Settings;
/***/ },
/* 241 */
/* 243 */
/***/ function(module, exports, __webpack_require__) {
"use strict";
+37 -1
View File
@@ -42,7 +42,6 @@ func ListInstalledMods(w http.ResponseWriter, r *http.Request) {
resp.Success = true
fmt.Printf("%+v", resp)
if err := json.NewEncoder(w).Encode(resp); err != nil {
log.Printf("Error in list mods: %s", err)
}
@@ -328,6 +327,43 @@ func RemoveSave(w http.ResponseWriter, r *http.Request) {
}
}
// Launches Factorio server binary with --create flag to create save
// Url must include save name for creation of savefile
func CreateSaveHandler(w http.ResponseWriter, r *http.Request) {
var err error
resp := JSONResponse{
Success: false,
}
vars := mux.Vars(r)
saveName := vars["save"]
if saveName == "" {
log.Printf("Error creating save, no name provided: %s", err)
resp.Data = "No save name provided."
if err := json.NewEncoder(w).Encode(resp); err != nil {
log.Printf("Error encoding save handler response: %s", err)
}
return
}
cmdOut, err := createSave(saveName)
if err != nil {
log.Printf("Error creating save: %s", err)
resp.Data = "Error creating savefile."
if err := json.NewEncoder(w).Encode(resp); err != nil {
log.Printf("Error encoding save handler response: %s", err)
}
return
}
resp.Success = true
resp.Data = fmt.Sprintf("Save %s created successfully. Command output: \n%s", saveName, cmdOut)
if err := json.NewEncoder(w).Encode(resp); err != nil {
log.Printf("Error encoding save response: %s", err)
}
}
// Returns last lines of the factorio-current.log file
func LogTail(w http.ResponseWriter, r *http.Request) {
var err error
+1 -1
View File
@@ -34,7 +34,7 @@ func loadFlags() {
config.FactorioSavesDir = config.FactorioDir + "/saves"
config.FactorioModsDir = config.FactorioDir + "/mods"
config.FactorioConfigFile = config.FactorioDir + "/" + *factorioConfigFile
config.FactorioBinary = config.FactorioDir + *factorioBinary
config.FactorioBinary = config.FactorioDir + "/" + *factorioBinary
config.ServerIP = *factorioIP
config.ServerPort = *factorioPort
config.FactorioLog = config.FactorioDir + "/factorio-current.log"
+5
View File
@@ -108,6 +108,11 @@ var apiRoutes = Routes{
"GET",
"/saves/rm/{save}",
RemoveSave,
}, {
"CreateSave",
"GET",
"/saves/create/{save}",
CreateSaveHandler,
}, {
"LogTail",
"GET",
+19
View File
@@ -1 +1,20 @@
package main
import (
"log"
"os/exec"
)
func createSave(saveName string) (string, error) {
args := []string{"--create", saveName}
cmdOutput, err := exec.Command(config.FactorioBinary, args...).Output()
if err != nil {
log.Printf("Error in creating Factorio save: %s", err)
return "", err
}
result := string(cmdOutput)
return result, nil
}
-1
View File
@@ -9,7 +9,6 @@ class Settings extends React.Component {
return(
<tbody>
{Object.keys(this.props.config).map(function(key) {
console.log(typeof key);
return(
<tr key={key}>
<td>{key}</td>
+1
View File
@@ -27,6 +27,7 @@ class ConfigContent extends React.Component {
}
});
}
render() {
return(
<div className="content-wrapper">
+75
View File
@@ -0,0 +1,75 @@
import React from 'react';
class CreateSave extends React.Component {
constructor(props) {
super(props);
this.createSaveFile = this.createSaveFile.bind(this);
this.updateSavesList = this.updateSavesList.bind(this)
this.state = {
loading: false,
}
}
updateSavesList() {
this.props.getSaves();
}
createSaveFile(e) {
this.setState({loading: true});
$.ajax({
url: "/api/saves/create/" + this.refs.savename.value,
dataType: "json",
success: (data) => {
console.log(data);
if (data.success === true) {
alert(data.data)
this.updateSavesList();
this.setState({loading: false});
} else {
alert(data.data)
document.getElementById('uploadsave').removeChild(loading);
this.setState({loading: false});
}
}
})
}
render() {
var loadingOverlay
if (this.state.loading) {
loadingOverlay =
<div className="overlay">
<i className="fa fa-refresh fa-spin"></i>
</div>
} else {
loadingOverlay = ""
}
return(
<div className="box" id="uploadsave">
<div className="box-header">
<h4 className="box-title">Create Save File</h4>
</div>
<div className="box-body">
<form>
<div className="form-group">
<label for="savefile">Enter Savefile Name... </label>
<input className="form-control" ref="savename" type="text" name="savefile" id="savefilename" />
</div>
<div className="form-group">
<input className="form-control btn btn-default" type="button" ref="button" value="Create" onClick={this.createSaveFile} />
</div>
</form>
</div>
{loadingOverlay}
</div>
)
}
}
CreateSave.propTypes = {
getSaves: React.PropTypes.func.isRequired,
}
export default CreateSave
-35
View File
@@ -5,7 +5,6 @@ class SavesList extends React.Component {
constructor(props) {
super(props);
this.updateSavesList = this.updateSavesList.bind(this);
this.uploadFile = this.uploadFile.bind(this);
this.removeSave = this.removeSave.bind(this);
}
@@ -13,24 +12,6 @@ class SavesList extends React.Component {
this.props.getSaves();
}
uploadFile(e) {
var fd = new FormData();
fd.append('savefile', this.refs.file.files[0]);
$.ajax({
url: "/api/saves/upload",
type: "POST",
data: fd,
processData: false,
contentType: false,
success: (data) => {
alert(data)
}
});
e.preventDefault();
this.updateSavesList();
}
removeSave(saveName, e) {
$.ajax({
url: "/api/saves/rm/" + saveName,
@@ -49,22 +30,6 @@ class SavesList extends React.Component {
</div>
<div className="box-body">
<div className="box">
<div className="box-header">
<h4 className="box-title">Upload Save File</h4>
</div>
<div className="box-body">
<form ref="uploadForm" className="form-inline" encType='multipart/form-data'>
<div className="form-group">
<label for="savefile">Upload Save File...</label>
<input className="form-control btn btn-default" ref="file" type="file" name="savefile" id="savefile" />
</div>
<div className="form-group">
<input className="form-control btn btn-default" type="button" ref="button" value="Upload" onClick={this.uploadFile} />
</div>
</form>
</div>
</div>
<div className="table-responsive">
<table className="table table-striped">
+58
View File
@@ -0,0 +1,58 @@
import React from 'react';
class UploadSave extends React.Component {
constructor(props) {
super(props)
this.updateSavesList = this.updateSavesList.bind(this);
this.uploadFile = this.uploadFile.bind(this);
}
updateSavesList() {
this.props.getSaves();
}
uploadFile(e) {
var fd = new FormData();
fd.append('savefile', this.refs.file.files[0]);
$.ajax({
url: "/api/saves/upload",
type: "POST",
data: fd,
processData: false,
contentType: false,
success: (data) => {
alert(data)
}
});
e.preventDefault();
this.updateSavesList();
}
render() {
return(
<div className="box">
<div className="box-header">
<h4 className="box-title">Upload Save File</h4>
</div>
<div className="box-body">
<form ref="uploadForm" className="form-inline" encType='multipart/form-data'>
<div className="form-group">
<label for="savefile">Upload Save File...</label>
<input className="form-control btn btn-default" ref="file" type="file" name="savefile" id="savefile" />
</div>
<div className="form-group">
<input className="form-control btn btn-default" type="button" ref="button" value="Upload" onClick={this.uploadFile} />
</div>
</form>
</div>
</div>
)
}
}
UploadSave.propTypes = {
getSaves: React.PropTypes.func.isRequired,
}
export default UploadSave
+14
View File
@@ -1,5 +1,7 @@
import React from 'react';
import SavesList from './Saves/SavesList.jsx';
import CreateSave from './Saves/CreateSave.jsx';
import UploadSave from './Saves/UploadSave.jsx';
class SavesContent extends React.Component {
constructor(props) {
@@ -56,6 +58,18 @@ class SavesContent extends React.Component {
</section>
<section className="content">
<div className="row">
<div className="col-md-6">
<CreateSave
getSaves={this.getSaves}
/>
</div>
<div className="col-md-6">
<UploadSave
getSaves={this.getSaves}
/>
</div>
</div>
<SavesList
{...this.state}