func fetchConfig(funcname string, name string, config interface{}) bool { var ret otto.Value var err error if name == "" { ret, err = jsVM.Call(funcname, nil) } else { ret, err = jsVM.Call(funcname, nil, name) } if err != nil { log.Printf("call failed, in '%s', %v", funcname, err) return false } jsonConfig, err := ret.ToString() if err != nil { log.Println(err) return false } if err := json.Unmarshal([]byte(jsonConfig), config); err != nil { log.Printf("json.Unmarshal failed, in '%s', %v", funcname, err) return false } return true }
func (es *ExpressionStats) ConsiderValue(val otto.Value) { // increment the count es.Count += 1 if val.IsNumber() { f, err := val.ToFloat() if err != nil { log.Printf("Error converting number to float %v", err) } else { // update the sum es.Sum += f // if this is smaller than anything we've seen so far update the min if f < es.Min { es.Min = f } // if this is larger than anything we've seen so far update the max if f > es.Max { es.Max = f } // update the average (perhaps wasteful, could be done once at the end // but i'd have to walk the whole tree again, for now will do update it each time es.Avg = es.Sum / float64(es.Count) // we incremented es.count in this function, can not divide by 0 } } }
// find the node from the based ont the hash passed in // the hash needs to at least have a {name: }property func (js *JavascriptBuilder) findNode(token string, in otto.Value) (n Node, err error) { var ( givenOptions map[string]interface{} ok bool name string ) e, err := in.Export() if err != nil { return n, err } // accept both a json hash and a string as an argument. // if the arg is a hash, then we should extract the name, // and pull the node from the yaml, and then merge the given options // over top of the options presented in the config node. // // if the arg is a string, then use that string as the name // and pull the config node switch arg := e.(type) { case map[string]interface{}: givenOptions = arg if name, ok = givenOptions["name"].(string); ok { // merge the two maps tmpMap := make(map[string]interface{}) for k, v := range js.config.Nodes[name] { tmpMap[k] = v } for k, v := range givenOptions { tmpMap[k] = v } givenOptions = tmpMap } else { // we don't have a name, so lets generate one. u, err := uuid.NewV4() if err != nil { return n, fmt.Errorf("%s error. unable to create uuid (%s)", token, err.Error()) } name = u.String() givenOptions["name"] = name } case string: name = arg givenOptions, ok = js.config.Nodes[name] if !ok { return n, fmt.Errorf("%s error. unable to find node '%s'", token, name) } } if token == "transform" { // this is a little bit of magic so that transformers (which are added by the transform fn get the right kind) givenOptions["type"] = "transformer" } kind, ok := givenOptions["type"].(string) if !ok { return n, fmt.Errorf("%s: hash requires a type field, but no type given", token) } return NewNode(name, kind, givenOptions) }
// Execute Javascript func (sh *Shell) execScript(editor bool) stateFn { var out string var value otto.Value var err error if !editor { tmp := strings.TrimPrefix(sh.input, RunJavascript) // remove script meta-command value, err = sh.jsengine.Run(tmp) } else { value, err = sh.jsengine.Run(sh.input) } if err != nil { out = err.Error() } else if value.IsDefined() { out = value.String() } sh.write(out) if !editor { sh.line.AppendHistory(sh.input) } return bqlPrompt }
func formatObject(v otto.Value, width, indent, limit, level int, seen map[otto.Value]bool) (string, error) { if seen[v] { return strings.Repeat(" ", level*indent) + "[circular]", nil } o := v.Object() bits := []string{"{"} keys := o.Keys() for i, k := range keys { e, err := o.Get(k) d, err := formatIndent(e, width, indent, limit-1, level+1, len(k)+2, seenWith(seen, v)) if err != nil { return "", err } bits = append(bits, strings.Repeat(" ", (level+1)*indent)+k+": "+d+",") i++ } bits = append(bits, strings.Repeat(" ", level*indent)+"}") return strings.Join(bits, "\n"), nil }
func formatObjectOneLine(v otto.Value, limit int, seen map[otto.Value]bool) (string, error) { if limit == 0 { return "...", nil } if seen[v] { return "[circular]", nil } o := v.Object() bits := []string{} keys := o.Keys() for _, k := range keys { e, err := o.Get(k) if err != nil { return "", err } d, err := formatOneLine(e, limit-1, seenWith(seen, v)) if err != nil { return "", err } bits = append(bits, k+": "+d) } return "{" + strings.Join(bits, ", ") + "}", nil }
//GetInt64 gets int64 from otto value func GetInt64(value otto.Value) (result int64, err error) { result, err = value.ToInteger() if err != nil { err = fmt.Errorf(wrongArgumentType, value, "int64") } return }
func runIteratorWithCallback(it graph.Iterator, ses *Session, callback otto.Value, this otto.FunctionCall, limit int) { count := 0 it, _ = it.Optimize() for { if ses.doHalt { return } _, ok := it.Next() if !ok { break } tags := make(map[string]graph.TSVal) it.TagResults(&tags) val, _ := this.Otto.ToValue(tagsToValueMap(tags, ses)) val, _ = callback.Call(this.This, val) count++ if limit >= 0 && count >= limit { break } for it.NextResult() == true { if ses.doHalt { return } tags := make(map[string]graph.TSVal) it.TagResults(&tags) val, _ := this.Otto.ToValue(tagsToValueMap(tags, ses)) val, _ = callback.Call(this.This, val) count++ if limit >= 0 && count >= limit { break } } } it.Close() }
//GetBool gets bool from otto value func GetBool(value otto.Value) (bool, error) { rawBool, _ := value.Export() result, ok := rawBool.(bool) if !ok { return false, fmt.Errorf(wrongArgumentType, rawBool, "bool") } return result, nil }
//GetAuthorization gets Transaction from otto value func GetAuthorization(value otto.Value) (schema.Authorization, error) { rawAuthorization, _ := value.Export() result, ok := rawAuthorization.(schema.Authorization) if !ok { return nil, fmt.Errorf(wrongArgumentType, rawAuthorization, "Authorization") } return result, nil }
//GetTransaction gets Transaction from otto value func GetTransaction(value otto.Value) (transaction.Transaction, error) { rawTransaction, _ := value.Export() result, ok := rawTransaction.(transaction.Transaction) if !ok { return nil, fmt.Errorf(wrongArgumentType, rawTransaction, "Transaction") } return result, nil }
//GetString gets string from otto value func GetString(value otto.Value) (string, error) { rawString, _ := value.Export() result, ok := rawString.(string) if !ok { return "", fmt.Errorf(wrongArgumentType, rawString, "string") } return result, nil }
//GetStringList gets []string from otto value func GetStringList(value otto.Value) ([]string, error) { rawSlice, _ := value.Export() rawResult, ok := rawSlice.([]string) if !ok { return make([]string, 0), fmt.Errorf(wrongArgumentType, rawSlice, "array of strings") } return rawResult, nil }
func (f *JSFilter) Filter(ev *message.Event) (*message.Event, error) { var dropped bool f.vm.Set("$", map[string]interface{}{ "env": f.conf.Env, "event": map[string]interface{}{ "tag": ev.Tag, "time": ev.Time, "record": ev.Record, }, "drop": func(call otto.FunctionCall) otto.Value { dropped = true return otto.Value{} }, "emit": func(call otto.FunctionCall) (ret otto.Value) { var record otto.Value var t time.Time tag := call.Argument(0).String() if !call.Argument(2).IsDefined() { record = call.Argument(1) t = time.Now() } else { record = call.Argument(2) v, err := call.Argument(1).Export() if err != nil { f.env.Log.Warningf("Failed to get time: %v", err) return } var ok bool t, ok = v.(time.Time) if !ok { f.env.Log.Warningf("Failed to get time: unsupported type %T", v) return } } rec, err := record.Export() if err != nil { f.env.Log.Warningf("Failed to get record: %v", err) return } typedRec, ok := rec.(map[string]interface{}) if !ok { f.env.Log.Warningf("Failed to get record: Unsupported type %T", rec) return } f.env.Emit(message.NewEventWithTime(tag, t, typedRec)) return }, }) _, err := f.vm.Run(f.script) if err != nil { return nil, err } else if dropped { return nil, nil } return ev, nil }
//GetMap gets map[string]interface{} from otto value func GetMap(value otto.Value) (map[string]interface{}, error) { rawMap, _ := value.Export() result, ok := rawMap.(map[string]interface{}) if !ok { return map[string]interface{}{}, fmt.Errorf(wrongArgumentType, rawMap, "Object") } for key, value := range result { result[key] = ConvertOttoToGo(value) } return result, nil }
func (rm refMap) MustResolve(ref otto.Value) interface{} { key, err := ref.ToString() if err != nil { panic(err) } v, ok := rm[key] if !ok { panic(fmt.Sprintf("Invalid reference: %s", key)) } return v }
//GetOrCreateTransaction gets transaction from otto value or creates new is otto value is null func (env *Environment) GetOrCreateTransaction(value otto.Value) (transaction.Transaction, bool, error) { if !value.IsNull() { tx, err := GetTransaction(value) return tx, false, err } dataStore := env.DataStore tx, err := dataStore.Begin() if err != nil { return nil, false, fmt.Errorf("Error creating transaction: %v", err.Error()) } return tx, true, nil }
func (p *Plugin) AddCallback(eventCode string, name string, callback otto.Value) { wrappedCallback := func(env otto.Value) { _, err := callback.Call(env) if err != nil { p.log.Printf("Callback `%s` (%#v) for event code `%s` errored: %s", name, callback, eventCode, err) } } p.callbacks[eventCode] = append(p.callbacks[eventCode], &pluginFunc{ function: wrappedCallback, help: name, }) }
func (wk *worker) runIteratorWithCallback(it graph.Iterator, callback otto.Value, this otto.FunctionCall, limit int) { ctx, cancel := wk.newContext() defer cancel() err := graph.Iterate(ctx, it).Paths(true).Limit(limit).TagEach(func(tags map[string]graph.Value) { val, _ := this.Otto.ToValue(wk.tagsToValueMap(tags)) val, _ = callback.Call(this.This, val) }) if err != nil { clog.Errorf("gremlin: %v", err) } }
// uses the "prettyPrint" JS function to format a value func (self *JSRE) PrettyPrint(v interface{}) (val otto.Value, err error) { var method otto.Value v, err = self.vm.ToValue(v) if err != nil { return } method, err = self.vm.Get("prettyPrint") if err != nil { return } return method.Call(method, v) }
func (p *PacSandbox) ottoRetString(v otto.Value, rte error) (string, error) { if rte != nil { return "", rte } ret, err := v.ToString() if err != nil { return "", err } return ret, nil }
// PrettyPrint writes v to standard output. func (self *JSRE) PrettyPrint(v interface{}) (val otto.Value, err error) { var method otto.Value self.do(func(vm *otto.Otto) { val, err = vm.ToValue(v) if err != nil { return } method, err = vm.Get("prettyPrint") if err != nil { return } val, err = method.Call(method, val) }) return val, err }
//GetList gets []interface{} from otto value func GetList(value otto.Value) ([]interface{}, error) { rawSlice, err := value.Export() result := make([]interface{}, 0) if rawSlice == nil || err != nil { return result, err } typeOfSlice := reflect.TypeOf(rawSlice) if typeOfSlice.Kind() != reflect.Array && typeOfSlice.Kind() != reflect.Slice { return result, fmt.Errorf(wrongArgumentType, value, "array") } list := reflect.ValueOf(rawSlice) for i := 0; i < list.Len(); i++ { result = append(result, ConvertOttoToGo(list.Index(i).Interface())) } return result, err }
func (wk *worker) runIteratorWithCallback(it graph.Iterator, callback otto.Value, this otto.FunctionCall, limit int) { n := 0 it, _ = it.Optimize() if glog.V(2) { b, err := json.MarshalIndent(it.Describe(), "", " ") if err != nil { glog.V(2).Infof("failed to format description: %v", err) } else { glog.V(2).Infof("%s", b) } } for { select { case <-wk.kill: return default: } if !graph.Next(it) { break } tags := make(map[string]graph.Value) it.TagResults(tags) val, _ := this.Otto.ToValue(wk.tagsToValueMap(tags)) val, _ = callback.Call(this.This, val) n++ if limit >= 0 && n >= limit { break } for it.NextPath() { select { case <-wk.kill: return default: } tags := make(map[string]graph.Value) it.TagResults(tags) val, _ := this.Otto.ToValue(wk.tagsToValueMap(tags)) val, _ = callback.Call(this.This, val) n++ if limit >= 0 && n >= limit { break } } } it.Close() }
func (p *Plugin) SetCommand(name string, command otto.Value, help string) { if _, ok := p.commands[name]; ok { if p.cfg.Irc.Debug || p.cfg.Debug { p.log.Printf("Warning: Command `%s` was already defined. Overriding...", name) } } wrappedCommand := func(env otto.Value) { _, err := command.Call(env) if err != nil { p.log.Printf("Command `%s` errored: %s", name, err) } } p.commands[name] = &pluginFunc{ function: wrappedCommand, help: help, } }
func (ctrl *JsController) callHandler(handler otto.Value, params ...interface{}) (interface{}, error) { if !handler.IsFunction() { return nil, fmt.Errorf("Result should be a function, got %v", handler) } out, err := handler.Call(handler, params...) if err != nil { glog.Errorf("Call resulted in failure %#v", err) return nil, err } obj, err := out.Export() if err != nil { glog.Errorf("Failed to extract response %#v", err) return nil, err } return obj, nil }
func ottoValueToStringArray(value otto.Value) []string { { value, _ := value.Export() switch value := value.(type) { case string: return []string{value} case []interface{}: result := make([]string, 0, len(value)) for _, item := range value { if value, ok := item.(string); ok { result = append(result, value) } } return result } } return nil }
func objToHeader(data *otto.Value, header http.Header) { dataMap, _ := data.Export() for key, val := range dataMap.(map[string]interface{}) { switch val.(type) { case string: { header.Add(key, val.(string)) break } case []interface{}: { for _, headerVal := range val.([]interface{}) { header.Add(key, headerVal.(string)) } break } } } }
func formatArrayOneLine(v otto.Value, limit int, seen map[otto.Value]bool) (string, error) { if limit == 0 { return "...", nil } if seen[v] { return "[circular]", nil } o := v.Object() lv, err := o.Get("length") if err != nil { return "", err } li, err := lv.Export() if err != nil { return "", err } l, ok := li.(uint32) if !ok { return "", fmt.Errorf("length property must be a number; was %T", li) } var bits []string for i := 0; i < int(l); i++ { e, err := o.Get(fmt.Sprintf("%d", i)) if err != nil { return "", err } d, err := formatOneLine(e, limit-1, seenWith(seen, v)) if err != nil { return "", err } bits = append(bits, d) } return "[" + strings.Join(bits, ", ") + "]", nil }
// Converts a JS array into a Go string array. func ottoArrayToStrings(array otto.Value) []string { goValue, err := array.Export() if err != nil { return nil } if result, ok := goValue.([]string); ok { return result } goArray, ok := goValue.([]interface{}) if !ok || len(goArray) == 0 { return nil } result := make([]string, 0, len(goArray)) for _, item := range goArray { if str, ok := item.(string); ok { result = append(result, str) } } return result }