From cb0358dbb4695271056a13075114090555000f63 Mon Sep 17 00:00:00 2001 From: serr Date: Fri, 11 Apr 2025 11:12:38 +0300 Subject: [PATCH] facade --- main.go | 50 +++++---------- mvc/controllers/controllers_pages/main.go | 10 +-- mvc/controllers/controllers_pages/main_ru.go | 8 +-- mvc/controllers/controllers_pages/post.go | 12 ++-- mvc/controllers/controllers_pages/posts.go | 8 +-- mvc/models/app.go | 66 ++++++++------------ mvc/models/cache.go | 12 ++-- mvc/models/config.go | 21 ++++--- mvc/models/models_pages/posts.go | 21 +++---- mvc/models/templates.go | 31 +++++++++ 10 files changed, 115 insertions(+), 124 deletions(-) create mode 100644 mvc/models/templates.go diff --git a/main.go b/main.go index 1274015..f4f32e3 100644 --- a/main.go +++ b/main.go @@ -6,75 +6,57 @@ import ( "main/mvc/controllers" "main/mvc/controllers/controllers_pages" "main/mvc/models" - "main/mvc/models/models_pages" "main/tools" "net/http" ) func main() { var err error - // Инициализация конфига - if err := models.Cfg.Load("config.json"); err != nil { - log.Fatal(err) - } + var app *models.App - // Загрузка постов - if err := models_pages.LoadPosts(models.Cfg.PostsDir); err != nil { - log.Fatal(err) - } - - // Инициализация приложения (обязательно после инициализации конфига) - if err := models.InitApp(); err != nil { + // Инициализация приложения + if app, err = models.InitApp(); err != nil { log.Fatal(err) } // Добавление префикса в виде домена сервера к записям в лог - log.SetPrefix(fmt.Sprintf("%s | ", models.Cfg.ServerDomain)) + log.SetPrefix(fmt.Sprintf("%s | ", app.Cfg.ServerDomain)) - // Настройка маршрутов и запуск - if setupRoutesAndRun() != nil { - log.Fatal(err) - } -} - -func setupRoutesAndRun() error { // Настройка маршрутов - router := setupRoutes() + router := setupRoutes(app) // Запуск сервера - if ok, err := tools.IsIPInUse(models.Cfg.ServerIP); err != nil { - return err + if ok, err := tools.IsIPInUse(app.Cfg.ServerIP); err != nil { + log.Fatal(err) } else if ok { - runServer(models.Cfg.ServerIP, models.Cfg.ServerPort, router) + runServer(app.Cfg.ServerIP, app.Cfg.ServerPort, router) } else { - runServer(models.Cfg.LocalIP, models.Cfg.LocalPort, router) + runServer(app.Cfg.LocalIP, app.Cfg.LocalPort, router) } - - return nil } // Настраивает маршруты -func setupRoutes() *http.ServeMux { +func setupRoutes(app *models.App) *http.ServeMux { router := http.NewServeMux() // Цепочка обработчиков, которые сработают до отдачи страницы юзеру m := controllers.MiddlewaresChain // Обработка статических файлов - router.Handle(models.Cfg.AssetsDir, m(controllers.StaticHandler())) + router.Handle(app.Cfg.AssetsDir, m(controllers.StaticHandler())) // Главные странички { // Обработка главной страницы (русская версия) - router.Handle("/ru/", m(controllers_pages.MainRuPageHandler())) + router.Handle("/ru/", m(controllers_pages.MainRuPageHandler(app))) // Обработка главной страницы - router.Handle("/", m(controllers_pages.MainPageHandler())) + router.Handle("/", m(controllers_pages.MainPageHandler(app))) // Обработка страницы со списком постов - router.Handle("/posts/", m(controllers_pages.PostsPageHandler())) + router.Handle("/posts/", m(controllers_pages.PostsPageHandler(app))) // Обработка страничек постов - for key := range models_pages.GetPosts() { + for key := range app.Posts { postLink := string(key) - router.Handle(postLink, m(controllers_pages.PostPageHandler())) + router.Handle(postLink, m(controllers_pages.PostPageHandler(app))) } } diff --git a/mvc/controllers/controllers_pages/main.go b/mvc/controllers/controllers_pages/main.go index 817c927..b8a2caa 100644 --- a/mvc/controllers/controllers_pages/main.go +++ b/mvc/controllers/controllers_pages/main.go @@ -10,7 +10,7 @@ import ( ) // Обработчик главной страницы -func MainPageHandler() http.HandlerFunc { +func MainPageHandler(app *models.App) http.HandlerFunc { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var err error @@ -18,7 +18,7 @@ func MainPageHandler() http.HandlerFunc { // Количество запросов, обработанных сервером за 24ч if r.Method == "COUNT" { var count []byte - if count, err = tools.GetJournalctlLogsCount("server", models.Cfg.ServerDomain, 24); err != nil { + if count, err = tools.GetJournalctlLogsCount("server", app.Cfg.ServerDomain, 24); err != nil { log.Printf("%s", err.Error()) } sendCount(w, count) @@ -38,14 +38,14 @@ func MainPageHandler() http.HandlerFunc { } // Страничка рендерится только если ее нет в кэше - pageData, ok := models.PagesCache.Get(models_pages.MainPageTmplName) + pageData, ok := app.PagesCache.Get(models_pages.MainPageTmplName) if !ok { - pageData, err = models_pages.RenderMainPage(models.App.Templates, models.App.Version) + pageData, err = models_pages.RenderMainPage(app.Templates, app.Version) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } - models.PagesCache.Set(models_pages.MainPageTmplName, pageData) + app.PagesCache.Set(models_pages.MainPageTmplName, pageData) } sendMainPage(w, pageData.([]byte)) diff --git a/mvc/controllers/controllers_pages/main_ru.go b/mvc/controllers/controllers_pages/main_ru.go index 3fed8e9..c864a8a 100644 --- a/mvc/controllers/controllers_pages/main_ru.go +++ b/mvc/controllers/controllers_pages/main_ru.go @@ -7,19 +7,19 @@ import ( ) // Обработчик главной страницы -func MainRuPageHandler() http.HandlerFunc { +func MainRuPageHandler(app *models.App) http.HandlerFunc { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var err error // Страничка рендерится только если ее нет в кэше - pageData, ok := models.PagesCache.Get(models_pages.MainRuPageTmplName) + pageData, ok := app.PagesCache.Get(models_pages.MainRuPageTmplName) if !ok { - pageData, err = models_pages.RenderMainRuPage(models.App.Templates, models.App.Version) + pageData, err = models_pages.RenderMainRuPage(app.Templates, app.Version) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } - models.PagesCache.Set(models_pages.MainRuPageTmplName, pageData) + app.PagesCache.Set(models_pages.MainRuPageTmplName, pageData) } sendMainRuPage(w, pageData.([]byte)) diff --git a/mvc/controllers/controllers_pages/post.go b/mvc/controllers/controllers_pages/post.go index ba792bb..7fa07b5 100644 --- a/mvc/controllers/controllers_pages/post.go +++ b/mvc/controllers/controllers_pages/post.go @@ -7,24 +7,22 @@ import ( ) // Обработчик главной страницы -func PostPageHandler() http.HandlerFunc { +func PostPageHandler(app *models.App) http.HandlerFunc { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var err error - posts := models_pages.GetPosts() - // Страничка рендерится только если ее нет в кэше - pageData, ok := models.PagesCache.Get(models_pages.PostPageTmplName) + pageData, ok := app.PagesCache.Get(models_pages.PostPageTmplName) if !ok { - post := posts[models_pages.PostLink(r.URL.Path)] + post := app.Posts[models_pages.PostLink(r.URL.Path)] - pageData, err = models_pages.RenderPostPage(models.App.Templates, models.App.Version, post.Data) + pageData, err = models_pages.RenderPostPage(app.Templates, app.Version, post.Data) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } - models.PagesCache.Set(models_pages.PostPageTmplName, pageData) + app.PagesCache.Set(models_pages.PostPageTmplName, pageData) } sendPostPage(w, pageData.([]byte)) diff --git a/mvc/controllers/controllers_pages/posts.go b/mvc/controllers/controllers_pages/posts.go index 40d89c1..90e0b22 100644 --- a/mvc/controllers/controllers_pages/posts.go +++ b/mvc/controllers/controllers_pages/posts.go @@ -7,19 +7,19 @@ import ( ) // Обработчик главной страницы -func PostsPageHandler() http.HandlerFunc { +func PostsPageHandler(app *models.App) http.HandlerFunc { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var err error // Страничка рендерится только если ее нет в кэше - pageData, ok := models.PagesCache.Get(models_pages.PostsPageTmplName) + pageData, ok := app.PagesCache.Get(models_pages.PostsPageTmplName) if !ok { - pageData, err = models_pages.RenderPostsPage(models.App.Templates, models.App.Version) + pageData, err = app.Posts.RenderPostsPage(app.Templates, app.Version) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } - models.PagesCache.Set(models_pages.PostsPageTmplName, pageData) + app.PagesCache.Set(models_pages.PostsPageTmplName, pageData) } sendPostsPage(w, pageData.([]byte)) diff --git a/mvc/models/app.go b/mvc/models/app.go index 40d015c..4d4297c 100644 --- a/mvc/models/app.go +++ b/mvc/models/app.go @@ -2,55 +2,39 @@ package models import ( "html/template" - "os" - "path/filepath" - "strings" + "main/mvc/models/models_pages" "time" ) -// App хранит шаблоны и время запуска -type app struct { - Templates *template.Template // Шаблоны страниц - Version int64 // Время запуска +type App struct { + Cfg *Config // Сонфиг + Posts models_pages.Posts // Посты + Templates *template.Template // Шаблоны страниц + PagesCache *Cache // Кэш (отрендеренные странички) + Version int64 // Время запуска } -var ( - App = &app{} -) - // Инициализирует приложение -func InitApp() error { +func InitApp() (*App, error) { + var err error - App.Version = time.Now().Unix() + app := &App{} + // Версия чтобы статика не кэшировалась + app.Version = time.Now().Unix() + // Загрузка конфига + if app.Cfg, err = loadConfig(ConfigPath); err != nil { + return nil, err + } + // Загрузка постов + if app.Posts, err = models_pages.LoadPosts(app.Cfg.PostsDir); err != nil { + return nil, err + } // Загрузка шаблонов - if err := App.loadTemplates(Cfg.TemplatesDir, Cfg.TemplatesExt); err != nil { - return err + if app.Templates, err = loadTemplates(app.Cfg.TemplatesDir, app.Cfg.TemplatesExt); err != nil { + return nil, err } - return nil -} - -// Загрузка шаблонов -func (a *app) loadTemplates(templatesPath string, ext string) error { - tmpls := template.New("") - - err := filepath.Walk(templatesPath, func(path string, f os.FileInfo, err error) error { - if err != nil { - return err - } - if !f.IsDir() && strings.HasSuffix(f.Name(), ext) { - _, err = tmpls.ParseFiles(path) - if err != nil { - return err - } - } - return nil - }) - - if err != nil { - return err - } - - a.Templates = tmpls - return nil + // Инициализация кэша + app.PagesCache = initCache() + return app, nil } diff --git a/mvc/models/cache.go b/mvc/models/cache.go index 847d5ef..9722d9d 100644 --- a/mvc/models/cache.go +++ b/mvc/models/cache.go @@ -2,23 +2,23 @@ package models import "sync" -type cache struct { +type Cache struct { Data map[string]any Mu sync.RWMutex } -var ( - PagesCache = cache{Data: make(map[string]any)} -) +func initCache() *Cache { + return &Cache{Data: make(map[string]any)} +} -func (c *cache) Get(key string) (any, bool) { +func (c *Cache) Get(key string) (any, bool) { c.Mu.RLock() pageData, ok := c.Data[key] c.Mu.RUnlock() return pageData, ok } -func (c *cache) Set(key string, data any) { +func (c *Cache) Set(key string, data any) { c.Mu.Lock() c.Data[key] = data c.Mu.Unlock() diff --git a/mvc/models/config.go b/mvc/models/config.go index 680f661..28215ba 100644 --- a/mvc/models/config.go +++ b/mvc/models/config.go @@ -5,7 +5,11 @@ import ( "os" ) -type config struct { +const ( + ConfigPath = "config.json" +) + +type Config struct { PostsDir string AssetsDir string TemplatesDir string @@ -18,18 +22,15 @@ type config struct { Port string } -var ( - Cfg = &config{} -) - -func (c *config) Load(configPath string) error { +func loadConfig(configPath string) (*Config, error) { + cfg := &Config{} configFile, err := os.ReadFile(configPath) if err != nil { - return err + return nil, err } - err = json.Unmarshal(configFile, c) + err = json.Unmarshal(configFile, cfg) if err != nil { - return err + return nil, err } - return nil + return cfg, nil } diff --git a/mvc/models/models_pages/posts.go b/mvc/models/models_pages/posts.go index 2a930be..298d0f5 100644 --- a/mvc/models/models_pages/posts.go +++ b/mvc/models/models_pages/posts.go @@ -17,17 +17,12 @@ const ( PostsPageTmplName = "posts.gohtml" ) -type posts map[PostLink]*Post +type Posts map[PostLink]*Post -var ( - allPosts = posts{} -) +func LoadPosts(dir string) (Posts, error) { -func GetPosts() posts { - return allPosts -} + posts := Posts{} -func LoadPosts(dir string) error { err := filepath.Walk(dir, func(path string, f os.FileInfo, err error) error { if err != nil { return err @@ -46,25 +41,25 @@ func LoadPosts(dir string) error { html := tools.MdToHTML(md) link := fmt.Sprintf("/%s/", strings.TrimSuffix(filepath.Base(path), ".md")) - allPosts[PostLink(link)] = newPost(link, html) + posts[PostLink(link)] = newPost(link, html) } return nil }) if err != nil { - return err + return nil, err } - return nil + return posts, nil } -func RenderPostsPage(templates *template.Template, version int64) ([]byte, error) { +func (p *Posts) RenderPostsPage(templates *template.Template, version int64) ([]byte, error) { var pageData bytes.Buffer context := map[string]any{ "version": version, "renderingTimestamp": time.Now().Unix(), - "posts": allPosts, + "posts": p, } if err := templates.ExecuteTemplate(&pageData, PostsPageTmplName, context); err != nil { diff --git a/mvc/models/templates.go b/mvc/models/templates.go new file mode 100644 index 0000000..08175e9 --- /dev/null +++ b/mvc/models/templates.go @@ -0,0 +1,31 @@ +package models + +import ( + "html/template" + "os" + "path/filepath" + "strings" +) + +func loadTemplates(templatesPath string, ext string) (*template.Template, error) { + tmpls := template.New("") + + err := filepath.Walk(templatesPath, func(path string, f os.FileInfo, err error) error { + if err != nil { + return err + } + if !f.IsDir() && strings.HasSuffix(f.Name(), ext) { + _, err = tmpls.ParseFiles(path) + if err != nil { + return err + } + } + return nil + }) + + if err != nil { + return nil, err + } + + return tmpls, nil +}