added button to download save files, updated readme

This commit is contained in:
majormjr 2016-04-20 08:22:51 -04:00
parent bb0aba974d
commit e0ac8fdbec
5 changed files with 57 additions and 71 deletions

View File

@ -28,34 +28,56 @@ Example:
```
## Building the server
## Development
The backend is built as a REST API via the Go web application.
It also acts as the webserver to serve the front end react application
All api actions are accessible with the /api route. The frontend is accessible with the root url.
All api actions are accessible with the /api route. The frontend is accessible from /.
### Requirements
+ Go 1.6
+ NodeJS 4.2.6
###Building Go backend
#### Building the Go backend
Go Application which manages the Factorio server.
API requests for managing the Factorio server are sent to /api.
The frontend code is served by a HTTP file server running on /.
```
git clone https://github.com/MajorMJR/factorio-server-manager.git
cd factorio-server-manager
go build
```
###building React frontend
install nodejs (use nvm)
cd static/js
npm install
npm run build
#### Building the React frontend
Frontend is built using React and the AdminLTE CSS framework. See app/dist/ for AdminLTE included files and license.
The root of the UI application is served at app/index.html. Run the npm build script and the Go application during development to get live rebuilding of the UI code.
All necessary CSS and Javascript files are included for running the UI.
Transpiled bundle.js application is output to app/bundle.js, 'npm run build' script starts webpack to build the React application for development
```
install nodejs (use nvm)
cd ui/
npm install
npm run build
Start factorio-server-manager binary in another terminal
```
## Contributing
1. Fork it!
2. Create your feature branch: `git checkout -b my-new-feature`
3. Commit your changes: `git commit -am 'Add some feature'`
4. Push to the branch: `git push origin my-new-feature`
5. Submit a pull request :D
## Authors
* **Mitch Roote** - [roote.me](https://roote.me)
See also the list of [contributors](https://github.com/your/project/contributors) who participated in this project.
## License
This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details

View File

@ -25858,7 +25858,7 @@
"Copyright © 2016 ",
_react2.default.createElement(
"a",
{ href: "#" },
{ href: "https://roote.me" },
"Mitch Roote"
),
"."
@ -26967,7 +26967,7 @@
/* 238 */
/***/ function(module, exports, __webpack_require__) {
"use strict";
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
@ -26997,61 +26997,40 @@
}
_createClass(Save, [{
key: "downloadSave",
value: function downloadSave(e) {
e.preventDefault();
var node = this.refs.saveName;
var saveName = node.name;
$.ajax({
url: "/api/saves/dl/" + saveName,
dataType: "json",
success: function success(data) {
console.log(data);
},
error: function error(xhr, status, err) {
console.log('api/mods/list', status, err.toString());
}
});
}
}, {
key: "render",
key: 'render',
value: function render() {
var saveLocation = "/api/saves/dl/" + this.props.save.name;
var saveSize = parseFloat(this.props.save.size / 1024 / 1024).toFixed(3);
var saveLastMod = Date.parse(this.props.save.last_mod);
var date = new Date(saveLastMod);
var dateFmt = date.getFullYear() + '-' + date.getMonth() + '-' + date.getDay() + ' ' + date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds();
return _react2.default.createElement(
"tr",
'tr',
null,
_react2.default.createElement(
"td",
'td',
null,
this.props.save.name
),
_react2.default.createElement(
"td",
'td',
null,
dateFmt
),
_react2.default.createElement(
"td",
'td',
null,
saveSize,
" MB"
' MB'
),
_react2.default.createElement(
"td",
'td',
null,
_react2.default.createElement(
"form",
{ onSubmit: this.downloadSave.bind(this) },
_react2.default.createElement("input", { className: "btn btn-default btn-sm",
ref: "saveName",
type: "submit",
value: "Download Save",
name: this.props.save.name
})
'a',
{ className: 'btn btn-default', href: saveLocation },
'Download'
)
)
);

View File

@ -13,6 +13,7 @@ func Index(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "hello world")
}
// Returns JSON response of all mods installed in factorio/mods
func ListInstalledMods(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
@ -23,6 +24,8 @@ func ListInstalledMods(w http.ResponseWriter, r *http.Request) {
}
}
// Toggles mod passed in through mod variable
// Updates mod-list.json file to toggle the enabled status of mods
func ToggleMod(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
@ -31,7 +34,7 @@ func ToggleMod(w http.ResponseWriter, r *http.Request) {
m, err := parseModList()
if err != nil {
log.Printf("Could parse mod list: %s", err)
log.Printf("Could not parse mod list: %s", err)
return
}
@ -46,8 +49,10 @@ func ToggleMod(w http.ResponseWriter, r *http.Request) {
}
}
// Returns JSON response of all mods in the mod-list.json file
func ListMods(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
m, err := parseModList()
if err != nil {
log.Printf("Could not parse mod list: %s", err)
@ -59,6 +64,7 @@ func ListMods(w http.ResponseWriter, r *http.Request) {
}
// Lists all save files in the factorio/saves directory
func ListSaves(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
@ -69,6 +75,7 @@ func ListSaves(w http.ResponseWriter, r *http.Request) {
}
}
// Returns last lines of the factorio-current.log file
func LogTail(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
@ -91,7 +98,7 @@ func DLSave(w http.ResponseWriter, r *http.Request) {
saveName := config.FactorioSavesDir + "/" + save
w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", save))
log.Printf("%s", saveName)
log.Printf("%s downloading: %s", r.Host, saveName)
http.ServeFile(w, r, saveName)
}

View File

@ -7,7 +7,7 @@ class Footer extends React.Component {
<div className="pull-right hidden-xs">
Anything you want!!!!!!
</div>
<strong>Copyright &copy; 2016 <a href="#">Mitch Roote</a>.</strong> MIT License.
<strong>Copyright &copy; 2016 <a href="https://roote.me">Mitch Roote</a>.</strong> MIT License.
</footer>
)
}

View File

@ -1,23 +1,8 @@
import React from 'react';
class Save extends React.Component {
downloadSave(e) {
e.preventDefault();
const node = this.refs.saveName;
const saveName = node.name;
$.ajax({
url: "/api/saves/dl/" + saveName,
dataType: "json",
success: (data) => {
console.log(data)
},
error: (xhr, status, err) => {
console.log('api/mods/list', status, err.toString());
}
})
}
render() {
let saveLocation = "/api/saves/dl/" + this.props.save.name
let saveSize = parseFloat(this.props.save.size / 1024 / 1024).toFixed(3)
let saveLastMod = Date.parse(this.props.save.last_mod);
let date = new Date(saveLastMod)
@ -30,14 +15,7 @@ class Save extends React.Component {
<td>{dateFmt}</td>
<td>{saveSize} MB</td>
<td>
<form onSubmit={this.downloadSave.bind(this)}>
<input className='btn btn-default btn-sm'
ref='saveName'
type='submit'
value='Download Save'
name={this.props.save.name}
/>
</form>
<a className="btn btn-default" href={saveLocation}>Download</a>
</td>
</tr>
)