script.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. // script
  2. package util
  3. import (
  4. "encoding/json"
  5. "fmt"
  6. ljson "github.com/yuin/gopher-json"
  7. "github.com/yuin/gopher-lua"
  8. )
  9. type LuaScript struct {
  10. Code, Name, Script string
  11. Doc map[string]interface{} //经过前置过滤的源信息
  12. Block []*Block //分块信息
  13. KvMap map[string][]map[string]interface{}
  14. Result map[string][]map[string]interface{} //抽取结果信息
  15. L *lua.LState
  16. }
  17. //stype per:前置,core:抽取,back:后置
  18. func (s *LuaScript) RunScript(stype string) map[string]interface{} {
  19. data := map[string]interface{}{}
  20. s.L = lua.NewState()
  21. s.L.PreloadModule("json", ljson.Loader)
  22. defer s.L.Close()
  23. if err := s.L.DoString(s.Script); err != nil {
  24. data["err"] = err.Error()
  25. } else {
  26. if stype == "pre" {
  27. tab := MapToLuaTable(s.L, s.Doc)
  28. if err := s.L.CallByParam(lua.P{
  29. Fn: s.L.GetGlobal("main"),
  30. NRet: 1,
  31. Protect: true,
  32. }, tab); err != nil {
  33. data["err"] = err.Error()
  34. }
  35. } else if stype == "core" {
  36. tab := MapToLuaTable(s.L, s.Doc)
  37. block, _ := json.Marshal(s.Block)
  38. kvMap := MapToLuaTable2(s.L, s.KvMap)
  39. if err := s.L.CallByParam(lua.P{
  40. Fn: s.L.GetGlobal("main"),
  41. NRet: 1,
  42. Protect: true,
  43. }, tab, lua.LString(block), kvMap); err != nil {
  44. data["err"] = err.Error()
  45. }
  46. } else if stype == "back" {
  47. result := MapToLuaTable2(s.L, s.Result)
  48. if err := s.L.CallByParam(lua.P{
  49. Fn: s.L.GetGlobal("main"),
  50. NRet: 1,
  51. Protect: true,
  52. }, result); err != nil {
  53. data["err"] = err.Error()
  54. }
  55. }
  56. ret := s.L.Get(-1)
  57. s.L.Pop(1)
  58. if tmp, ok := ret.(*lua.LTable); ok {
  59. data = LuaTableToMap(tmp)
  60. } else {
  61. data["rep"] = ret
  62. }
  63. }
  64. return data
  65. }
  66. func Logic(str string, doc map[string]interface{}) bool {
  67. L := lua.NewState()
  68. L.PreloadModule("json", ljson.Loader)
  69. defer L.Close()
  70. b := false
  71. if err := L.DoString(str); err != nil {
  72. panic(err)
  73. } else {
  74. tab := MapToLuaTable(L, doc)
  75. if err := L.CallByParam(lua.P{
  76. Fn: L.GetGlobal("logic"),
  77. NRet: 1,
  78. Protect: true,
  79. }, tab); err != nil {
  80. panic(err)
  81. }
  82. ret := L.Get(-1)
  83. L.Pop(1)
  84. if ret.String() == "true" {
  85. b = true
  86. }
  87. }
  88. return b
  89. }
  90. func MapToLuaTable(l *lua.LState, obj map[string]interface{}) *lua.LTable {
  91. tab := l.NewTable()
  92. for k, v := range obj {
  93. if val, ok := v.(string); ok {
  94. tab.RawSet(lua.LString(k), lua.LString(val))
  95. } else if val, ok := v.(int64); ok {
  96. tab.RawSet(lua.LString(k), lua.LNumber(val))
  97. } else if val, ok := v.(int32); ok {
  98. tab.RawSet(lua.LString(k), lua.LNumber(val))
  99. } else if val, ok := v.(float64); ok {
  100. tab.RawSet(lua.LString(k), lua.LNumber(val))
  101. } else if val, ok := v.(float32); ok {
  102. tab.RawSet(lua.LString(k), lua.LNumber(val))
  103. } else if val, ok := v.(bool); ok {
  104. tab.RawSet(lua.LString(k), lua.LBool(val))
  105. } else if val, ok := v.(map[string]interface{}); ok {
  106. tab.RawSet(lua.LString(k), MapToLuaTable(l, val))
  107. } else if val, ok := v.([]string); ok {
  108. tb := l.NewTable()
  109. for k, vv := range val {
  110. tb.Insert(k, lua.LString(vv))
  111. }
  112. tab.RawSet(lua.LString(k), tb)
  113. } else if val, ok := v.([]map[string]interface{}); ok {
  114. tab2 := l.NewTable()
  115. for i, v := range val {
  116. tab2.Insert(i, MapToLuaTable(l, v))
  117. }
  118. tab.RawSet(lua.LString(k), tab2)
  119. } else if val, ok := v.([]interface{}); ok {
  120. bs, _ := json.Marshal(val)
  121. tab.RawSet(lua.LString(k), lua.LString(string(bs)))
  122. }
  123. }
  124. return tab
  125. }
  126. func MapToLuaTable2(l *lua.LState, obj map[string][]map[string]interface{}) *lua.LTable {
  127. tab := l.NewTable()
  128. for k, ms := range obj {
  129. tab2 := l.NewTable()
  130. for i, v := range ms {
  131. tab2.Insert(i+1 /*加1防止顺序错乱*/, MapToLuaTable(l, v))
  132. }
  133. tab.RawSet(lua.LString(k), tab2)
  134. }
  135. return tab
  136. }
  137. func LuaTableToMap(param *lua.LTable) map[string]interface{} {
  138. tmp := map[string]interface{}{}
  139. param.ForEach(func(key, val lua.LValue) {
  140. kk := fmt.Sprint(key)
  141. if v, ok := val.(lua.LString); ok {
  142. tmp[kk] = string(v)
  143. } else if v, ok := val.(*lua.LTable); ok {
  144. t := []map[string]interface{}{}
  145. v.ForEach(func(k, inv lua.LValue) {
  146. if vv, ok := inv.(*lua.LTable); ok {
  147. t = append(t, LuaTableToMap(vv))
  148. }
  149. })
  150. tmp[kk] = t
  151. } else if v, ok := val.(*lua.LBool); ok {
  152. if v.String() == "true" {
  153. tmp[kk] = true
  154. } else {
  155. tmp[kk] = false
  156. }
  157. } else {
  158. tmp[kk] = v
  159. }
  160. })
  161. return tmp
  162. }