Merge pull request #22 from RiV-chain/offline_ui

load index.html from file resource
This commit is contained in:
Vadym Vikulin 2022-11-26 16:29:44 +02:00 committed by GitHub
commit d834b2515f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 175 additions and 161 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
.history

4
contrib/ui/mesh-ui/assets/all.min.css vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -6,8 +6,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>RiV-mesh</title> <title>RiV-mesh</title>
<link rel="stylesheet" href="https://maxst.icons8.com/vue-static/landings/line-awesome/font-awesome-line-awesome/css/all.min.css" type="text/css"> <link rel="stylesheet" href="assets/all.min.css" type="text/css">
<link rel="stylesheet" href="https://unpkg.com/bulmaswatch/slate/bulmaswatch.min.css" type="text/css"> <link rel="stylesheet" href="assets/bulmaswatch.min.css" type="text/css">
<script> <script>
function setFieldValue(id, value){ function setFieldValue(id, value){

Binary file not shown.

View file

@ -1,162 +1,164 @@
package main package main
import ( import (
"github.com/webview/webview" "encoding/json"
"github.com/hjson/hjson-go" "fmt"
"encoding/json" "io/ioutil"
"path/filepath" "log"
"io/ioutil" "net"
"os/exec" "net/url"
"net/url" "os"
"runtime" "os/exec"
"strings" "path/filepath"
"strconv" "runtime"
"time" "strconv"
"net" "strings"
"log" "time"
"fmt"
"os"
"github.com/RiV-chain/RiV-mesh/src/admin" "github.com/hjson/hjson-go"
"github.com/webview/webview"
"github.com/RiV-chain/RiV-mesh/src/admin"
) )
var riv_ctrl_path string var riv_ctrl_path string
func main() { func main() {
debug := true debug := true
w := webview.New(debug) w := webview.New(debug)
defer w.Destroy() defer w.Destroy()
w.SetTitle("RiV-mesh") w.SetTitle("RiV-mesh")
w.SetSize(690, 920, webview.HintFixed) w.SetSize(690, 920, webview.HintFixed)
/*1. Create ~/.riv-mesh folder if not existing /*1. Create ~/.riv-mesh folder if not existing
*2. Create ~/.riv-mesh/mesh.conf if not existing *2. Create ~/.riv-mesh/mesh.conf if not existing
*3. If the file exists read Peers. *3. If the file exists read Peers.
*3.1 Invoke add peers for each record *3.1 Invoke add peers for each record
*/ */
mesh_folder := ".riv-mesh" mesh_folder := ".riv-mesh"
mesh_conf := "mesh.conf" mesh_conf := "mesh.conf"
user_home := get_user_home_path() user_home := get_user_home_path()
mesh_settings_folder := filepath.Join(user_home, mesh_folder) mesh_settings_folder := filepath.Join(user_home, mesh_folder)
err := os.MkdirAll(mesh_settings_folder, os.ModePerm) err := os.MkdirAll(mesh_settings_folder, os.ModePerm)
if err != nil { if err != nil {
fmt.Printf("Unable to create folder: %v", err) fmt.Printf("Unable to create folder: %v", err)
} }
mesh_settings_path := filepath.Join(user_home, mesh_folder, mesh_conf) mesh_settings_path := filepath.Join(user_home, mesh_folder, mesh_conf)
riv_ctrl_path = get_ctl_path() riv_ctrl_path = get_ctl_path()
if _, err := os.Stat(mesh_settings_path); os.IsNotExist(err) { if _, err := os.Stat(mesh_settings_path); os.IsNotExist(err) {
err := ioutil.WriteFile(mesh_settings_path, []byte(""), 0750) err := ioutil.WriteFile(mesh_settings_path, []byte(""), 0750)
if err != nil { if err != nil {
fmt.Printf("Unable to write file: %v", err) fmt.Printf("Unable to write file: %v", err)
} }
} else { } else {
//read peers from mesh.conf //read peers from mesh.conf
conf, _ := ioutil.ReadFile(mesh_settings_path) conf, _ := ioutil.ReadFile(mesh_settings_path)
var dat map[string]interface {} var dat map[string]interface{}
if err := hjson.Unmarshal(conf, &dat); err != nil { if err := hjson.Unmarshal(conf, &dat); err != nil {
fmt.Printf("Unable to parse mesh.conf file: %v", err) fmt.Printf("Unable to parse mesh.conf file: %v", err)
} else { } else {
if dat["Peers"]!=nil { if dat["Peers"] != nil {
peers := dat["Peers"].([]interface{}) peers := dat["Peers"].([]interface{})
remove_peers() remove_peers()
for _, u := range peers { for _, u := range peers {
log.Printf("Unmarshaled: %v", u.(string)) log.Printf("Unmarshaled: %v", u.(string))
add_peers(u.(string)) add_peers(u.(string))
} }
} else { } else {
fmt.Printf("Warning: Peers array not loaded from mesh.conf file") fmt.Printf("Warning: Peers array not loaded from mesh.conf file")
} }
} }
} }
var path string var path string
if len(os.Args)>1 { if len(os.Args) > 1 {
path, err = filepath.Abs(filepath.Dir(os.Args[1])) path, err = filepath.Abs(filepath.Dir(os.Args[1]))
} else { } else {
path, err = filepath.Abs(filepath.Dir(os.Args[0])) path, err = filepath.Abs(filepath.Dir(os.Args[0]))
} }
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
log.Println(path) log.Println(path)
w.Bind("onLoad", func() { w.Bind("onLoad", func() {
log.Println("page loaded") log.Println("page loaded")
go run(w) go run(w)
}) })
w.Bind("savePeers", func(peer_list string) { w.Bind("savePeers", func(peer_list string) {
//log.Println("peers saved ", peer_list) //log.Println("peers saved ", peer_list)
var peers []string var peers []string
_ = json.Unmarshal([]byte(peer_list), &peers) _ = json.Unmarshal([]byte(peer_list), &peers)
log.Printf("Unmarshaled: %v", peers) log.Printf("Unmarshaled: %v", peers)
remove_peers() remove_peers()
for _, u := range peers { for _, u := range peers {
log.Printf("Unmarshaled: %v", u) log.Printf("Unmarshaled: %v", u)
add_peers(u) add_peers(u)
} }
//add peers to ~/mesh.conf //add peers to ~/mesh.conf
dat := make(map[string]interface{}) dat := make(map[string]interface{})
dat["Peers"] = peers dat["Peers"] = peers
bs, _ := hjson.Marshal(dat) bs, _ := hjson.Marshal(dat)
e := ioutil.WriteFile(mesh_settings_path, bs, 0750) e := ioutil.WriteFile(mesh_settings_path, bs, 0750)
if e != nil { if e != nil {
fmt.Printf("Unable to write file: %v", e) fmt.Printf("Unable to write file: %v", e)
} }
}) })
w.Bind("ping", func(peer_list string) { w.Bind("ping", func(peer_list string) {
go ping(w, peer_list) go ping(w, peer_list)
}) })
dat, err := ioutil.ReadFile(path+"/index.html") //dat, err := ioutil.ReadFile(path+"/index.html")
w.Navigate("data:text/html,"+url.QueryEscape(string(dat))) //w.Navigate("data:text/html,"+url.QueryEscape(string(dat)))
//w.Navigate("data:text/html,"+"<html>"+path+"</html>") //w.Navigate("data:text/html,"+"<html>"+path+"</html>")
w.Run() w.Navigate("file://" + path + "/index.html")
w.Run()
} }
func ping(w webview.WebView, peer_list string){ func ping(w webview.WebView, peer_list string) {
var peers []string var peers []string
_ = json.Unmarshal([]byte(peer_list), &peers) _ = json.Unmarshal([]byte(peer_list), &peers)
log.Printf("Unmarshaled: %v", peers) log.Printf("Unmarshaled: %v", peers)
for _, u := range peers { for _, u := range peers {
log.Printf("Unmarshaled: %v", u) log.Printf("Unmarshaled: %v", u)
ping_time := check(u); ping_time := check(u)
log.Printf("ping: %d", ping_time) log.Printf("ping: %d", ping_time)
setPingValue(w, u, strconv.FormatInt(ping_time, 10)); setPingValue(w, u, strconv.FormatInt(ping_time, 10))
} }
} }
func check(peer string) int64 { func check(peer string) int64 {
u, e := url.Parse(peer) u, e := url.Parse(peer)
if e!=nil { if e != nil {
return -1 return -1
} }
t := time.Now() t := time.Now()
_, err := net.DialTimeout("tcp", u.Host, 5*time.Second) _, err := net.DialTimeout("tcp", u.Host, 5*time.Second)
if err!=nil { if err != nil {
return -1 return -1
} }
d := time.Since(t) d := time.Since(t)
return d.Milliseconds() return d.Milliseconds()
} }
func get_user_home_path() string { func get_user_home_path() string {
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
path, exists := os.LookupEnv("USERPROFILE") path, exists := os.LookupEnv("USERPROFILE")
if exists { if exists {
return path return path
} else { } else {
return "" return ""
} }
} else { } else {
path, exists := os.LookupEnv("HOME") path, exists := os.LookupEnv("HOME")
if exists { if exists {
return path return path
} else { } else {
return "" return ""
} }
} }
} }
func get_ctl_path() string{ func get_ctl_path() string {
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
program_path := "programfiles" program_path := "programfiles"
path, exists := os.LookupEnv(program_path) path, exists := os.LookupEnv(program_path)
if exists { if exists {
@ -173,17 +175,17 @@ func get_ctl_path() string{
} }
} }
func run(w webview.WebView){ func run(w webview.WebView) {
if len(riv_ctrl_path) > 0 { if len(riv_ctrl_path) > 0 {
get_self(w) get_self(w)
get_peers(w) get_peers(w)
} }
_ = time.AfterFunc(10*time.Second, func() { _ = time.AfterFunc(10*time.Second, func() {
run(w) run(w)
}) })
} }
func run_command(command string) []byte{ func run_command(command string) []byte {
args := []string{"-json", command} args := []string{"-json", command}
cmd := exec.Command(riv_ctrl_path, args...) cmd := exec.Command(riv_ctrl_path, args...)
out, err := cmd.CombinedOutput() out, err := cmd.CombinedOutput()
@ -194,26 +196,26 @@ func run_command(command string) []byte{
return out return out
} }
func run_command_with_arg(command string, arg string) []byte{ func run_command_with_arg(command string, arg string) []byte {
args := []string{"-json", command, arg} args := []string{"-json", command, arg}
cmd := exec.Command(riv_ctrl_path, args...) cmd := exec.Command(riv_ctrl_path, args...)
out, err := cmd.CombinedOutput() out, err := cmd.CombinedOutput()
if err != nil { if err != nil {
//log.Fatalf("command failed: %s\n", riv_ctrl_path+" "+strings.Join(args, " ")) //log.Fatalf("command failed: %s\n", riv_ctrl_path+" "+strings.Join(args, " "))
return []byte(err.Error()) return []byte(err.Error())
} }
return out return out
} }
func add_peers(uri string){ func add_peers(uri string) {
run_command_with_arg("addpeers", "uri="+uri) run_command_with_arg("addpeers", "uri="+uri)
} }
func remove_peers(){ func remove_peers() {
run_command("removepeers") run_command("removepeers")
} }
func get_self(w webview.WebView){ func get_self(w webview.WebView) {
res := &admin.GetSelfResponse{} res := &admin.GetSelfResponse{}
out := run_command("getSelf") out := run_command("getSelf")
@ -231,7 +233,7 @@ func get_self(w webview.WebView){
//go setFieldValue(w, "peers", string(out)) //go setFieldValue(w, "peers", string(out))
} }
func get_peers(w webview.WebView){ func get_peers(w webview.WebView) {
res := &admin.GetPeersResponse{} res := &admin.GetPeersResponse{}
out := run_command("getPeers") out := run_command("getPeers")
@ -242,11 +244,11 @@ func get_peers(w webview.WebView){
var m []string var m []string
for _, s := range res.Peers { for _, s := range res.Peers {
m=append(m, s.Remote) m = append(m, s.Remote)
} }
for k := range m { for k := range m {
// Loop // Loop
fmt.Println(k) fmt.Println(k)
} }
inner_html := strings.Join(m[:], "<br>") inner_html := strings.Join(m[:], "<br>")
strings.Join(m[:], "<br>") strings.Join(m[:], "<br>")
@ -255,12 +257,12 @@ func get_peers(w webview.WebView){
func setFieldValue(p webview.WebView, id string, value string) { func setFieldValue(p webview.WebView, id string, value string) {
p.Dispatch(func() { p.Dispatch(func() {
p.Eval("setFieldValue('"+id+"','"+value+"');") p.Eval("setFieldValue('" + id + "','" + value + "');")
}) })
} }
func setPingValue(p webview.WebView, peer string, value string) { func setPingValue(p webview.WebView, peer string, value string) {
p.Dispatch(func() { p.Dispatch(func() {
p.Eval("setPingValue('"+peer+"','"+value+"');") p.Eval("setPingValue('" + peer + "','" + value + "');")
}) })
} }