fiber.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. package fiber
  2. import (
  3. "html/template"
  4. "log"
  5. "strconv"
  6. "time"
  7. "github.com/dmitriygnatenko/internal/interfaces"
  8. "github.com/dmitriygnatenko/internal/services/handler"
  9. adminHandler "github.com/dmitriygnatenko/internal/services/handler/admin"
  10. "github.com/gofiber/fiber/v2"
  11. "github.com/gofiber/fiber/v2/middleware/basicauth"
  12. "github.com/gofiber/fiber/v2/middleware/cors"
  13. "github.com/gofiber/fiber/v2/middleware/monitor"
  14. "github.com/gofiber/fiber/v2/middleware/recover"
  15. "github.com/gofiber/template/html"
  16. )
  17. const (
  18. appName = "dmitriygnatenko"
  19. templatesPath = "./../../internal/templates"
  20. staticPath = "../../web"
  21. )
  22. func Init(sp interfaces.IServiceProvider) (*fiber.App, error) {
  23. fiberApp := fiber.New(getConfig(sp))
  24. // Configure web root
  25. fiberApp.Static("/", staticPath)
  26. // Configure CORS middleware
  27. fiberApp.Use(cors.New())
  28. // Configure recover middleware
  29. fiberApp.Use(recover.New())
  30. // Configure handlers
  31. fiberApp.Get("/", handler.MainPageHandler(sp))
  32. fiberApp.Get("/tag/:tag", handler.TagHandler(sp))
  33. fiberApp.Get("/article/:article", handler.ArticleHandler(sp))
  34. // Admin
  35. user := sp.GetEnvService().GetAdminUser()
  36. password := sp.GetEnvService().GetAdminPassword()
  37. if user != "" && password != "" {
  38. admin := fiberApp.Group("/admin", basicauth.New(basicauth.Config{
  39. Users: map[string]string{
  40. user: password,
  41. },
  42. }))
  43. admin.Get("/metrics", monitor.New(monitor.Config{}))
  44. admin.Get("/", adminHandler.ArticleHandler(sp))
  45. admin.All("/article/add", adminHandler.AddArticleHandler(sp))
  46. admin.All("/article/edit/:id<int>", adminHandler.EditArticleHandler(sp))
  47. admin.All("/article/delete/:id<int>", adminHandler.DeleteArticleHandler(sp))
  48. admin.Get("/tag", adminHandler.TagHandler(sp))
  49. admin.All("/tag/add", adminHandler.AddTagHandler(sp))
  50. admin.All("/tag/edit/:id<int>", adminHandler.EditTagHandler(sp))
  51. admin.All("/tag/delete/:id<int>", adminHandler.DeleteTagHandler(sp))
  52. }
  53. return fiberApp, nil
  54. }
  55. func getConfig(sp interfaces.IServiceProvider) fiber.Config {
  56. return fiber.Config{
  57. AppName: appName,
  58. DisableStartupMessage: true,
  59. Views: initEngine(sp.GetEnvService()),
  60. ErrorHandler: initErrorHandler(sp),
  61. }
  62. }
  63. func initEngine(env interfaces.IEnv) *html.Engine {
  64. engine := html.New(templatesPath, ".html")
  65. // nolint:gocritic
  66. engine.AddFunc("now", func() time.Time {
  67. return time.Now()
  68. })
  69. // nolint:gosec
  70. engine.AddFunc("noescape", func(str string) template.HTML {
  71. return template.HTML(str)
  72. })
  73. engine.AddFunc("gridsep", func(i, l int) bool {
  74. i++
  75. return i%3 == 0 && i != l
  76. })
  77. engine.AddFunc("version", func() string {
  78. return env.GetStaticVersion()
  79. })
  80. engine.AddFunc("ga", func() bool {
  81. return env.IsGAEnabled()
  82. })
  83. return engine
  84. }
  85. func initErrorHandler(sp interfaces.IServiceProvider) fiber.ErrorHandler {
  86. return func(ctx *fiber.Ctx, err error) error {
  87. errCode := fiber.StatusInternalServerError
  88. errText := err.Error()
  89. if e, ok := err.(*fiber.Error); ok {
  90. errCode = e.Code
  91. }
  92. var renderData fiber.Map
  93. if errCode == fiber.StatusNotFound {
  94. renderData = fiber.Map{
  95. "pageTitle": "Страница не найдена",
  96. "code": fiber.StatusNotFound,
  97. "text": "Запрашиваемая вами страница не найдена",
  98. }
  99. } else {
  100. renderData = fiber.Map{
  101. "pageTitle": "Внутренняя ошибка",
  102. "code": fiber.StatusInternalServerError,
  103. "text": "Внутренняя ошибка сервера, идем исправлять...",
  104. }
  105. }
  106. if errText != "" && errCode != fiber.StatusNotFound && errCode != fiber.StatusMethodNotAllowed {
  107. sendErr := sp.GetMailerService().Send(
  108. sp.GetEnvService().GetAdminEmail(),
  109. "Ошибка на сайте dmitriygnatenko.ru",
  110. "Код: "+strconv.Itoa(errCode)+"\r\n"+"Текст: "+errText,
  111. )
  112. if sendErr != nil {
  113. log.Print(sendErr)
  114. }
  115. }
  116. renderData["headTitle"] = "От слона к суслику - статьи про PHP, Go, алгоритмы"
  117. return ctx.Render("error", renderData, "_layout")
  118. }
  119. }