page_module.go 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. // package page_module -- страница показа модуля.
  2. package page_module
  3. import (
  4. _ "embed"
  5. "fmt"
  6. "strings"
  7. "github.com/gofiber/fiber/v3"
  8. "gitp78su.ipnodns.ru/svi/kern/v4/d0"
  9. "gitp78su.ipnodns.ru/svi/kern/v4/d1"
  10. "gitp78su.ipnodns.ru/svi/kern/v4/d2"
  11. "gitp78su.ipnodns.ru/svi/kern/v4/d3/mod_ent/mod_num"
  12. "gitp78su.ipnodns.ru/svi/kern/v4/d3/mod_spec"
  13. )
  14. // PageModule -- страница показа модуля.
  15. type PageModule struct {
  16. kCtx *d2.KernCtx
  17. }
  18. var (
  19. page *PageModule
  20. txtFiberApp = d0.LetTxt("fiberApp")
  21. )
  22. // GetPageModule -- возвращает страницу модуля.
  23. func GetPageModule() *d0.Result[*PageModule] {
  24. if page != nil {
  25. return d0.ResOk(page)
  26. }
  27. kCtx := d2.GetKernCtx()
  28. optFiber := kCtx.Get(txtFiberApp)
  29. if optFiber.IsNone() {
  30. err := d0.LetErr("GetPageModule(): not found fiberApp in kernel ctx")
  31. return d0.ResErr[*PageModule](err)
  32. }
  33. fiberApp := optFiber.Some().Val().(*fiber.App)
  34. kCtx.Set(txtFiberApp, fiberApp, "fiberApp in GetPageModule()")
  35. sf := &PageModule{
  36. kCtx: kCtx,
  37. }
  38. fiberApp.Post("/module/:id", sf.postModule)
  39. fiberApp.Post("/module_state/:id", sf.postModuleState)
  40. fiberApp.Post("/module_ctx/:id", sf.postModuleCtx)
  41. fiberApp.Post("/module_log/:id", sf.postModuleLog)
  42. fiberApp.Post("/module_svg_sec/svg_sec_:id.svg", sf.postSvgSec)
  43. fiberApp.Post("/module_svg_min/svg_min_:id.svg", sf.postSvgMin)
  44. fiberApp.Post("/module_svg_day/svg_day_:id.svg", sf.postSvgDay)
  45. page = sf
  46. return d0.ResOk(sf)
  47. }
  48. //go:embed log_block.html
  49. var strLogBlock string
  50. // Возвращает страницу лога модуля.
  51. func (sf *PageModule) postModuleLog(ctx fiber.Ctx) error {
  52. _modNum := ctx.Params("id", "1")
  53. resNum := mod_num.FromStr(d0.LetTxt(_modNum))
  54. if resNum.IsErr() {
  55. return ctx.SendString(resNum.Err().Error())
  56. }
  57. modNum := resNum.Ok()
  58. module, _ := sf.getModule(modNum)
  59. if module == nil {
  60. strOut := strings.ReplaceAll(strLogBlock, "{.id}", modNum.String())
  61. strOut = strings.ReplaceAll(strOut, "{.log}", strOut)
  62. strOut = strings.ReplaceAll(strOut, "{.name}", "not found")
  63. strOut = strings.ReplaceAll(strOut, "{.mod_state}", "")
  64. return ctx.SendString(strOut)
  65. }
  66. _log := module.Log()
  67. if module.Name().Get() == "kCtx" {
  68. _log = sf.kCtx.Log()
  69. }
  70. strOut := ""
  71. for i := range d0.Num(100) {
  72. msg := _log.Get(i).String()
  73. if strings.Contains(msg, "*no msg*") {
  74. continue
  75. }
  76. strOut += msg + "\n"
  77. }
  78. strOut = strings.ReplaceAll(strLogBlock, "{.log}", strOut)
  79. strOut = strings.ReplaceAll(strOut, "{.name}", module.Name().String())
  80. strOut = strings.ReplaceAll(strOut, "{.id}", _modNum)
  81. return ctx.SendString(strOut)
  82. }
  83. //go:embed ctx_row_val.html
  84. var strCtxRowVal string
  85. //go:embed ctx_row_block.html
  86. var strCtxRowBlock string
  87. // Возвращает блок контекста монолита.
  88. func (sf *PageModule) postModuleCtx(ctx fiber.Ctx) error {
  89. _modNum := ctx.Params("id", "1")
  90. resNum := mod_num.FromStr(d0.LetTxt(_modNum))
  91. if resNum.IsErr() {
  92. err := fmt.Errorf("PageModule.postModuleCtx(): in extract module num(%q), err=\n\t%w",
  93. _modNum, resNum.Err())
  94. return err
  95. }
  96. modNum := resNum.Ok()
  97. module, _ := sf.getModule(modNum)
  98. if module == nil {
  99. strOut := strings.ReplaceAll(strCtxRowBlock, "{.id}", modNum.String())
  100. strOut = strings.ReplaceAll(strOut, "{.name}", "not found")
  101. strOut = strings.ReplaceAll(strOut, "{.ctx_block}", "")
  102. return ctx.SendString(strOut)
  103. }
  104. mCtx := module.Ctx()
  105. lst := mCtx.SortedList()
  106. if module.Name().Get() == "kCtx" {
  107. lst = sf.kCtx.SortedList()
  108. }
  109. strOut := ""
  110. for _, val := range lst {
  111. strRow := strCtxRowVal
  112. strRow = strings.ReplaceAll(strRow, "{.key}", val.Key().String())
  113. _val := val.Val()
  114. valShort := fmt.Sprint(_val)
  115. runes := []rune(valShort)
  116. if len(runes) > 20 {
  117. runes = runes[:20]
  118. valShort = string(runes)
  119. }
  120. strRow = strings.ReplaceAll(strRow, "{.value}", valShort)
  121. _type := fmt.Sprintf("%#T", _val)
  122. _type = strings.ReplaceAll(_type, ".", ".<br>")
  123. strRow = strings.ReplaceAll(strRow, "{.type}", _type)
  124. strRow = strings.ReplaceAll(strRow, "{.createAt}", val.CreateAt().String())
  125. strRow = strings.ReplaceAll(strRow, "{.updateAt}", val.UpdateAt().String())
  126. strRow = strings.ReplaceAll(strRow, "{.comment}", val.Comment().String())
  127. strOut += strRow
  128. }
  129. strOut = strings.ReplaceAll(strCtxRowBlock, "{.ctx_block}", strOut)
  130. strOut = strings.ReplaceAll(strOut, "{.id}", modNum.String())
  131. strOut = strings.ReplaceAll(strOut, "{.name}", module.Name().String())
  132. return ctx.SendString(strOut)
  133. }
  134. //go:embed module_state.html
  135. var strStateModule string
  136. //go:embed module_state_block.html
  137. var strStateModuleBlock string
  138. // Показывает состояние модуля.
  139. func (sf *PageModule) postModuleState(ctx fiber.Ctx) error {
  140. _modNum := ctx.Params("id", "1")
  141. resNum := mod_num.FromStr(d0.LetTxt(_modNum))
  142. if resNum.IsErr() {
  143. err := fmt.Errorf("PageModule.postModuleState(): in extract module num(%q), err=\n\t%w",
  144. _modNum, resNum.Err())
  145. return err
  146. }
  147. modNum := resNum.Ok()
  148. module, modVal := sf.getModule(modNum)
  149. if module == nil {
  150. strOut := strings.ReplaceAll(strStateModuleBlock, "{.id}", "")
  151. return ctx.SendString(strOut)
  152. }
  153. dictState := map[string]any{}
  154. dictState["{.name}"] = module.Name()
  155. dictState["{.createAt}"] = modVal.CreateAt()
  156. dictState["{.updateAt}"] = modVal.UpdateAt()
  157. dictState["{.comment}"] = modVal.Comment()
  158. dictState["{.id}"] = modNum.String()
  159. dictState["{.live}"] = module.Live()
  160. dictState["{.svg_sec}"] = module.Stat().SvgSec()
  161. strOut := strStateModuleBlock
  162. for key, val := range dictState {
  163. strOut = strings.ReplaceAll(strOut, key, fmt.Sprint(val))
  164. }
  165. return ctx.SendString(strOut)
  166. }
  167. // Показывает состояние модуля.
  168. func (sf *PageModule) postModule(ctx fiber.Ctx) error {
  169. _modNum := ctx.Params("id", "1")
  170. resNum := mod_num.FromStr(d0.LetTxt(_modNum))
  171. if resNum.IsErr() {
  172. err := fmt.Errorf("PageModule.postModule(): in extract module num(%q), err=\n\t%w",
  173. _modNum, resNum.Err())
  174. return err
  175. }
  176. modNum := resNum.Ok()
  177. module, modVal := sf.getModule(modNum)
  178. if module == nil {
  179. strOut := strings.ReplaceAll(strStateModule, "{.name}", "unknown")
  180. strOut = strings.ReplaceAll(strOut, "{.mod_state}", "")
  181. strOut = strings.ReplaceAll(strOut, "{.id}", "")
  182. return ctx.SendString(strOut)
  183. }
  184. dictState := map[string]any{}
  185. dictState["{.name}"] = module.Name()
  186. dictState["{.createAt}"] = modVal.CreateAt()
  187. dictState["{.updateAt}"] = modVal.UpdateAt()
  188. dictState["{.comment}"] = modVal.Comment()
  189. // dictState["{.id}"] = id
  190. dictState["{.live}"] = module.Live()
  191. dictState["{.svg_sec}"] = module.Stat().SvgSec()
  192. strOut := strStateModuleBlock
  193. for key, val := range dictState {
  194. strOut = strings.ReplaceAll(strOut, key, fmt.Sprint(val))
  195. }
  196. {
  197. strOut = strings.ReplaceAll(strStateModule, "{.mod_state}", strOut)
  198. strOut = strings.ReplaceAll(strOut, "{.name}", module.Name().String())
  199. strOut = strings.ReplaceAll(strOut, "{.id}", modNum.String())
  200. }
  201. return ctx.SendString(strOut)
  202. }
  203. // Возвращает секундную статистику модуля.
  204. func (sf *PageModule) postSvgDay(ctx fiber.Ctx) error {
  205. _modNum := ctx.Params("id", "1")
  206. resNum := mod_num.FromStr(d0.LetTxt(_modNum))
  207. if resNum.IsErr() {
  208. err := fmt.Errorf("PageModule.postSvgDay(): in extract module num(%q), err=\n\t%w",
  209. _modNum, resNum.Err())
  210. return err
  211. }
  212. modNum := resNum.Ok()
  213. module, _ := sf.getModule(modNum)
  214. if module == nil {
  215. return ctx.SendString("")
  216. }
  217. strSvgSec := module.Stat().SvgDay()
  218. ctx.Set("Content-Type", "image/svg+xml")
  219. return ctx.SendString(strSvgSec.String())
  220. }
  221. // Возвращает секундную статистику модуля.
  222. func (sf *PageModule) postSvgMin(ctx fiber.Ctx) error {
  223. _modNum := ctx.Params("id", "1")
  224. resNum := mod_num.FromStr(d0.LetTxt(_modNum))
  225. if resNum.IsErr() {
  226. err := fmt.Errorf("PageModule.postSvgMin(): in extract module num(%q), err=\n\t%w",
  227. _modNum, resNum.Err())
  228. return err
  229. }
  230. modNum := resNum.Ok()
  231. module, _ := sf.getModule(modNum)
  232. if module == nil {
  233. return ctx.SendString("")
  234. }
  235. strSvgSec := module.Stat().SvgMin()
  236. ctx.Set("Content-Type", "image/svg+xml")
  237. return ctx.SendString(strSvgSec.String())
  238. }
  239. // Возвращает секундную статистику модуля.
  240. func (sf *PageModule) postSvgSec(ctx fiber.Ctx) error {
  241. _modNum := ctx.Params("id", "1")
  242. resNum := mod_num.FromStr(d0.LetTxt(_modNum))
  243. if resNum.IsErr() {
  244. err := fmt.Errorf("PageModule.postSvgSec(): in extract module num(%q), err=\n\t%w",
  245. _modNum, resNum.Err())
  246. return err
  247. }
  248. modNum := resNum.Ok()
  249. module, _ := sf.getModule(modNum)
  250. if module == nil {
  251. return ctx.SendString("")
  252. }
  253. strSvgSec := module.Stat().SvgSec()
  254. ctx.Set("Content-Type", "image/svg+xml")
  255. return ctx.SendString(strSvgSec.String())
  256. }
  257. // Возвращает модуль.
  258. func (sf *PageModule) getModule(modNum *mod_num.LModuleNum) (mod_spec.IKernelModule, *d1.CtxValue) {
  259. optMonolit := sf.kCtx.Get(d0.LetTxt("monolit"))
  260. if optMonolit.IsNone() {
  261. return nil, nil
  262. }
  263. mon := optMonolit.Some().Val().(mod_spec.IKernelMonolit)
  264. chLst := mon.Ctx().SortedList()
  265. var (
  266. val *d1.CtxValue
  267. isFind bool
  268. )
  269. for _, val = range chLst {
  270. name := "module_" + modNum.Get()
  271. if name == val.Key().Get() {
  272. isFind = true
  273. break
  274. }
  275. }
  276. if !isFind {
  277. return nil, nil
  278. }
  279. mod := val.Val().(mod_spec.IKernelModule)
  280. return mod, val
  281. }