diff --git a/hid/AsyncOtto.go b/hid/AsyncOtto.go index 19e109e..336be51 100644 --- a/hid/AsyncOtto.go +++ b/hid/AsyncOtto.go @@ -167,6 +167,13 @@ func (avm *AsyncOttoVM) RunAsync(ctx context.Context, src interface{}, anonymous if caught == haltirq { 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 job.SetFinished() return diff --git a/hid/controller.go b/hid/controller.go index 1204e89..45a8dc7 100644 --- a/hid/controller.go +++ b/hid/controller.go @@ -1,3 +1,4 @@ +// +build linux package hid @@ -301,12 +302,14 @@ func (ctl *HIDController) CancelAllBackgroundJobs() { for job,_ := range oldList { fmt.Printf("Cancelling Job %d\n", job.Id) job.Cancel() + /* ctl.emitEvent(Event{ Job:job, Vm:job.executingVM, Type:EventType_JOB_CANCELLED, Message:"Script execution cancelled", }) + */ } globalJobList = make(map[*AsyncOttoJob]bool) //Create new empty list globalJobListMutex.Unlock() diff --git a/service/Event.go b/service/Event.go index 9233c6b..b057abd 100644 --- a/service/Event.go +++ b/service/Event.go @@ -1,15 +1,15 @@ package service import ( - "errors" - "fmt" - pb "github.com/mame82/P4wnP1_go/proto" "context" + "fmt" + "github.com/mame82/P4wnP1_go/common_web" + "github.com/mame82/P4wnP1_go/hid" + pb "github.com/mame82/P4wnP1_go/proto" + "log" "sync" "time" - "log" - "github.com/mame82/P4wnP1_go/hid" - "github.com/mame82/P4wnP1_go/common_web" + "errors" ) type EventManager struct { @@ -53,7 +53,7 @@ func (em *EventManager) Emit(event *pb.Event) { } 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) 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{ 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_Tint64{Tint64: int64(level)}}, {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 } - tJson, _ := time.Now().MarshalJSON() + + unixTimeMillis := time.Now().UnixNano() / 1e6 return &pb.Event{ 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: errString}}, //error String (message in case of error) {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 }, } } diff --git a/service/triggerAction.go b/service/triggerAction.go index c684a5d..3a36c76 100644 --- a/service/triggerAction.go +++ b/service/triggerAction.go @@ -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) - 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 diff --git a/web_client/common.go b/web_client/common.go index a9c6361..7be45ee 100644 --- a/web_client/common.go +++ b/web_client/common.go @@ -3,12 +3,9 @@ package main import ( - "github.com/gopherjs/gopherjs/js" "crypto/md5" "encoding/hex" - "time" - pb "github.com/mame82/P4wnP1_go/proto/gopherjs" - "context" + "github.com/gopherjs/gopherjs/js" ) func O() *js.Object { @@ -27,6 +24,14 @@ func StringToMD5(input string) string { 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) { ctx,cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() @@ -65,4 +70,5 @@ func RunHIDScript(filename string, timeoutSeconds uint32) (job *pb.HIDScriptJob, }, ) -} \ No newline at end of file +} +*/ \ No newline at end of file diff --git a/web_client/hvueCompHIDEvents.go b/web_client/hvueCompHIDEvents.go index 5243ee4..e00238e 100644 --- a/web_client/hvueCompHIDEvents.go +++ b/web_client/hvueCompHIDEvents.go @@ -29,8 +29,11 @@ func InitCompHIDEvents() { func(vm *hvue.VM) interface{} { 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) { - println("EvID", evID) + //println("EvID", evID) return common_web.EventTypeHIDName[evID] }), ) @@ -45,12 +48,16 @@ const (
+ + {{ formatDate(props.value) }} + + {{ evIdToString(props.value) }} diff --git a/web_client/hvueCompHIDJobs.go b/web_client/hvueCompHIDJobs.go index 2c9c7e6..6a72ca7 100644 --- a/web_client/hvueCompHIDJobs.go +++ b/web_client/hvueCompHIDJobs.go @@ -123,13 +123,16 @@ ScriptSource string `js:"textSource"` {{ job.textResult }} + + show job result + - + cancel HIDScript job {{ job.id }} - + @@ -141,15 +144,31 @@ ScriptSource string `js:"textSource"` compHIDJobOverviewTemplate = ` - Running - + + + + + - + @@ -160,7 +179,12 @@ compHIDJobOverviewTemplate = ` diff --git a/web_client/hvueCompHIDScript.go b/web_client/hvueCompHIDScript.go index 84fb07c..31f0683 100644 --- a/web_client/hvueCompHIDScript.go +++ b/web_client/hvueCompHIDScript.go @@ -5,7 +5,6 @@ package main import ( "github.com/gopherjs/gopherjs/js" "github.com/mame82/hvue" - "strconv" ) type CompHIDScriptCodeEditorData struct { @@ -13,28 +12,6 @@ type CompHIDScriptCodeEditorData struct { 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 { *js.Object Name string `js:"name"` @@ -80,7 +57,6 @@ func InitComponentsHIDScript() { "hid-script-code-editor", hvue.Template(compHIDScriptCodeEditorTemplate), hvue.DataFunc(newCompHIDScriptCodeEditorData), - hvue.Method("SendAndRun", SendAndRun), hvue.ComputedWithGetSet( "scriptContent", func(vm *hvue.VM) interface{} { @@ -133,7 +109,10 @@ func InitComponentsHIDScript() { vm.Get("$q").Call("notify", "store " + name.String()) 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) + }), ) } diff --git a/web_client/hvueCompLogger.go b/web_client/hvueCompLogger.go index 4ff0368..b3d6b62 100644 --- a/web_client/hvueCompLogger.go +++ b/web_client/hvueCompLogger.go @@ -3,6 +3,7 @@ package main import ( + "github.com/gopherjs/gopherjs/js" "github.com/mame82/hvue" ) @@ -30,22 +31,25 @@ func InitCompLogger() { hvue.NewComponent( "logger", hvue.Template(compLoggerTemplate), -// hvue.DataFunc(NewLoggerData), -// hvue.MethodsOf(&CompLoggerData{}), + hvue.DataFunc(func(vm *hvue.VM) interface{} { + data := &struct { + *js.Object + Pagination *jsDataTablePagination `js:"pagination"` + }{Object:O()} + + data.Pagination = newPagination(0, 1) + + return data + }), hvue.Method("logLevelClass", LogLevelClass), 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{} { 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", func(vm *hvue.VM) interface{} { return vm.Get("$store").Get("state").Get("EventProcessor").Get("logArray") @@ -57,7 +61,24 @@ func InitCompLogger() { const ( compLoggerTemplate = ` - + + +
+ + + {{ formatDate(props.value) }} + + +
+
+ +
` ) diff --git a/web_client/hvueCompUSBSettings.go b/web_client/hvueCompUSBSettings.go index faa0542..13cba23 100644 --- a/web_client/hvueCompUSBSettings.go +++ b/web_client/hvueCompUSBSettings.go @@ -115,7 +115,7 @@ const (
- USB Gadget Settings + USB Gadget Settings ({{ deploying }}) diff --git a/web_client/hvueComponentsBluetooth.go b/web_client/hvueComponentsBluetooth.go index c07e9a9..e9fc8c4 100644 --- a/web_client/hvueComponentsBluetooth.go +++ b/web_client/hvueComponentsBluetooth.go @@ -359,19 +359,23 @@ const templateBluetoothPage = `
- +
- -
-
- +
+
+ +
+
+ +
+
diff --git a/web_client/jsDataHandling.go b/web_client/jsDataHandling.go index bd77e79..74343be 100644 --- a/web_client/jsDataHandling.go +++ b/web_client/jsDataHandling.go @@ -234,7 +234,7 @@ type jsLogEvent struct { EvLogSource string `js:"source"` EvLogLevel int `js:"level"` EvLogMessage string `js:"message"` - EvLogTime string `js:"time"` + EvLogTime int64 `js:"time"` } //HID event @@ -247,7 +247,7 @@ type jsHidEvent struct { Result string `js:"result"` Error string `js:"error"` Message string `js:"message"` - EvLogTime string `js:"time"` + EvLogTime int64 `js:"time"` } func (jsEv *jsEvent) toLogEvent() (res *jsLogEvent, err error) { @@ -273,10 +273,11 @@ func (jsEv *jsEvent) toLogEvent() (res *jsLogEvent, err error) { return nil, eNoLogEvent } - res.EvLogTime, ok = jsEv.Values[3].(string) + res.EvLogTime, ok = jsEv.Values[3].(int64) if !ok { return nil, eNoLogEvent } + println("EvLogTime", res.EvLogTime) return res, nil } @@ -323,7 +324,7 @@ func (jsEv *jsEvent) toHidEvent() (res *jsHidEvent, err error) { return nil, eNoHidEvent } - res.EvLogTime, ok = jsEv.Values[7].(string) + res.EvLogTime, ok = jsEv.Values[7].(int64) if !ok { return nil, eNoHidEvent } @@ -341,7 +342,7 @@ type jsHidJobState struct { LastMessage string `js:"lastMessage"` TextResult string `js:"textResult"` // TextError string `js:"textError"` - LastUpdateTime string `js:"lastUpdateTime"` //JSON timestamp from server + LastUpdateTime int64 `js:"lastUpdateTime"` //JSON timestamp from server 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. // 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" -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)) //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, "") 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: 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) - - /* - 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: data.JobList.UpdateEntry(hEv.JobId, hEv.VMId, true, false, hEv.Message, hEv.Message, hEv.EvLogTime, "") default: diff --git a/web_client/main.go b/web_client/main.go index c51a040..508a104 100644 --- a/web_client/main.go +++ b/web_client/main.go @@ -47,19 +47,18 @@ func Router(router *js.Object) hvue.ComponentOption { func main() { println(GetBaseURL()) -println("====================---------") 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) // ToDo: delete because debug // RpcClient.GetAllDeployedEthernetInterfaceSettings(time.Second*10) - router := NewVueRouter("/usb", - VueRouterRoute("/usb","", ""), + router := NewVueRouter( + "/usb", // route below could be used for an easter egg //VueRouterRoute("/","", ""), + VueRouterRoute("/usb","", ""), VueRouterRoute("/hid","", ""), VueRouterRoute("/hidjobs","", ""), VueRouterRoute("/logger","", ""), @@ -88,25 +87,7 @@ println("====================---------") vm := hvue.NewVM( hvue.El("#app"), 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 - hvue.Computed( - "console", - func(vm *hvue.VM) interface{} { - return js.Global.Get("console") - }), hvue.Computed("state", func(vm *hvue.VM) interface{} { return vm.Get("$store").Get("state") //works only with Vuex store option added }), @@ -118,7 +99,6 @@ println("====================---------") ) // ToDo: remove next lines, debug code js.Global.Set("vm",vm) - js.Global.Set("rpc", RpcClient) } const templateMainApp = ` @@ -132,13 +112,13 @@ const templateMainApp = ` - - - - - + + + + + @@ -155,14 +135,6 @@ const templateMainApp = ` - diff --git a/web_client/mvuexGlobalState.go b/web_client/mvuexGlobalState.go index 359a479..5d098ec 100644 --- a/web_client/mvuexGlobalState.go +++ b/web_client/mvuexGlobalState.go @@ -12,6 +12,7 @@ import ( "github.com/pkg/errors" "io" "path/filepath" + "strconv" "strings" "time" ) @@ -45,12 +46,14 @@ const ( //HIDScripts and jobs VUEX_ACTION_UPDATE_RUNNING_HID_JOBS = "updateRunningHidJobs" - VUEX_ACTION_REMOVE_SUCCEEDED_HID_JOBS = "removeSucceededHidJobs" - VUEX_ACTION_REMOVE_FAILED_HID_JOBS = "removeFailedHidJobs" + VUEX_ACTION_REMOVE_SUCCEEDED_HID_JOBS = "removeSucceededHidJobs" + VUEX_ACTION_REMOVE_FAILED_HID_JOBS = "removeFailedHidJobs" VUEX_ACTION_UPDATE_STORED_HID_SCRIPTS_LIST = "updateStoredHIDScriptsList" VUEX_ACTION_UPDATE_CURRENT_HID_SCRIPT_SOURCE_FROM_REMOTE_FILE = "updateCurrentHidScriptSourceFromRemoteFile" 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_STORED_HID_SCRIPTS_LIST = "setStoredHIDScriptsList" @@ -155,6 +158,7 @@ func createGlobalStateStruct() GlobalState { state.Title = "P4wnP1 by MaMe82" state.CurrentHIDScriptSource = initHIDScript state.CurrentGadgetSettings = NewUSBGadgetSettings() + state.CurrentlyDeployingGadgetSettings = false state.CurrentlyDeployingWifiSettings = false state.HidJobList = NewHIDJobStateList() 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: store.Dispatch(VUEX_ACTION_UPDATE_ALL_ETHERNET_INTERFACE_SETTINGS) 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: store.Dispatch(VUEX_ACTION_UPDATE_WIFI_STATE) 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) { - - go func() { id := uint32(jobID.Int()) 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) }() + 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 } @@ -932,7 +974,8 @@ func actionUpdateRunningHidJobs(store *mvuex.Store, context *mvuex.ActionContext for _, jobstate := range jobstates { 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 QuasarNotify(notification) + return }() return @@ -1267,9 +1311,12 @@ func initMVuex() *mvuex.Store { mvuex.Action(VUEX_ACTION_START_EVENT_LISTEN, actionStartEventListen), mvuex.Action(VUEX_ACTION_STOP_EVENT_LISTEN, actionStopEventListen), + mvuex.Action(VUEX_ACTION_REMOVE_SUCCEEDED_HID_JOBS, actionRemoveSucceededHidJobs), mvuex.Action(VUEX_ACTION_REMOVE_FAILED_HID_JOBS, actionRemoveFailedHidJobs), 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{} { @@ -1327,6 +1374,9 @@ func initMVuex() *mvuex.Store { }), ) + store.Dispatch(VUEX_ACTION_START_EVENT_LISTEN) + +/* // fetch deployed gadget settings store.Dispatch(VUEX_ACTION_UPDATE_CURRENT_USB_SETTINGS) @@ -1335,14 +1385,14 @@ func initMVuex() *mvuex.Store { // 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 } 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 } diff --git a/web_client/rpcClient.go b/web_client/rpcClient.go index 8ee5e22..8515254 100644 --- a/web_client/rpcClient.go +++ b/web_client/rpcClient.go @@ -29,6 +29,40 @@ func NewRpcClient(addr string) Rpc { 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) { ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel()