page_module.go 9.3 KB

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