script.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. // script
  2. package util
  3. import (
  4. "encoding/json"
  5. "fmt"
  6. "log"
  7. qu "qfw/util"
  8. ljson "github.com/yuin/gopher-json"
  9. "github.com/yuin/gopher-lua"
  10. )
  11. type LuaScript struct {
  12. Code, Name, Script string
  13. Doc map[string]interface{} //经过前置过滤的源信息
  14. Block []*Block //分块信息
  15. KvMap map[string][]map[string]interface{}
  16. Result map[string][]map[string]interface{} //抽取结果信息
  17. L *lua.LState
  18. }
  19. func (s *LuaScript) ClearRunScript() map[string]interface{} {
  20. data := map[string]interface{}{}
  21. qu.Try(func() {
  22. s.L = lua.NewState() //创建lua虚拟机
  23. s.L.PreloadModule("json", ljson.Loader)
  24. defer s.L.Close()
  25. if err := s.L.DoString(s.Script); err != nil {
  26. data["err"] = err.Error()
  27. } else {
  28. //doc:每条结果数据
  29. //KvMap:合并数据的list
  30. tab := MapToLuaTable(s.L, s.Doc)
  31. kvMap := MapToLuaTable2(s.L, s.KvMap)
  32. if err := s.L.CallByParam(lua.P{
  33. Fn: s.L.GetGlobal("main"),
  34. NRet: 1,
  35. Protect: true,
  36. }, lua.LString(s.Code), tab, kvMap); err != nil {
  37. data["err"] = err.Error()
  38. }
  39. ret := s.L.Get(-1)
  40. s.L.Pop(1)
  41. if tmp, ok := ret.(*lua.LTable); ok {
  42. data = LuaTableToMap(tmp)
  43. } else {
  44. data["rep"] = ret
  45. }
  46. }
  47. }, func(err interface{}) {
  48. log.Println("lua err:", data["err"])
  49. })
  50. return data
  51. }
  52. //stype per:前置,core:抽取,back:后置
  53. func (s *LuaScript) RunScript(stype string) map[string]interface{} {
  54. data := map[string]interface{}{}
  55. qu.Try(func() {
  56. s.L = lua.NewState()
  57. s.L.PreloadModule("json", ljson.Loader)
  58. defer s.L.Close()
  59. if err := s.L.DoString(s.Script); err != nil {
  60. data["err"] = err.Error()
  61. } else {
  62. if stype == "pre" {
  63. tab := MapToLuaTable(s.L, s.Doc)
  64. if err := s.L.CallByParam(lua.P{
  65. Fn: s.L.GetGlobal("main"),
  66. NRet: 1,
  67. Protect: true,
  68. }, lua.LString(s.Code), tab); err != nil {
  69. data["err"] = err.Error()
  70. }
  71. } else if stype == "core" {
  72. tab := MapToLuaTable(s.L, s.Doc)
  73. block, _ := json.Marshal(s.Block)
  74. kvMap := MapToLuaTable2(s.L, s.KvMap)
  75. if err := s.L.CallByParam(lua.P{
  76. Fn: s.L.GetGlobal("main"),
  77. NRet: 1,
  78. Protect: true,
  79. }, lua.LString(s.Code), tab, lua.LString(block), kvMap); err != nil {
  80. data["err"] = err.Error()
  81. }
  82. } else if stype == "back" {
  83. result := MapToLuaTable2(s.L, s.Result)
  84. if err := s.L.CallByParam(lua.P{
  85. Fn: s.L.GetGlobal("main"),
  86. NRet: 1,
  87. Protect: true,
  88. }, lua.LString(s.Code), result); err != nil {
  89. data["err"] = err.Error()
  90. }
  91. }
  92. ret := s.L.Get(-1)
  93. s.L.Pop(1)
  94. if tmp, ok := ret.(*lua.LTable); ok {
  95. data = LuaTableToMap(tmp)
  96. } else {
  97. data["rep"] = ret
  98. }
  99. }
  100. }, func(err interface{}) {
  101. log.Println("lua err:", err)
  102. })
  103. return data
  104. }
  105. func Logic(str string, doc map[string]interface{}) bool {
  106. b := false
  107. var errs error
  108. qu.Try(func() {
  109. L := lua.NewState()
  110. L.PreloadModule("json", ljson.Loader)
  111. defer L.Close()
  112. if err := L.DoString(str); err != nil {
  113. errs = err
  114. } else {
  115. tab := MapToLuaTable(L, doc)
  116. if err := L.CallByParam(lua.P{
  117. Fn: L.GetGlobal("logic"),
  118. NRet: 1,
  119. Protect: true,
  120. }, tab); err != nil {
  121. errs = err
  122. }
  123. ret := L.Get(-1)
  124. L.Pop(1)
  125. if ret.String() == "true" {
  126. b = true
  127. }
  128. }
  129. }, func(err interface{}) {
  130. log.Println("lua err:", errs)
  131. })
  132. return b
  133. }
  134. func MapToLuaTable(l *lua.LState, obj map[string]interface{}) *lua.LTable {
  135. tab := l.NewTable()
  136. for k, v := range obj {
  137. if val, ok := v.(string); ok {
  138. tab.RawSet(lua.LString(k), lua.LString(val))
  139. } else if val, ok := v.(int64); ok {
  140. tab.RawSet(lua.LString(k), lua.LNumber(val))
  141. } else if val, ok := v.(int32); ok {
  142. tab.RawSet(lua.LString(k), lua.LNumber(val))
  143. } else if val, ok := v.(int); ok {
  144. tab.RawSet(lua.LString(k), lua.LNumber(val))
  145. } else if val, ok := v.(float64); ok {
  146. tab.RawSet(lua.LString(k), lua.LNumber(val))
  147. } else if val, ok := v.(float32); ok {
  148. tab.RawSet(lua.LString(k), lua.LNumber(val))
  149. } else if val, ok := v.(bool); ok {
  150. tab.RawSet(lua.LString(k), lua.LBool(val))
  151. } else if val ,ok := v.(map[string]bool);ok{//把map的value值为true的存储为数组
  152. tb := l.NewTable()
  153. var i int
  154. for k2,_ := range val{
  155. tb.Insert(i, lua.LString(k2))
  156. i+=1
  157. }
  158. tab.RawSet(lua.LString(k), tb)
  159. } else if val, ok := v.(map[string]interface{}); ok {
  160. tab.RawSet(lua.LString(k), MapToLuaTable(l, val))
  161. } else if val, ok := v.([]string); ok {
  162. tb := l.NewTable()
  163. for k, vv := range val {
  164. tb.Insert(k, lua.LString(vv))
  165. }
  166. tab.RawSet(lua.LString(k), tb)
  167. } else if val, ok := v.([]map[string]interface{}); ok {
  168. tab2 := l.NewTable()
  169. for i, v := range val {
  170. tab2.Insert(i, MapToLuaTable(l, v))
  171. }
  172. tab.RawSet(lua.LString(k), tab2)
  173. } else if val, ok := v.([]interface{}); ok {
  174. bs, _ := json.Marshal(val)
  175. tab.RawSet(lua.LString(k), lua.LString(string(bs)))
  176. }
  177. }
  178. return tab
  179. }
  180. func MapToLuaTable2(l *lua.LState, obj map[string][]map[string]interface{}) *lua.LTable {
  181. tab := l.NewTable()
  182. for k, ms := range obj {
  183. tab2 := l.NewTable()
  184. for i, v := range ms {
  185. tab2.Insert(i+1 /*加1防止顺序错乱*/, MapToLuaTable(l, v))
  186. }
  187. tab.RawSet(lua.LString(k), tab2)
  188. }
  189. return tab
  190. }
  191. func LuaTableToMap(param *lua.LTable) map[string]interface{} {
  192. tmp := map[string]interface{}{}
  193. param.ForEach(func(key, val lua.LValue) {
  194. kk := fmt.Sprint(key)
  195. if v, ok := val.(lua.LString); ok {
  196. tmp[kk] = string(v)
  197. } else if v, ok := val.(*lua.LTable); ok {
  198. if kk == "blocktag"{//分块
  199. t := map[string]bool{}
  200. v.ForEach(func(value lua.LValue, value2 lua.LValue) {
  201. t[value2.String()]=true
  202. })
  203. tmp[kk] = t
  204. return
  205. }
  206. t := []map[string]interface{}{}
  207. v.ForEach(func(k, inv lua.LValue) {
  208. if vv, ok := inv.(*lua.LTable); ok {
  209. t = append(t, LuaTableToMap(vv))
  210. }
  211. })
  212. tmp[kk] = t
  213. } else if v, ok := val.(*lua.LBool); ok {
  214. if v.String() == "true" {
  215. tmp[kk] = true
  216. } else {
  217. tmp[kk] = false
  218. }
  219. } else if kk == "comeintime" || kk == "publishtime" {
  220. tmp[kk] = qu.Int64All(val.String())
  221. } else if v, ok := val.(*lua.LNumber); ok {
  222. tmp[kk] = qu.Float64All(v.String())
  223. } else if v, ok := val.(lua.LNumber); ok {
  224. tmp[kk] = qu.Float64All(v.String())
  225. } else {
  226. tmp[kk] = val
  227. }
  228. })
  229. return tmp
  230. }