diff --git a/README.md b/README.md index 6178b4b..f7ca090 100644 --- a/README.md +++ b/README.md @@ -21,8 +21,10 @@ then navigate to `localhost:3000` initially the heavy lifting was done by the server, but the need for a better frontend was clear. +full documentation coming soon once actual functionality has been nailed down. + ## credits svg icons via https://iconsvg.xyz -raspberry pi svg via https://www.vectorlogo.zone/logos/raspberrypi/index.html \ No newline at end of file +raspberry pi svg via https://www.vectorlogo.zone/logos/raspberrypi/index.html diff --git a/assets/web/index.html b/assets/web/index.html index 09fdf5b..921a3ea 100644 --- a/assets/web/index.html +++ b/assets/web/index.html @@ -3,14 +3,17 @@ - Home | PiNas + Home | GoNAS
- -

PiNas

+

GoNAS

+

Hot Storage Usage (%)

+ +

Cold Storage Usage (%)

+
@@ -19,5 +22,31 @@ Cold Files
+ \ No newline at end of file diff --git a/assets/web/listing.html b/assets/web/listing.html index f63b36c..6589e27 100644 --- a/assets/web/listing.html +++ b/assets/web/listing.html @@ -3,7 +3,7 @@ - | PiNas + | GoNAS @@ -16,7 +16,7 @@ -

PiNas

+

GoNAS

@@ -31,7 +31,7 @@
- +

..

diff --git a/assets/web/static/app.js b/assets/web/static/app.js index 0af65cf..f25e00c 100644 --- a/assets/web/static/app.js +++ b/assets/web/static/app.js @@ -1,4 +1,4 @@ -const $ = element => document.getElementById(element); +const $ = selector => document.querySelector(selector); const init = event => { var path = window.location.pathname; @@ -12,9 +12,9 @@ const init = event => { buildList(json); }); - $("path-header").innerText = path; - - document.querySelector("body").addEventListener('contextmenu', function(ev) { + $("#path-header").innerText = path; + $("#path").value = path; + document.querySelector("body").addEventListener('contextmenu', function (ev) { if (ev.target.localName == "a") { ev.preventDefault(); @@ -28,13 +28,13 @@ const init = event => { return false; }, false); - document.querySelector("body").addEventListener('click', function(ev) { + $("body").addEventListener('click', function (ev) { let shouldDismiss = ev.target.dataset.dismissContext == undefined && ev.target.parentElement.classList.contains("context-actions") == false && ev.target.localName != 'a'; if (ev.which == 1 && shouldDismiss) { ev.preventDefault(); - var d = document.getElementById('context'); + var d = $('#context'); d.classList.add("hidden"); return false; } @@ -58,20 +58,19 @@ const buildList = data => { if (data.Files[i].IsDirectory == true) { fileItem.classList.add("directory"); fileLink.href = "/" + data.Prefix + "/" + data.Path + "/" + data.Files[i].Name; - } - else { + } else { fileItem.classList.add("file"); fileLink.href = "/" + data.SinglePrefix + "/" + data.Path + "/" + data.Files[i].Name; } fileLink.innerText = data.Files[i].Name; fileItem.appendChild(fileLink); - document.getElementById("filelist").appendChild(fileItem); + $("#filelist").appendChild(fileItem); } } const upload = (file, path) => { - var formData = new FormData(); + var formData = new FormData(); formData.append("path", path); formData.append("file", file); fetch('/upload', { // Your POST endpoint diff --git a/assets/web/static/styles.css b/assets/web/static/styles.css index 8afc72d..ded43ef 100644 --- a/assets/web/static/styles.css +++ b/assets/web/static/styles.css @@ -96,4 +96,8 @@ a.back-button { .context-actions li { border-bottom: 1px solid black; cursor: pointer; +} + +progress[value] { + height: 20px; } \ No newline at end of file diff --git a/files/files.go b/files/files.go index 2394c2a..aaabc97 100644 --- a/files/files.go +++ b/files/files.go @@ -44,7 +44,7 @@ func Listing(tier string) common.Handler { panic(err) } - var config Config; + var config Config err = json.Unmarshal(d, &config) if err != nil { panic(err) diff --git a/router/router.go b/router/router.go index 910c044..9713f79 100644 --- a/router/router.go +++ b/router/router.go @@ -7,6 +7,7 @@ import ( "github.com/gmemstr/nas/common" "github.com/gmemstr/nas/files" + "github.com/gmemstr/nas/system" "github.com/gorilla/mux" ) @@ -61,6 +62,9 @@ func Init() *mux.Router { fileList(), )).Methods("GET") + r.Handle("/api/diskusage", Handle( + system.DiskUsages(), + )).Methods("GET") r.Handle("/api/files/", Handle( files.Listing("hot"), diff --git a/system/system.go b/system/system.go new file mode 100644 index 0000000..b4c5a89 --- /dev/null +++ b/system/system.go @@ -0,0 +1,72 @@ +package system + +import ( + "encoding/json" + "github.com/gmemstr/nas/common" + "io/ioutil" + "net/http" + "syscall" +) + +type Config struct { + ColdStorage string + HotStorage string +} + +type UsageStat struct { + Available int64 + Free int64 + Total int64 +} + +type UsageStats struct { + ColdStorage UsageStat + HotStorage UsageStat +} + +func DiskUsages() common.Handler { + + return func(rc *common.RouterContext, w http.ResponseWriter, r *http.Request) *common.HTTPError { + var statHot syscall.Statfs_t + var statCold syscall.Statfs_t + + d, err := ioutil.ReadFile("assets/config/config.json") + if err != nil { + panic(err) + } + + var config Config + err = json.Unmarshal(d, &config) + if err != nil { + panic(err) + } + + // Default to hot storage + storage := config.HotStorage + err = syscall.Statfs(storage, &statHot) + if err != nil { + panic(err) + } + hotStats := UsageStat{ + Free: statHot.Bsize * int64(statHot.Bfree), + Total: statHot.Bsize * int64(statHot.Blocks), + } + storage = config.ColdStorage + err = syscall.Statfs(storage, &statCold) + if err != nil { + panic(err) + } + coldStats := UsageStat{ + Free: statCold.Bsize * int64(statCold.Bfree), + Total: statCold.Bsize * int64(statCold.Blocks), + } + usages := UsageStats{ + HotStorage: hotStats, + ColdStorage: coldStats, + } + // Available blocks * size per block = available space in bytes + resultJson, err := json.Marshal(usages) + w.Write(resultJson) + return nil + } +} \ No newline at end of file