mirror of
https://github.com/RoganDawes/P4wnP1_aloa.git
synced 2025-11-15 08:32:06 +01:00
webclient,service,hid: Fixes of HIDScript state events; fix timestamp displaying
This commit is contained in:
@@ -167,6 +167,13 @@ func (avm *AsyncOttoVM) RunAsync(ctx context.Context, src interface{}, anonymous
|
|||||||
if caught == haltirq {
|
if caught == haltirq {
|
||||||
job.ResultErr = errors.New(fmt.Sprintf("Execution of job %d on VM %d interrupted\n", job.Id, avm.Id))
|
job.ResultErr = errors.New(fmt.Sprintf("Execution of job %d on VM %d interrupted\n", job.Id, avm.Id))
|
||||||
|
|
||||||
|
avm.emitEvent(Event{
|
||||||
|
Job:job,
|
||||||
|
Vm:job.executingVM,
|
||||||
|
Type:EventType_JOB_CANCELLED,
|
||||||
|
Message:"Script execution cancelled",
|
||||||
|
})
|
||||||
|
|
||||||
// signal Job finished
|
// signal Job finished
|
||||||
job.SetFinished()
|
job.SetFinished()
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// +build linux
|
||||||
|
|
||||||
package hid
|
package hid
|
||||||
|
|
||||||
@@ -301,12 +302,14 @@ func (ctl *HIDController) CancelAllBackgroundJobs() {
|
|||||||
for job,_ := range oldList {
|
for job,_ := range oldList {
|
||||||
fmt.Printf("Cancelling Job %d\n", job.Id)
|
fmt.Printf("Cancelling Job %d\n", job.Id)
|
||||||
job.Cancel()
|
job.Cancel()
|
||||||
|
/*
|
||||||
ctl.emitEvent(Event{
|
ctl.emitEvent(Event{
|
||||||
Job:job,
|
Job:job,
|
||||||
Vm:job.executingVM,
|
Vm:job.executingVM,
|
||||||
Type:EventType_JOB_CANCELLED,
|
Type:EventType_JOB_CANCELLED,
|
||||||
Message:"Script execution cancelled",
|
Message:"Script execution cancelled",
|
||||||
})
|
})
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
globalJobList = make(map[*AsyncOttoJob]bool) //Create new empty list
|
globalJobList = make(map[*AsyncOttoJob]bool) //Create new empty list
|
||||||
globalJobListMutex.Unlock()
|
globalJobListMutex.Unlock()
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
pb "github.com/mame82/P4wnP1_go/proto"
|
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"github.com/mame82/P4wnP1_go/common_web"
|
||||||
|
"github.com/mame82/P4wnP1_go/hid"
|
||||||
|
pb "github.com/mame82/P4wnP1_go/proto"
|
||||||
|
"log"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
"log"
|
"errors"
|
||||||
"github.com/mame82/P4wnP1_go/hid"
|
|
||||||
"github.com/mame82/P4wnP1_go/common_web"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type EventManager struct {
|
type EventManager struct {
|
||||||
@@ -53,7 +53,7 @@ func (em *EventManager) Emit(event *pb.Event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (em *EventManager) Write(p []byte) (n int, err error) {
|
func (em *EventManager) Write(p []byte) (n int, err error) {
|
||||||
ev := ConstructEventLog("logWriter", 1, string(p))
|
ev := ConstructEventLog("logWriter", LOG_LEVEL_INFORMATION, string(p))
|
||||||
em.Emit(ev)
|
em.Emit(ev)
|
||||||
return len(p), nil
|
return len(p), nil
|
||||||
}
|
}
|
||||||
@@ -165,8 +165,32 @@ func ConstructEventNotifyStateChange(stateType common_web.EvtStateChangeType) *p
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ConstructEventLog(source string, level int, message string) *pb.Event {
|
/*
|
||||||
tJson, _ := time.Now().MarshalJSON()
|
case 1:
|
||||||
|
return prefix + "critical"
|
||||||
|
case 2:
|
||||||
|
return prefix + "error"
|
||||||
|
case 3:
|
||||||
|
return prefix + "warning"
|
||||||
|
case 4:
|
||||||
|
return prefix + "information"
|
||||||
|
case 5:
|
||||||
|
return prefix + "verbose"
|
||||||
|
*/
|
||||||
|
type LogLevel int
|
||||||
|
const (
|
||||||
|
LOG_LEVEL_UNDEFINED LogLevel = iota
|
||||||
|
LOG_LEVEL_CRITICAL
|
||||||
|
LOG_LEVEL_ERROR
|
||||||
|
LOG_LEVEL_WARNING
|
||||||
|
LOG_LEVEL_INFORMATION
|
||||||
|
LOG_LEVEL_VERBOSE
|
||||||
|
)
|
||||||
|
|
||||||
|
func ConstructEventLog(source string, level LogLevel, message string) *pb.Event {
|
||||||
|
//tJson, _ := time.Now().MarshalJSON()
|
||||||
|
|
||||||
|
unixTimeMillis := time.Now().UnixNano() / 1e6
|
||||||
|
|
||||||
return &pb.Event{
|
return &pb.Event{
|
||||||
Type: common_web.EVT_LOG,
|
Type: common_web.EVT_LOG,
|
||||||
@@ -174,7 +198,7 @@ func ConstructEventLog(source string, level int, message string) *pb.Event {
|
|||||||
{Val: &pb.EventValue_Tstring{Tstring: source}},
|
{Val: &pb.EventValue_Tstring{Tstring: source}},
|
||||||
{Val: &pb.EventValue_Tint64{Tint64: int64(level)}},
|
{Val: &pb.EventValue_Tint64{Tint64: int64(level)}},
|
||||||
{Val: &pb.EventValue_Tstring{Tstring: message}},
|
{Val: &pb.EventValue_Tstring{Tstring: message}},
|
||||||
{Val: &pb.EventValue_Tstring{Tstring: string(tJson)}},
|
{Val: &pb.EventValue_Tint64{Tint64: unixTimeMillis}}, //retrieve time in nano second accuracy and scale down to milliseconds
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -266,7 +290,8 @@ func ConstructEventHID(hidEvent hid.Event) *pb.Event {
|
|||||||
vmID = eVM.Id
|
vmID = eVM.Id
|
||||||
}
|
}
|
||||||
|
|
||||||
tJson, _ := time.Now().MarshalJSON()
|
|
||||||
|
unixTimeMillis := time.Now().UnixNano() / 1e6
|
||||||
|
|
||||||
return &pb.Event{
|
return &pb.Event{
|
||||||
Type: common_web.EVT_HID, //Type
|
Type: common_web.EVT_HID, //Type
|
||||||
@@ -278,7 +303,7 @@ func ConstructEventHID(hidEvent hid.Event) *pb.Event {
|
|||||||
{Val: &pb.EventValue_Tstring{Tstring: resString}}, //result String
|
{Val: &pb.EventValue_Tstring{Tstring: resString}}, //result String
|
||||||
{Val: &pb.EventValue_Tstring{Tstring: errString}}, //error String (message in case of error)
|
{Val: &pb.EventValue_Tstring{Tstring: errString}}, //error String (message in case of error)
|
||||||
{Val: &pb.EventValue_Tstring{Tstring: message}}, //Mesage text of event
|
{Val: &pb.EventValue_Tstring{Tstring: message}}, //Mesage text of event
|
||||||
{Val: &pb.EventValue_Tstring{Tstring: string(tJson)}}, //Timestamp of event genration
|
{Val: &pb.EventValue_Tint64{Tint64: unixTimeMillis}}, //Timestamp of event genration
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -547,7 +547,7 @@ func (tam *TriggerActionManager) executeActionLog(evt *pb.Event, ta *pb.TriggerA
|
|||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("Trigger '%s' fired -> executing action '%s'\n", triggerName, actionName)
|
fmt.Printf("Trigger '%s' fired -> executing action '%s'\n", triggerName, actionName)
|
||||||
tam.rootSvc.SubSysEvent.Emit(ConstructEventLog("TriggerAction", 0, logMessage))
|
tam.rootSvc.SubSysEvent.Emit(ConstructEventLog("TriggerAction", LOG_LEVEL_INFORMATION, logMessage))
|
||||||
}
|
}
|
||||||
|
|
||||||
// checks if the triggerType of the given event (if trigger event at all), matches the TriggerType of the TriggerAction
|
// checks if the triggerType of the given event (if trigger event at all), matches the TriggerType of the TriggerAction
|
||||||
|
|||||||
@@ -3,12 +3,9 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gopherjs/gopherjs/js"
|
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"time"
|
"github.com/gopherjs/gopherjs/js"
|
||||||
pb "github.com/mame82/P4wnP1_go/proto/gopherjs"
|
|
||||||
"context"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func O() *js.Object {
|
func O() *js.Object {
|
||||||
@@ -27,6 +24,14 @@ func StringToMD5(input string) string {
|
|||||||
return string(dst)
|
return string(dst)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BytesToMD5(input []byte) string {
|
||||||
|
sum := md5.Sum(input)
|
||||||
|
dst := make([]byte, hex.EncodedLen(len(sum)))
|
||||||
|
hex.Encode(dst, sum[:])
|
||||||
|
return string(dst)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
func UploadHIDScript(filename string, content string) (err error) {
|
func UploadHIDScript(filename string, content string) (err error) {
|
||||||
ctx,cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
ctx,cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
@@ -65,4 +70,5 @@ func RunHIDScript(filename string, timeoutSeconds uint32) (job *pb.HIDScriptJob,
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
@@ -29,8 +29,11 @@ func InitCompHIDEvents() {
|
|||||||
func(vm *hvue.VM) interface{} {
|
func(vm *hvue.VM) interface{} {
|
||||||
return vm.Get("$store").Get("state").Get("EventProcessor").Get("eventHidArray")
|
return vm.Get("$store").Get("state").Get("EventProcessor").Get("eventHidArray")
|
||||||
}),
|
}),
|
||||||
|
hvue.Method("formatDate", func(vm *hvue.VM, timestamp *js.Object) interface{} {
|
||||||
|
return js.Global.Get("Quasar").Get("utils").Get("date").Call("formatDate", timestamp, "YYYY-MM-DD HH:mm:ss Z")
|
||||||
|
}),
|
||||||
hvue.Method("evIdToString", func(vm *hvue.VM, evID int64) (res string) {
|
hvue.Method("evIdToString", func(vm *hvue.VM, evID int64) (res string) {
|
||||||
println("EvID", evID)
|
//println("EvID", evID)
|
||||||
return common_web.EventTypeHIDName[evID]
|
return common_web.EventTypeHIDName[evID]
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
@@ -45,12 +48,16 @@ const (
|
|||||||
<div>
|
<div>
|
||||||
<q-table
|
<q-table
|
||||||
:data="events"
|
:data="events"
|
||||||
:columns="[{name:'type', field: 'evtype', label: 'Event Type', align: 'left'}, {name:'vmid', field: 'vmId', label: 'VM ID', align: 'left'}, {name:'jobid', field: 'jobId', label: 'Job ID', align: 'left'}, {name:'haserror', field: 'hasError', label: 'Has error', align: 'left'}, {name:'res', field: 'result', label: 'Result', align: 'left'}, {name:'errormsg', field: 'error', label: 'Error', align: 'left'}, {name:'msg', field: 'message', label: 'Message', align: 'left'}, {name:'timestamp', field: 'time', label: 'Time', align: 'left'}]"
|
:columns="[{name:'timestamp', field: 'time', label: 'Time', align: 'left'}, {name:'type', field: 'evtype', label: 'Event Type', align: 'left'}, {name:'vmid', field: 'vmId', label: 'VM ID', align: 'left'}, {name:'jobid', field: 'jobId', label: 'Job ID', align: 'left'}, {name:'haserror', field: 'hasError', label: 'Has error', align: 'left'}, {name:'res', field: 'result', label: 'Result', align: 'left'}, {name:'errormsg', field: 'error', label: 'Error', align: 'left'}, {name:'msg', field: 'message', label: 'Message', align: 'left'}]"
|
||||||
row-key="name"
|
row-key="name"
|
||||||
:pagination="pagination"
|
:pagination="pagination"
|
||||||
hide-bottom
|
hide-bottom
|
||||||
>
|
>
|
||||||
|
|
||||||
|
<q-td slot="body-cell-timestamp" slot-scope="props" :props="props">
|
||||||
|
{{ formatDate(props.value) }}
|
||||||
|
</q-td>
|
||||||
|
|
||||||
<q-td slot="body-cell-type" slot-scope="props" :props="props">
|
<q-td slot="body-cell-type" slot-scope="props" :props="props">
|
||||||
{{ evIdToString(props.value) }}
|
{{ evIdToString(props.value) }}
|
||||||
</q-td>
|
</q-td>
|
||||||
|
|||||||
@@ -123,13 +123,16 @@ ScriptSource string `js:"textSource"`
|
|||||||
<q-popover>
|
<q-popover>
|
||||||
{{ job.textResult }}
|
{{ job.textResult }}
|
||||||
</q-popover>
|
</q-popover>
|
||||||
|
<q-tooltip>
|
||||||
|
show job result
|
||||||
|
</q-tooltip>
|
||||||
</q-btn>
|
</q-btn>
|
||||||
</q-item-side>
|
</q-item-side>
|
||||||
<q-item-side right v-if="!job.hasSucceeded && !job.hasFailed">
|
<q-item-side right v-if="!job.hasSucceeded && !job.hasFailed">
|
||||||
<q-btn flat round dense color="negative" icon="cancel" @click="cancel">
|
<q-btn flat round dense color="negative" icon="cancel" @click="cancel">
|
||||||
<q-popover>
|
<q-tooltip>
|
||||||
cancel HIDScript job {{ job.id }}
|
cancel HIDScript job {{ job.id }}
|
||||||
</q-popover>
|
</q-tooltip>
|
||||||
</q-btn>
|
</q-btn>
|
||||||
</q-item-side>
|
</q-item-side>
|
||||||
</q-item>
|
</q-item>
|
||||||
@@ -141,15 +144,31 @@ ScriptSource string `js:"textSource"`
|
|||||||
compHIDJobOverviewTemplate = `
|
compHIDJobOverviewTemplate = `
|
||||||
<q-card class="full-height">
|
<q-card class="full-height">
|
||||||
<q-list>
|
<q-list>
|
||||||
<q-list-header>Running</q-list-header>
|
<q-collapsible opened icon-toggle>
|
||||||
<hid-job-overview-item v-for="job in $store.getters.hidjobsRunning" :job="job" :key="job.id"></hid-job-overview-item>
|
<template slot="header">
|
||||||
|
<q-item-main label="Running jobs" :sublabel="'(' + $store.getters.hidjobsRunning.length + ' running jobs)'"/>
|
||||||
|
<q-item-side v-if="$store.getters.hidjobsRunning.length > 0" right>
|
||||||
|
<q-btn icon="cancel" color="red" @click="$store.dispatch('cancelAllHIDJobs')" round inverted flat>
|
||||||
|
<q-tooltip>
|
||||||
|
cancel all running HIDScript jobs
|
||||||
|
</q-tooltip>
|
||||||
|
</q-btn>
|
||||||
|
</q-item-side>
|
||||||
|
</template>
|
||||||
|
<hid-job-overview-item v-for="job in $store.getters.hidjobsRunning" :job="job" :key="job.id"></hid-job-overview-item>
|
||||||
|
</q-collapsible>
|
||||||
</q-list>
|
</q-list>
|
||||||
|
|
||||||
<q-list>
|
<q-list>
|
||||||
<q-collapsible opened icon-toggle>
|
<q-collapsible opened icon-toggle>
|
||||||
<template slot="header">
|
<template slot="header">
|
||||||
<q-item-main label="Succeeded" :sublabel="'(' + $store.getters.hidjobsSucceeded.length + ' successful jobs)'"/>
|
<q-item-main label="Succeeded" :sublabel="'(' + $store.getters.hidjobsSucceeded.length + ' successful jobs)'"/>
|
||||||
<q-item-side v-if="$store.getters.hidjobsSucceeded.length > 0" right>
|
<q-item-side v-if="$store.getters.hidjobsSucceeded.length > 0" right>
|
||||||
<q-btn icon="delete" color="red" @click="$store.dispatch('removeSucceededHidJobs')" round inverted flat />
|
<q-btn icon="delete" color="red" @click="$store.dispatch('removeSucceededHidJobs')" round inverted flat>
|
||||||
|
<q-tooltip>
|
||||||
|
delete succeeded HID jobs from list
|
||||||
|
</q-tooltip>
|
||||||
|
</q-btn>
|
||||||
</q-item-side>
|
</q-item-side>
|
||||||
</template>
|
</template>
|
||||||
<hid-job-overview-item v-for="job in $store.getters.hidjobsSucceeded" :job="job" :key="job.id"></hid-job-overview-item>
|
<hid-job-overview-item v-for="job in $store.getters.hidjobsSucceeded" :job="job" :key="job.id"></hid-job-overview-item>
|
||||||
@@ -160,7 +179,12 @@ compHIDJobOverviewTemplate = `
|
|||||||
<template slot="header">
|
<template slot="header">
|
||||||
<q-item-main label="Failed" :sublabel="'(' + $store.getters.hidjobsFailed.length + ' failed jobs)'"/>
|
<q-item-main label="Failed" :sublabel="'(' + $store.getters.hidjobsFailed.length + ' failed jobs)'"/>
|
||||||
<q-item-side v-if="$store.getters.hidjobsFailed.length > 0" right>
|
<q-item-side v-if="$store.getters.hidjobsFailed.length > 0" right>
|
||||||
<q-btn icon="delete" color="red" @click="$store.dispatch('removeFailedHidJobs')" round inverted flat />
|
<q-btn icon="delete" color="red" @click="$store.dispatch('removeFailedHidJobs')" round inverted flat>
|
||||||
|
<q-tooltip>
|
||||||
|
delete failed HID jobs from list
|
||||||
|
</q-tooltip>
|
||||||
|
</q-btn>
|
||||||
|
|
||||||
</q-item-side>
|
</q-item-side>
|
||||||
</template>
|
</template>
|
||||||
<hid-job-overview-item v-for="job in $store.getters.hidjobsFailed" :job="job" :key="job.id"></hid-job-overview-item>
|
<hid-job-overview-item v-for="job in $store.getters.hidjobsFailed" :job="job" :key="job.id"></hid-job-overview-item>
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ package main
|
|||||||
import (
|
import (
|
||||||
"github.com/gopherjs/gopherjs/js"
|
"github.com/gopherjs/gopherjs/js"
|
||||||
"github.com/mame82/hvue"
|
"github.com/mame82/hvue"
|
||||||
"strconv"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type CompHIDScriptCodeEditorData struct {
|
type CompHIDScriptCodeEditorData struct {
|
||||||
@@ -13,28 +12,6 @@ type CompHIDScriptCodeEditorData struct {
|
|||||||
CodeMirrorOptions *CodeMirrorOptionsType `js:"codemirrorOptions"`
|
CodeMirrorOptions *CodeMirrorOptionsType `js:"codemirrorOptions"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToDo: Change into action of vuex store
|
|
||||||
func SendAndRun(vm *hvue.VM) {
|
|
||||||
sourceCode := vm.Get("$store").Get("state").Get("currentHIDScriptSource").String()
|
|
||||||
md5 := StringToMD5(sourceCode) //Calculate MD5 hexstring of current script content
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
timeout := uint32(0)
|
|
||||||
err := UploadHIDScript(md5, sourceCode)
|
|
||||||
if err != nil {
|
|
||||||
QuasarNotifyError("Error uploading script", err.Error(), QUASAR_NOTIFICATION_POSITION_TOP)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
job,err := RunHIDScript(md5, timeout)
|
|
||||||
if err != nil {
|
|
||||||
QuasarNotifyError("Error starting script as background job", err.Error(), QUASAR_NOTIFICATION_POSITION_TOP)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
QuasarNotifySuccess("Script started successfully", "Job ID " + strconv.Itoa(int(job.Id)), QUASAR_NOTIFICATION_POSITION_TOP)
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
type CodeMirrorMode struct {
|
type CodeMirrorMode struct {
|
||||||
*js.Object
|
*js.Object
|
||||||
Name string `js:"name"`
|
Name string `js:"name"`
|
||||||
@@ -80,7 +57,6 @@ func InitComponentsHIDScript() {
|
|||||||
"hid-script-code-editor",
|
"hid-script-code-editor",
|
||||||
hvue.Template(compHIDScriptCodeEditorTemplate),
|
hvue.Template(compHIDScriptCodeEditorTemplate),
|
||||||
hvue.DataFunc(newCompHIDScriptCodeEditorData),
|
hvue.DataFunc(newCompHIDScriptCodeEditorData),
|
||||||
hvue.Method("SendAndRun", SendAndRun),
|
|
||||||
hvue.ComputedWithGetSet(
|
hvue.ComputedWithGetSet(
|
||||||
"scriptContent",
|
"scriptContent",
|
||||||
func(vm *hvue.VM) interface{} {
|
func(vm *hvue.VM) interface{} {
|
||||||
@@ -133,7 +109,10 @@ func InitComponentsHIDScript() {
|
|||||||
vm.Get("$q").Call("notify", "store " + name.String())
|
vm.Get("$q").Call("notify", "store " + name.String())
|
||||||
vm.Store.Call("dispatch", VUEX_ACTION_STORE_CURRENT_HID_SCRIPT_SOURCE_TO_REMOTE_FILE, name)
|
vm.Store.Call("dispatch", VUEX_ACTION_STORE_CURRENT_HID_SCRIPT_SOURCE_TO_REMOTE_FILE, name)
|
||||||
}),
|
}),
|
||||||
hvue.Method("SendAndRun", SendAndRun),
|
hvue.Method("SendAndRun", func (vm *hvue.VM) {
|
||||||
|
sourceCode := vm.Get("$store").Get("state").Get("currentHIDScriptSource").String()
|
||||||
|
vm.Store.Call("dispatch", VUEX_ACTION_AND_AND_RUN_HID_SCRIPT, sourceCode)
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/gopherjs/gopherjs/js"
|
||||||
"github.com/mame82/hvue"
|
"github.com/mame82/hvue"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -30,22 +31,25 @@ func InitCompLogger() {
|
|||||||
hvue.NewComponent(
|
hvue.NewComponent(
|
||||||
"logger",
|
"logger",
|
||||||
hvue.Template(compLoggerTemplate),
|
hvue.Template(compLoggerTemplate),
|
||||||
// hvue.DataFunc(NewLoggerData),
|
hvue.DataFunc(func(vm *hvue.VM) interface{} {
|
||||||
// hvue.MethodsOf(&CompLoggerData{}),
|
data := &struct {
|
||||||
|
*js.Object
|
||||||
|
Pagination *jsDataTablePagination `js:"pagination"`
|
||||||
|
}{Object:O()}
|
||||||
|
|
||||||
|
data.Pagination = newPagination(0, 1)
|
||||||
|
|
||||||
|
return data
|
||||||
|
}),
|
||||||
hvue.Method("logLevelClass", LogLevelClass),
|
hvue.Method("logLevelClass", LogLevelClass),
|
||||||
hvue.PropObj("max-entries", hvue.Types(hvue.PNumber), hvue.Default(5)),
|
hvue.PropObj("max-entries", hvue.Types(hvue.PNumber), hvue.Default(5)),
|
||||||
hvue.Created(func(vm *hvue.VM) {
|
|
||||||
println("OnCreated")
|
|
||||||
// vm.Call("StartListening")
|
|
||||||
}),
|
|
||||||
hvue.Destroyed(func(vm *hvue.VM) {
|
|
||||||
println("OnDestroyed")
|
|
||||||
// vm.Call("StopListening")
|
|
||||||
}),
|
|
||||||
|
|
||||||
hvue.Computed("classFromLevel", func(vm *hvue.VM) interface{} {
|
hvue.Computed("classFromLevel", func(vm *hvue.VM) interface{} {
|
||||||
return "info"
|
return "info"
|
||||||
}),
|
}),
|
||||||
|
hvue.Method("formatDate", func(vm *hvue.VM, timestamp *js.Object) interface{} {
|
||||||
|
return js.Global.Get("Quasar").Get("utils").Get("date").Call("formatDate", timestamp, "YYYY-MM-DD HH:mm:ss Z")
|
||||||
|
}),
|
||||||
hvue.Computed("logArray",
|
hvue.Computed("logArray",
|
||||||
func(vm *hvue.VM) interface{} {
|
func(vm *hvue.VM) interface{} {
|
||||||
return vm.Get("$store").Get("state").Get("EventProcessor").Get("logArray")
|
return vm.Get("$store").Get("state").Get("EventProcessor").Get("logArray")
|
||||||
@@ -57,7 +61,24 @@ func InitCompLogger() {
|
|||||||
const (
|
const (
|
||||||
|
|
||||||
compLoggerTemplate = `
|
compLoggerTemplate = `
|
||||||
<q-page>
|
<q-page padding>
|
||||||
|
<q-card>
|
||||||
|
<div>
|
||||||
|
<q-table
|
||||||
|
:data="logArray"
|
||||||
|
:columns="[{name:'logTime', field: 'time', label: 'Time', align: 'left'}, {name:'logSource', field: 'source', label: 'Source', align: 'left'}, {name:'logLevel', field: 'level', label: 'Level', align: 'left'}, {name:'logMessage', field: 'message', label: 'Message', align: 'left'}]"
|
||||||
|
row-key="name"
|
||||||
|
:pagination="pagination"
|
||||||
|
hide-bottom
|
||||||
|
>
|
||||||
|
<q-td slot="body-cell-logTime" slot-scope="props" :props="props">
|
||||||
|
{{ formatDate(props.value) }}
|
||||||
|
</q-td>
|
||||||
|
</q-table>
|
||||||
|
</div>
|
||||||
|
</q-card>
|
||||||
|
|
||||||
|
<!--
|
||||||
<div class="logger">
|
<div class="logger">
|
||||||
<table class="log-entries">
|
<table class="log-entries">
|
||||||
<tr>
|
<tr>
|
||||||
@@ -74,6 +95,7 @@ const (
|
|||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
-->
|
||||||
</q-page>
|
</q-page>
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ const (
|
|||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<q-card>
|
<q-card>
|
||||||
<q-card-title>
|
<q-card-title>
|
||||||
USB Gadget Settings
|
USB Gadget Settings ({{ deploying }})
|
||||||
</q-card-title>
|
</q-card-title>
|
||||||
|
|
||||||
<q-card-main>
|
<q-card-main>
|
||||||
|
|||||||
@@ -359,19 +359,23 @@ const templateBluetoothPage = `
|
|||||||
</q-card>
|
</q-card>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!--
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
{{ CurrentControllerInfo }}
|
{{ CurrentControllerInfo }}
|
||||||
</div>
|
</div>
|
||||||
|
-->
|
||||||
<div class="col-12 col-lg">
|
<div class="col-12 col-lg">
|
||||||
<bluetooth-controller :controllerInfo="CurrentControllerInfo"></bluetooth-controller>
|
<bluetooth-controller :controllerInfo="CurrentControllerInfo"></bluetooth-controller>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-lg">
|
<div class="col-12 col-lg">
|
||||||
<bluetooth-controller-network-services :controllerInfo="CurrentControllerInfo"></bluetooth-controller-network-services>
|
<div class="row gutter-y-sm">
|
||||||
</div>
|
<div class="col-12">
|
||||||
<div class="col-12 col-lg">
|
<bluetooth-controller-network-services :controllerInfo="CurrentControllerInfo"></bluetooth-controller-network-services>
|
||||||
<bluetooth-agent :bluetoothAgent="CurrentBluetoothAgentSettings"></bluetooth-agent>
|
</div>
|
||||||
|
<div class="col-12">
|
||||||
|
<bluetooth-agent :bluetoothAgent="CurrentBluetoothAgentSettings"></bluetooth-agent>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</q-page>
|
</q-page>
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ type jsLogEvent struct {
|
|||||||
EvLogSource string `js:"source"`
|
EvLogSource string `js:"source"`
|
||||||
EvLogLevel int `js:"level"`
|
EvLogLevel int `js:"level"`
|
||||||
EvLogMessage string `js:"message"`
|
EvLogMessage string `js:"message"`
|
||||||
EvLogTime string `js:"time"`
|
EvLogTime int64 `js:"time"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//HID event
|
//HID event
|
||||||
@@ -247,7 +247,7 @@ type jsHidEvent struct {
|
|||||||
Result string `js:"result"`
|
Result string `js:"result"`
|
||||||
Error string `js:"error"`
|
Error string `js:"error"`
|
||||||
Message string `js:"message"`
|
Message string `js:"message"`
|
||||||
EvLogTime string `js:"time"`
|
EvLogTime int64 `js:"time"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (jsEv *jsEvent) toLogEvent() (res *jsLogEvent, err error) {
|
func (jsEv *jsEvent) toLogEvent() (res *jsLogEvent, err error) {
|
||||||
@@ -273,10 +273,11 @@ func (jsEv *jsEvent) toLogEvent() (res *jsLogEvent, err error) {
|
|||||||
return nil, eNoLogEvent
|
return nil, eNoLogEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
res.EvLogTime, ok = jsEv.Values[3].(string)
|
res.EvLogTime, ok = jsEv.Values[3].(int64)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, eNoLogEvent
|
return nil, eNoLogEvent
|
||||||
}
|
}
|
||||||
|
println("EvLogTime", res.EvLogTime)
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
@@ -323,7 +324,7 @@ func (jsEv *jsEvent) toHidEvent() (res *jsHidEvent, err error) {
|
|||||||
return nil, eNoHidEvent
|
return nil, eNoHidEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
res.EvLogTime, ok = jsEv.Values[7].(string)
|
res.EvLogTime, ok = jsEv.Values[7].(int64)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, eNoHidEvent
|
return nil, eNoHidEvent
|
||||||
}
|
}
|
||||||
@@ -341,7 +342,7 @@ type jsHidJobState struct {
|
|||||||
LastMessage string `js:"lastMessage"`
|
LastMessage string `js:"lastMessage"`
|
||||||
TextResult string `js:"textResult"`
|
TextResult string `js:"textResult"`
|
||||||
// TextError string `js:"textError"`
|
// TextError string `js:"textError"`
|
||||||
LastUpdateTime string `js:"lastUpdateTime"` //JSON timestamp from server
|
LastUpdateTime int64 `js:"lastUpdateTime"` //JSON timestamp from server
|
||||||
ScriptSource string `js:"textSource"`
|
ScriptSource string `js:"textSource"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -392,7 +393,7 @@ func NewHIDJobStateList() *jsHidJobStateList {
|
|||||||
// state list, directly, but instead uses the "Vue.set()" method to update the object, while making vue aware of it.
|
// state list, directly, but instead uses the "Vue.set()" method to update the object, while making vue aware of it.
|
||||||
// This means: THE "UpdateEntry" METHOD RELIES ON THE PRESENCE OF THE "Vue" OBJECT IN JAVASCRIPT GLOBAL SCOPE. This again
|
// This means: THE "UpdateEntry" METHOD RELIES ON THE PRESENCE OF THE "Vue" OBJECT IN JAVASCRIPT GLOBAL SCOPE. This again
|
||||||
// means Vue.JS has to be loaded, BEFORE THIS METHOD IS CALLED"
|
// means Vue.JS has to be loaded, BEFORE THIS METHOD IS CALLED"
|
||||||
func (jl *jsHidJobStateList) UpdateEntry(id, vmId int64, hasFailed, hasSucceeded bool, message, textResult, lastUpdateTime, scriptSource string) {
|
func (jl *jsHidJobStateList) UpdateEntry(id, vmId int64, hasFailed, hasSucceeded bool, message string, textResult string, lastUpdateTime int64, scriptSource string) {
|
||||||
key := strconv.Itoa(int(id))
|
key := strconv.Itoa(int(id))
|
||||||
|
|
||||||
//Check if job exists, update existing one if already present
|
//Check if job exists, update existing one if already present
|
||||||
@@ -998,29 +999,10 @@ func (data *jsEventProcessor) handleHidEvent(hEv *jsHidEvent) {
|
|||||||
data.JobList.UpdateEntry(hEv.JobId, hEv.VMId, hEv.HasError, false, hEv.Message, hEv.Error, hEv.EvLogTime, "")
|
data.JobList.UpdateEntry(hEv.JobId, hEv.VMId, hEv.HasError, false, hEv.Message, hEv.Error, hEv.EvLogTime, "")
|
||||||
|
|
||||||
QuasarNotifyError("HIDScript job " + strconv.Itoa(int(hEv.JobId)) + " failed", hEv.Error, QUASAR_NOTIFICATION_POSITION_TOP)
|
QuasarNotifyError("HIDScript job " + strconv.Itoa(int(hEv.JobId)) + " failed", hEv.Error, QUASAR_NOTIFICATION_POSITION_TOP)
|
||||||
/*
|
|
||||||
notification := &QuasarNotification{Object: O()}
|
|
||||||
notification.Message = "HIDScript job " + strconv.Itoa(int(hEv.JobId)) + " failed"
|
|
||||||
notification.Detail = hEv.Error
|
|
||||||
notification.Position = QUASAR_NOTIFICATION_POSITION_TOP
|
|
||||||
notification.Type = QUASAR_NOTIFICATION_TYPE_NEGATIVE
|
|
||||||
notification.Timeout = 5000
|
|
||||||
QuasarNotify(notification)
|
|
||||||
*/
|
|
||||||
case common_web.HidEventType_JOB_SUCCEEDED:
|
case common_web.HidEventType_JOB_SUCCEEDED:
|
||||||
data.JobList.UpdateEntry(hEv.JobId, hEv.VMId, hEv.HasError, true, hEv.Message, hEv.Result, hEv.EvLogTime, "")
|
data.JobList.UpdateEntry(hEv.JobId, hEv.VMId, hEv.HasError, true, hEv.Message, hEv.Result, hEv.EvLogTime, "")
|
||||||
|
|
||||||
QuasarNotifySuccess("HIDScript job " + strconv.Itoa(int(hEv.JobId)) + " succeeded", hEv.Result, QUASAR_NOTIFICATION_POSITION_TOP)
|
QuasarNotifySuccess("HIDScript job " + strconv.Itoa(int(hEv.JobId)) + " succeeded", hEv.Result, QUASAR_NOTIFICATION_POSITION_TOP)
|
||||||
|
|
||||||
/*
|
|
||||||
notification := &QuasarNotification{Object: O()}
|
|
||||||
notification.Message = "HIDScript job " + strconv.Itoa(int(hEv.JobId)) + " succeeded"
|
|
||||||
notification.Detail = hEv.Result
|
|
||||||
notification.Position = QUASAR_NOTIFICATION_POSITION_TOP
|
|
||||||
notification.Type = QUASAR_NOTIFICATION_TYPE_POSITIVE
|
|
||||||
notification.Timeout = 5000
|
|
||||||
QuasarNotify(notification)
|
|
||||||
*/
|
|
||||||
case common_web.HidEventType_JOB_CANCELLED:
|
case common_web.HidEventType_JOB_CANCELLED:
|
||||||
data.JobList.UpdateEntry(hEv.JobId, hEv.VMId, true, false, hEv.Message, hEv.Message, hEv.EvLogTime, "")
|
data.JobList.UpdateEntry(hEv.JobId, hEv.VMId, true, false, hEv.Message, hEv.Message, hEv.EvLogTime, "")
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -47,19 +47,18 @@ func Router(router *js.Object) hvue.ComponentOption {
|
|||||||
func main() {
|
func main() {
|
||||||
println(GetBaseURL())
|
println(GetBaseURL())
|
||||||
|
|
||||||
println("====================---------")
|
|
||||||
store := InitGlobalState() //sets Vuex store in JS window.store
|
store := InitGlobalState() //sets Vuex store in JS window.store
|
||||||
store.Dispatch(VUEX_ACTION_START_EVENT_LISTEN)
|
|
||||||
|
|
||||||
// RpcClient.StartListening() //Start event listening after global state is initiated (contains the event handlers)
|
// RpcClient.StartListening() //Start event listening after global state is initiated (contains the event handlers)
|
||||||
|
|
||||||
// ToDo: delete because debug
|
// ToDo: delete because debug
|
||||||
// RpcClient.GetAllDeployedEthernetInterfaceSettings(time.Second*10)
|
// RpcClient.GetAllDeployedEthernetInterfaceSettings(time.Second*10)
|
||||||
|
|
||||||
router := NewVueRouter("/usb",
|
router := NewVueRouter(
|
||||||
VueRouterRoute("/usb","", "<usb-settings></usb-settings>"),
|
"/usb",
|
||||||
// route below could be used for an easter egg
|
// route below could be used for an easter egg
|
||||||
//VueRouterRoute("/","", "<usb-settings></usb-settings>"),
|
//VueRouterRoute("/","", "<usb-settings></usb-settings>"),
|
||||||
|
VueRouterRoute("/usb","", "<usb-settings></usb-settings>"),
|
||||||
VueRouterRoute("/hid","", "<hid-script></hid-script>"),
|
VueRouterRoute("/hid","", "<hid-script></hid-script>"),
|
||||||
VueRouterRoute("/hidjobs","", "<hid-job-event-overview></hid-job-event-overview>"),
|
VueRouterRoute("/hidjobs","", "<hid-job-event-overview></hid-job-event-overview>"),
|
||||||
VueRouterRoute("/logger","", "<logger :max-entries='7'></logger>"),
|
VueRouterRoute("/logger","", "<logger :max-entries='7'></logger>"),
|
||||||
@@ -88,25 +87,7 @@ println("====================---------")
|
|||||||
vm := hvue.NewVM(
|
vm := hvue.NewVM(
|
||||||
hvue.El("#app"),
|
hvue.El("#app"),
|
||||||
hvue.Template(templateMainApp),
|
hvue.Template(templateMainApp),
|
||||||
/*
|
|
||||||
//add "testString" to data
|
|
||||||
hvue.DataFunc(func(vm *hvue.VM) interface{} {
|
|
||||||
data := struct{
|
|
||||||
*js.Object
|
|
||||||
TestString string `js:"testString"`
|
|
||||||
SelectedTab string `js:"selectedTab"`
|
|
||||||
}{Object: O()}
|
|
||||||
data.SelectedTab = "USB"
|
|
||||||
data.TestString = "type('hello');"
|
|
||||||
return &data
|
|
||||||
}),
|
|
||||||
*/
|
|
||||||
//add console to app as computed property, to allow debug output on vue events
|
//add console to app as computed property, to allow debug output on vue events
|
||||||
hvue.Computed(
|
|
||||||
"console",
|
|
||||||
func(vm *hvue.VM) interface{} {
|
|
||||||
return js.Global.Get("console")
|
|
||||||
}),
|
|
||||||
hvue.Computed("state", func(vm *hvue.VM) interface{} {
|
hvue.Computed("state", func(vm *hvue.VM) interface{} {
|
||||||
return vm.Get("$store").Get("state") //works only with Vuex store option added
|
return vm.Get("$store").Get("state") //works only with Vuex store option added
|
||||||
}),
|
}),
|
||||||
@@ -118,7 +99,6 @@ println("====================---------")
|
|||||||
)
|
)
|
||||||
// ToDo: remove next lines, debug code
|
// ToDo: remove next lines, debug code
|
||||||
js.Global.Set("vm",vm)
|
js.Global.Set("vm",vm)
|
||||||
js.Global.Set("rpc", RpcClient)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const templateMainApp = `
|
const templateMainApp = `
|
||||||
@@ -132,13 +112,13 @@ const templateMainApp = `
|
|||||||
</q-toolbar>
|
</q-toolbar>
|
||||||
<q-tabs>
|
<q-tabs>
|
||||||
<q-route-tab default slot="title" to="usb" name="tab-usb" icon="usb" label="USB Settings"></q-route-tab>
|
<q-route-tab default slot="title" to="usb" name="tab-usb" icon="usb" label="USB Settings"></q-route-tab>
|
||||||
<q-route-tab slot="title" to="hid" name="tab-hid-script" icon="code" label="HIDScript"></q-route-tab>
|
|
||||||
<q-route-tab slot="title" to="hidjobs" name="tab-hid-jobs" icon="schedule" label="HID Events"></q-route-tab>
|
|
||||||
<q-route-tab slot="title" to="logger" name="tab-logger" icon="message" label="Event Log"></q-route-tab>
|
|
||||||
<q-route-tab slot="title" to="network" name="tab-network" icon="settings_ethernet" label="Network settings"></q-route-tab>
|
|
||||||
<q-route-tab slot="title" to="wifi" name="tab-wifi" icon="wifi" label="WiFi settings"></q-route-tab>
|
<q-route-tab slot="title" to="wifi" name="tab-wifi" icon="wifi" label="WiFi settings"></q-route-tab>
|
||||||
<q-route-tab slot="title" to="triggeractions" name="tab-triggeraction" icon="whatshot" label="Trigger Actions"></q-route-tab>
|
|
||||||
<q-route-tab slot="title" to="bluetooth" name="tab-bluetooth" icon="bluetooth" label="Bluetooth"></q-route-tab>
|
<q-route-tab slot="title" to="bluetooth" name="tab-bluetooth" icon="bluetooth" label="Bluetooth"></q-route-tab>
|
||||||
|
<q-route-tab slot="title" to="network" name="tab-network" icon="settings_ethernet" label="Network settings"></q-route-tab>
|
||||||
|
<q-route-tab slot="title" to="triggeractions" name="tab-triggeraction" icon="whatshot" label="Trigger Actions"></q-route-tab>
|
||||||
|
<q-route-tab slot="title" to="hid" name="tab-hid-script" icon="keyboard" label="HIDScript"></q-route-tab>
|
||||||
|
<!-- <q-route-tab slot="title" to="hidjobs" name="tab-hid-jobs" icon="schedule" label="HID Events"></q-route-tab> -->
|
||||||
|
<q-route-tab slot="title" to="logger" name="tab-logger" icon="message" label="Event Log"></q-route-tab>
|
||||||
</q-tabs>
|
</q-tabs>
|
||||||
</q-layout-header>
|
</q-layout-header>
|
||||||
|
|
||||||
@@ -155,14 +135,6 @@ const templateMainApp = `
|
|||||||
<router-view></router-view>
|
<router-view></router-view>
|
||||||
|
|
||||||
<disconnect-modal :value="!$store.getters.isConnected"></disconnect-modal>
|
<disconnect-modal :value="!$store.getters.isConnected"></disconnect-modal>
|
||||||
<!--
|
|
||||||
<q-modal v-model="!$store.getters.isConnected" minimized no-route-dismiss no-esc-dismiss no-backdrop-dismiss>
|
|
||||||
<div style="padding: 50px">
|
|
||||||
<div class="q-display-1 q-mb-md">No connection to server</div>
|
|
||||||
<p>Trying to reconnect ... (attempt {{ $store.state.failedConnectionAttempts }})</p>
|
|
||||||
</div>
|
|
||||||
</q-modal>
|
|
||||||
-->
|
|
||||||
</q-page-container>
|
</q-page-container>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"io"
|
"io"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -45,12 +46,14 @@ const (
|
|||||||
|
|
||||||
//HIDScripts and jobs
|
//HIDScripts and jobs
|
||||||
VUEX_ACTION_UPDATE_RUNNING_HID_JOBS = "updateRunningHidJobs"
|
VUEX_ACTION_UPDATE_RUNNING_HID_JOBS = "updateRunningHidJobs"
|
||||||
VUEX_ACTION_REMOVE_SUCCEEDED_HID_JOBS = "removeSucceededHidJobs"
|
VUEX_ACTION_REMOVE_SUCCEEDED_HID_JOBS = "removeSucceededHidJobs"
|
||||||
VUEX_ACTION_REMOVE_FAILED_HID_JOBS = "removeFailedHidJobs"
|
VUEX_ACTION_REMOVE_FAILED_HID_JOBS = "removeFailedHidJobs"
|
||||||
VUEX_ACTION_UPDATE_STORED_HID_SCRIPTS_LIST = "updateStoredHIDScriptsList"
|
VUEX_ACTION_UPDATE_STORED_HID_SCRIPTS_LIST = "updateStoredHIDScriptsList"
|
||||||
VUEX_ACTION_UPDATE_CURRENT_HID_SCRIPT_SOURCE_FROM_REMOTE_FILE = "updateCurrentHidScriptSourceFromRemoteFile"
|
VUEX_ACTION_UPDATE_CURRENT_HID_SCRIPT_SOURCE_FROM_REMOTE_FILE = "updateCurrentHidScriptSourceFromRemoteFile"
|
||||||
VUEX_ACTION_STORE_CURRENT_HID_SCRIPT_SOURCE_TO_REMOTE_FILE = "storeCurrentHidScriptSourceToRemoteFile"
|
VUEX_ACTION_STORE_CURRENT_HID_SCRIPT_SOURCE_TO_REMOTE_FILE = "storeCurrentHidScriptSourceToRemoteFile"
|
||||||
VUEX_ACTION_CANCEL_HID_JOB = "cancelHIDJob"
|
VUEX_ACTION_CANCEL_HID_JOB = "cancelHIDJob"
|
||||||
|
VUEX_ACTION_CANCEL_ALL_HID_JOBS = "cancelAllHIDJobs"
|
||||||
|
VUEX_ACTION_AND_AND_RUN_HID_SCRIPT = "sendAndRunHIDScript"
|
||||||
|
|
||||||
VUEX_MUTATION_SET_CURRENT_HID_SCRIPT_SOURCE_TO = "setCurrentHIDScriptSource"
|
VUEX_MUTATION_SET_CURRENT_HID_SCRIPT_SOURCE_TO = "setCurrentHIDScriptSource"
|
||||||
VUEX_MUTATION_SET_STORED_HID_SCRIPTS_LIST = "setStoredHIDScriptsList"
|
VUEX_MUTATION_SET_STORED_HID_SCRIPTS_LIST = "setStoredHIDScriptsList"
|
||||||
@@ -155,6 +158,7 @@ func createGlobalStateStruct() GlobalState {
|
|||||||
state.Title = "P4wnP1 by MaMe82"
|
state.Title = "P4wnP1 by MaMe82"
|
||||||
state.CurrentHIDScriptSource = initHIDScript
|
state.CurrentHIDScriptSource = initHIDScript
|
||||||
state.CurrentGadgetSettings = NewUSBGadgetSettings()
|
state.CurrentGadgetSettings = NewUSBGadgetSettings()
|
||||||
|
state.CurrentlyDeployingGadgetSettings = false
|
||||||
state.CurrentlyDeployingWifiSettings = false
|
state.CurrentlyDeployingWifiSettings = false
|
||||||
state.HidJobList = NewHIDJobStateList()
|
state.HidJobList = NewHIDJobStateList()
|
||||||
state.TriggerActionList = NewTriggerActionSet()
|
state.TriggerActionList = NewTriggerActionSet()
|
||||||
@@ -204,7 +208,7 @@ func processEvent(evt *pb.Event, store *mvuex.Store, state *GlobalState) {
|
|||||||
case common_web.STATE_CHANGE_EVT_TYPE_NETWORK:
|
case common_web.STATE_CHANGE_EVT_TYPE_NETWORK:
|
||||||
store.Dispatch(VUEX_ACTION_UPDATE_ALL_ETHERNET_INTERFACE_SETTINGS)
|
store.Dispatch(VUEX_ACTION_UPDATE_ALL_ETHERNET_INTERFACE_SETTINGS)
|
||||||
case common_web.STATE_CHANGE_EVT_TYPE_HID:
|
case common_web.STATE_CHANGE_EVT_TYPE_HID:
|
||||||
store.Dispatch(VUEX_ACTION_UPDATE_RUNNING_HID_JOBS) // handled by dedicated listener
|
//store.Dispatch(VUEX_ACTION_UPDATE_RUNNING_HID_JOBS) // handled by dedicated listener
|
||||||
case common_web.STATE_CHANGE_EVT_TYPE_WIFI:
|
case common_web.STATE_CHANGE_EVT_TYPE_WIFI:
|
||||||
store.Dispatch(VUEX_ACTION_UPDATE_WIFI_STATE)
|
store.Dispatch(VUEX_ACTION_UPDATE_WIFI_STATE)
|
||||||
case common_web.STATE_CHANGE_EVT_TYPE_TRIGGER_ACTIONS:
|
case common_web.STATE_CHANGE_EVT_TYPE_TRIGGER_ACTIONS:
|
||||||
@@ -254,9 +258,34 @@ func actionUpdateAllStates(store *mvuex.Store, context *mvuex.ActionContext, sta
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func actionSendAndRunHIDScript(store *mvuex.Store, context *mvuex.ActionContext, state *GlobalState, scriptContent *js.Object) {
|
||||||
|
go func() {
|
||||||
|
strScriptContent := scriptContent.String()
|
||||||
|
|
||||||
|
println("Send and run HIDScript job")
|
||||||
|
//fetch deployed gadget settings
|
||||||
|
filename,err := RpcClient.UploadContentToTempFile(defaultTimeout, []byte(strScriptContent))
|
||||||
|
if err != nil {
|
||||||
|
println("Couldn't upload HIDScript job", err)
|
||||||
|
QuasarNotifyError("Error uploading script", err.Error(), QUASAR_NOTIFICATION_POSITION_TOP)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
job,err := RpcClient.RunHIDScriptJob(defaultTimeout, "/tmp/" + filename)
|
||||||
|
if err != nil {
|
||||||
|
println("Couldn't start HIDScript job", err)
|
||||||
|
QuasarNotifyError("Error starting script as background job", err.Error(), QUASAR_NOTIFICATION_POSITION_TOP)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
QuasarNotifySuccess("Script started successfully", "Job ID " + strconv.Itoa(int(job.Id)), QUASAR_NOTIFICATION_POSITION_TOP)
|
||||||
|
|
||||||
|
// ToDo: update HIDScriptJob list (should be done event based)
|
||||||
|
}()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func actionCancelHidJob(store *mvuex.Store, context *mvuex.ActionContext, state *GlobalState, jobID *js.Object) {
|
func actionCancelHidJob(store *mvuex.Store, context *mvuex.ActionContext, state *GlobalState, jobID *js.Object) {
|
||||||
|
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
id := uint32(jobID.Int())
|
id := uint32(jobID.Int())
|
||||||
println("Cancel HIDScript job", id)
|
println("Cancel HIDScript job", id)
|
||||||
@@ -269,8 +298,21 @@ func actionCancelHidJob(store *mvuex.Store, context *mvuex.ActionContext, state
|
|||||||
|
|
||||||
// ToDo: update HIDScriptJob list (should be done event based)
|
// ToDo: update HIDScriptJob list (should be done event based)
|
||||||
}()
|
}()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func actionCancelAllHidJobs(store *mvuex.Store, context *mvuex.ActionContext, state *GlobalState) {
|
||||||
|
go func() {
|
||||||
|
println("Cancel all HIDScript jobs")
|
||||||
|
//fetch deployed gadget settings
|
||||||
|
err := RpcClient.CancelAllHIDScriptJobs(defaultTimeout)
|
||||||
|
if err != nil {
|
||||||
|
println("Couldn't cancel all HIDScript jobs", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToDo: update HIDScriptJob list (should be done event based)
|
||||||
|
}()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -932,7 +974,8 @@ func actionUpdateRunningHidJobs(store *mvuex.Store, context *mvuex.ActionContext
|
|||||||
|
|
||||||
for _, jobstate := range jobstates {
|
for _, jobstate := range jobstates {
|
||||||
println("updateing jobstate", jobstate)
|
println("updateing jobstate", jobstate)
|
||||||
state.HidJobList.UpdateEntry(jobstate.Id, jobstate.VmId, false, false, "initial job state", "", time.Now().String(), jobstate.Source)
|
timeNowUnixMilli := time.Now().UnixNano()/1e6
|
||||||
|
state.HidJobList.UpdateEntry(jobstate.Id, jobstate.VmId, false, false, "initial job state", "", timeNowUnixMilli, jobstate.Source)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@@ -1115,6 +1158,7 @@ func actionDeployCurrentGadgetSettings(store *mvuex.Store, context *mvuex.Action
|
|||||||
notification.Timeout = 2000
|
notification.Timeout = 2000
|
||||||
QuasarNotify(notification)
|
QuasarNotify(notification)
|
||||||
|
|
||||||
|
return
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return
|
return
|
||||||
@@ -1267,9 +1311,12 @@ func initMVuex() *mvuex.Store {
|
|||||||
mvuex.Action(VUEX_ACTION_START_EVENT_LISTEN, actionStartEventListen),
|
mvuex.Action(VUEX_ACTION_START_EVENT_LISTEN, actionStartEventListen),
|
||||||
mvuex.Action(VUEX_ACTION_STOP_EVENT_LISTEN, actionStopEventListen),
|
mvuex.Action(VUEX_ACTION_STOP_EVENT_LISTEN, actionStopEventListen),
|
||||||
|
|
||||||
|
|
||||||
mvuex.Action(VUEX_ACTION_REMOVE_SUCCEEDED_HID_JOBS, actionRemoveSucceededHidJobs),
|
mvuex.Action(VUEX_ACTION_REMOVE_SUCCEEDED_HID_JOBS, actionRemoveSucceededHidJobs),
|
||||||
mvuex.Action(VUEX_ACTION_REMOVE_FAILED_HID_JOBS, actionRemoveFailedHidJobs),
|
mvuex.Action(VUEX_ACTION_REMOVE_FAILED_HID_JOBS, actionRemoveFailedHidJobs),
|
||||||
mvuex.Action(VUEX_ACTION_CANCEL_HID_JOB, actionCancelHidJob),
|
mvuex.Action(VUEX_ACTION_CANCEL_HID_JOB, actionCancelHidJob),
|
||||||
|
mvuex.Action(VUEX_ACTION_CANCEL_ALL_HID_JOBS, actionCancelAllHidJobs),
|
||||||
|
mvuex.Action(VUEX_ACTION_AND_AND_RUN_HID_SCRIPT, actionSendAndRunHIDScript),
|
||||||
|
|
||||||
|
|
||||||
mvuex.Getter("triggerActions", func(state *GlobalState) interface{} {
|
mvuex.Getter("triggerActions", func(state *GlobalState) interface{} {
|
||||||
@@ -1327,6 +1374,9 @@ func initMVuex() *mvuex.Store {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
store.Dispatch(VUEX_ACTION_START_EVENT_LISTEN)
|
||||||
|
|
||||||
|
/*
|
||||||
// fetch deployed gadget settings
|
// fetch deployed gadget settings
|
||||||
store.Dispatch(VUEX_ACTION_UPDATE_CURRENT_USB_SETTINGS)
|
store.Dispatch(VUEX_ACTION_UPDATE_CURRENT_USB_SETTINGS)
|
||||||
|
|
||||||
@@ -1335,14 +1385,14 @@ func initMVuex() *mvuex.Store {
|
|||||||
|
|
||||||
// Update WiFi state
|
// Update WiFi state
|
||||||
store.Dispatch(VUEX_ACTION_UPDATE_WIFI_STATE)
|
store.Dispatch(VUEX_ACTION_UPDATE_WIFI_STATE)
|
||||||
|
*/
|
||||||
// propagate Vuex store to global scope to allow injecting it to Vue by setting the "store" option
|
|
||||||
js.Global.Set("store", store)
|
|
||||||
|
|
||||||
|
|
||||||
return store
|
return store
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitGlobalState() *mvuex.Store {
|
func InitGlobalState() *mvuex.Store {
|
||||||
return initMVuex()
|
store := initMVuex()
|
||||||
|
// propagate Vuex store to global scope to allow injecting it to Vue by setting the "store" option
|
||||||
|
js.Global.Set("store", store)
|
||||||
|
return store
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,40 @@ func NewRpcClient(addr string) Rpc {
|
|||||||
return rcl
|
return rcl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (rpc *Rpc) UploadContentToTempFile(timeout time.Duration, content []byte) (filename string, err error) {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
//create hex string of content MD5 sum
|
||||||
|
filename = BytesToMD5(content)
|
||||||
|
|
||||||
|
//upload file to `/tmp/{md5_hash_hex}`
|
||||||
|
_,err = rpc.Client.FSWriteFile(ctx,
|
||||||
|
&pb.WriteFileRequest{
|
||||||
|
Data:content,
|
||||||
|
Append:false,
|
||||||
|
Filename:filename,
|
||||||
|
Folder: pb.AccessibleFolder_TMP,
|
||||||
|
MustNotExist:false,
|
||||||
|
})
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rpc *Rpc) RunHIDScriptJob(timeout time.Duration, filepath string) (job *pb.HIDScriptJob, err error) {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
//upload file to `/tmp/{md5_hash_hex}`
|
||||||
|
return rpc.Client.HIDRunScriptJob(
|
||||||
|
ctx,
|
||||||
|
&pb.HIDScriptRequest{
|
||||||
|
ScriptPath: filepath,
|
||||||
|
TimeoutSeconds: uint32(0),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
func (rpc *Rpc) CancelHIDScriptJob(timeout time.Duration, jobID uint32) (err error) {
|
func (rpc *Rpc) CancelHIDScriptJob(timeout time.Duration, jobID uint32) (err error) {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|||||||
Reference in New Issue
Block a user