page_module.go 9.3 KB

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