page_module.go 9.2 KB

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