Start of the web frontend and backend for config handling.

This commit is contained in:
Justin Hawkins 2021-09-28 22:09:12 +09:30
parent 7500a30f6b
commit 2aba19770f
5 changed files with 141 additions and 20 deletions

View File

@ -7,27 +7,27 @@ import (
) )
type Server struct { type Server struct {
Port int `yaml:"port"` Port int `yaml:"port" json:"port"`
Address string `yaml:"address"` Address string `yaml:"address" json:"address"`
DownloadPath string `yaml:"download_path"` DownloadPath string `yaml:"download_path" json:"download_path"`
} }
type DownloadProfile struct { type DownloadProfile struct {
Name string `yaml:"name"` Name string `yaml:"name" json:"name"`
Command string `yaml:"command"` Command string `yaml:"command" json:"command"`
Args []string `yaml:"args"` Args []string `yaml:"args" json:"args"`
} }
type UI struct { type UI struct {
PopupWidth int `yaml:"popup_width"` PopupWidth int `yaml:"popup_width" json:"popup_width"`
PopupHeight int `yaml:"popup_height"` PopupHeight int `yaml:"popup_height" json:"popup_height"`
} }
type Config struct { type Config struct {
Server Server `yaml:"server"` Server Server `yaml:"server" json:"server"`
UI UI `yaml:"ui"` UI UI `yaml:"ui" json:"ui"`
DownloadProfiles []DownloadProfile `yaml:"profiles"` DownloadProfiles []DownloadProfile `yaml:"profiles" json:"profiles"`
ConfigVersion int `yaml:"config_version"` ConfigVersion int `yaml:"config_version" json:"config_version"`
} }
func DefaultConfig() Config { func DefaultConfig() Config {
@ -41,11 +41,14 @@ func DefaultConfig() Config {
defaultConfig.DownloadProfiles = append(defaultConfig.DownloadProfiles, stdProfile) defaultConfig.DownloadProfiles = append(defaultConfig.DownloadProfiles, stdProfile)
defaultConfig.Server.Port = 6123 defaultConfig.Server.Port = 6123
defaultConfig.Server.Address = "localhost:6123" defaultConfig.Server.Address = "http://localhost:6123"
defaultConfig.Server.DownloadPath = "./" defaultConfig.Server.DownloadPath = "./"
defaultConfig.UI.PopupWidth = 500 defaultConfig.UI.PopupWidth = 500
defaultConfig.UI.PopupHeight = 500 defaultConfig.UI.PopupHeight = 500
defaultConfig.ConfigVersion = 1
return defaultConfig return defaultConfig
} }

32
main.go
View File

@ -37,7 +37,7 @@ type download struct {
var downloads []*download var downloads []*download
var downloadId = 0 var downloadId = 0
var versionInfo = version.Info{CurrentVersion: "v0.4.0"} var versionInfo = version.Info{CurrentVersion: "v0.5.0"}
//go:embed web //go:embed web
var webFS embed.FS var webFS embed.FS
@ -49,10 +49,13 @@ func main() {
r := mux.NewRouter() r := mux.NewRouter()
r.HandleFunc("/", HomeHandler) r.HandleFunc("/", HomeHandler)
r.HandleFunc("/config", ConfigHandler)
r.HandleFunc("/fetch", FetchHandler) r.HandleFunc("/fetch", FetchHandler)
r.HandleFunc("/fetch/info", FetchInfoHandler)
r.HandleFunc("/fetch/info/{id}", FetchInfoOneHandler) r.HandleFunc("/rest/fetch/info", FetchInfoHandler)
r.HandleFunc("/version", VersionHandler) r.HandleFunc("/rest/fetch/info/{id}", FetchInfoOneHandler)
r.HandleFunc("/rest/version", VersionHandler)
r.HandleFunc("/rest/config", ConfigRESTHandler)
http.Handle("/", r) http.Handle("/", r)
@ -113,6 +116,27 @@ func HomeHandler(w http.ResponseWriter, r *http.Request) {
} }
func ConfigHandler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
t, err := template.ParseFS(webFS, "web/layout.tmpl", "web/config.html")
if err != nil {
panic(err)
}
err = t.ExecuteTemplate(w, "layout", nil)
if err != nil {
panic(err)
}
}
func ConfigRESTHandler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
b, _ := json.Marshal(conf)
w.Write(b)
}
func FetchInfoOneHandler(w http.ResponseWriter, r *http.Request) { func FetchInfoOneHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r) vars := mux.Vars(r)
idString := vars["id"] idString := vars["id"]

92
web/config.html Normal file
View File

@ -0,0 +1,92 @@
{{ define "content" }}
<div x-data="config()" x-init="fetch_config();">
<h2>gropple config</h2>
<p x-show="version && version.upgrade_available">
<a href="https://github.com/tardisx/gropple/releases">Upgrade is available</a> -
you have
<span x-text="version.current_version"></span> and
<span x-text="version.github_version"></span>
is available.</p>
<div class="pure-g">
<div class="pure-u-md-1-2">
<form class="pure-form pure-form-stacked">
<fieldset>
<legend>Server</legend>
<label for="config-server-port">Listen Port</label>
<input type="text" id="config-server-port" placeholder="port number" x-model="config.server.port" />
<span class="pure-form-message">The port the web server will listen on.</span>
<label for="config-server-address">Server address (URL)</label>
<input type="text" id="config-server-address" placeholder="server address" x-model="config.server.address" />
<span class="pure-form-message">
The address the service will be available on. Generally it will be http://hostname:port where
hostname is the host the server is running on, and port is the port you set above.
</span>
<label for="config-server-downloadpath">Download path</label>
<input type="text" id="config-server-downloadpath" placeholder="path" x-model="config.server.download_path" />
<span class="pure-form-message">The path on the server to download files to.</span>
<legend>UI</legend>
<label for="config-ui-popupwidth">Popup Width</label>
<input type="text" id="config-ui-popupwidth" placeholder="width in pixels" x-model="config.ui.popup_width" />
<span class="pure-form-message">The width of popup windows in pixels.</span>
<label for="config-ui-popupheight">Popup Height</label>
<input type="text" id="config-ui-popupheight" placeholder="height in pixels" x-model="config.ui.popup_height" />
<span class="pure-form-message">The height of popup windows in pixels.</span>
</fieldset>
</form>
</div>
<div class="pure-u-md-1-2">
<form class="pure-form pure-form-stacked">
<fieldset>
<legend>Download Profiles</legend>
<label for="config-profiles-0-name">Name of this profile</label>
<input type="text" id="config-profiles-0-name" placeholder="name" x-model="config.profiles[0].name" />
<span class="pure-form-message">The name of this profile. For your information only.</span>
</fieldset>
</form>
</div>
</div>
</div>
{{ end }}
{{ define "js" }}
<script>
function config() {
return {
config: { server : {}, ui : {}, profiles: [{}] }, version: {},
fetch_config() {
fetch('/rest/config')
.then(response => response.json())
.then(config => {
this.config = config;
})
.catch(error => {
console.log('failed to fetch version info - will retry');
setTimeout(() => { this.fetch_version() }, 1000 );
});
},
}
}
</script>
{{ end }}

View File

@ -19,6 +19,8 @@
</p> </p>
</div> </div>
<a href="/config">config</a>
<table class="pure-table"> <table class="pure-table">
<thead> <thead>
<tr> <tr>
@ -53,7 +55,7 @@
return { return {
items: [], version: {}, items: [], version: {},
fetch_version() { fetch_version() {
fetch('/version') fetch('/rest/version')
.then(response => response.json()) .then(response => response.json())
.then(info => { .then(info => {
this.version = info; this.version = info;
@ -65,7 +67,7 @@
}); });
}, },
fetch_data() { fetch_data() {
fetch('/fetch/info') fetch('/rest/fetch/info')
.then(response => response.json()) .then(response => response.json())
.then(info => { .then(info => {
// will be null if no downloads yet // will be null if no downloads yet

View File

@ -22,7 +22,7 @@
return { return {
eta: '', percent: 0.0, state: '??', filename: '', finished: false, log :'', eta: '', percent: 0.0, state: '??', filename: '', finished: false, log :'',
fetch_data() { fetch_data() {
fetch('/fetch/info/{{ .Id }}') fetch('/rest/fetch/info/{{ .Id }}')
.then(response => response.json()) .then(response => response.json())
.then(info => { .then(info => {
this.eta = info.eta; this.eta = info.eta;