From 3bab5b3b51d786d246785d0b02964f7aa1afa166 Mon Sep 17 00:00:00 2001 From: Victor Lacasse-Beaudoin Date: Sun, 20 Aug 2023 16:19:05 -0400 Subject: [PATCH 1/2] Refactor api_handlers et web_handlers serverhandlers -> api_handlers html handlers dans cmd/server -> web_handlers --- .../api_handlers.go | 2 +- cmd/server.go | 268 ++---------------- web_handlers/web_handlers.go | 231 +++++++++++++++ 3 files changed, 254 insertions(+), 247 deletions(-) rename serverhandlers/serverhandlers.go => api_handlers/api_handlers.go (99%) create mode 100644 web_handlers/web_handlers.go diff --git a/serverhandlers/serverhandlers.go b/api_handlers/api_handlers.go similarity index 99% rename from serverhandlers/serverhandlers.go rename to api_handlers/api_handlers.go index e7c8e1f..3b8537b 100644 --- a/serverhandlers/serverhandlers.go +++ b/api_handlers/api_handlers.go @@ -1,4 +1,4 @@ -package serverhandlers +package api_handlers import ( "context" diff --git a/cmd/server.go b/cmd/server.go index 556c477..831946e 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -5,10 +5,8 @@ package cmd import ( "crypto/subtle" - "encoding/json" "fmt" "log" - "sort" "embed" "html/template" @@ -18,13 +16,12 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" - "git.agecem.com/agecem/agecem-org/api" + "git.agecem.com/agecem/agecem-org/api_handlers" "git.agecem.com/agecem/agecem-org/config" "git.agecem.com/agecem/agecem-org/media" - "git.agecem.com/agecem/agecem-org/models" "git.agecem.com/agecem/agecem-org/public" - "git.agecem.com/agecem/agecem-org/serverhandlers" "git.agecem.com/agecem/agecem-org/templates" + "git.agecem.com/agecem/agecem-org/web_handlers" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" ) @@ -201,51 +198,51 @@ func RunServer() { // API Routes - groupV1.GET("", serverhandlers.HandleV1) + groupV1.GET("", api_handlers.HandleV1) - groupV1.POST("/seed", serverhandlers.HandleV1Seed) + groupV1.POST("/seed", api_handlers.HandleV1Seed) - groupV1.GET("/bucket", serverhandlers.HandleV1BucketList) + groupV1.GET("/bucket", api_handlers.HandleV1BucketList) - groupV1.GET("/bucket/:bucket", serverhandlers.HandleV1BucketRead) + groupV1.GET("/bucket/:bucket", api_handlers.HandleV1BucketRead) - groupV1.POST("/bucket/:bucket", serverhandlers.HandleV1DocumentCreate) + groupV1.POST("/bucket/:bucket", api_handlers.HandleV1DocumentCreate) - groupV1.GET("/bucket/:bucket/:document", serverhandlers.HandleV1DocumentRead) + groupV1.GET("/bucket/:bucket/:document", api_handlers.HandleV1DocumentRead) - groupV1.PUT("/bucket/:bucket/:document", serverhandlers.HandleV1DocumentUpdate) + groupV1.PUT("/bucket/:bucket/:document", api_handlers.HandleV1DocumentUpdate) - groupV1.DELETE("/bucket/:bucket/:document", serverhandlers.HandleV1DocumentDelete) + groupV1.DELETE("/bucket/:bucket/:document", api_handlers.HandleV1DocumentDelete) // HTML Routes - e.GET("/", handleIndex) + e.GET("/", web_handlers.HandleIndex) - //e.GET("/a-propos", handleAPropos) + //e.GET("/a-propos", web_handlers.HandleAPropos) - //e.GET("/actualite", handleActualite) + //e.GET("/actualite", web_handlers.HandleActualite) - //e.GET("/actualite/:article", handleActualiteArticle) + //e.GET("/actualite/:article", web_handlers.HandleActualiteArticle) - e.GET("/vie-etudiante", handleVieEtudiante) + e.GET("/vie-etudiante", web_handlers.HandleVieEtudiante) - e.GET("/vie-etudiante/:organisme", handleVieEtudianteOrganisme) + e.GET("/vie-etudiante/:organisme", web_handlers.HandleVieEtudianteOrganisme) - e.GET("/documentation", handleDocumentation) + e.GET("/documentation", web_handlers.HandleDocumentation) - e.GET("/formulaires", handleFormulaires) + e.GET("/formulaires", web_handlers.HandleFormulaires) // Public Routes - e.GET("/public/documentation/:bucket/:document", handlePublicDocumentation) + e.GET("/public/documentation/:bucket/:document", web_handlers.HandlePublicDocumentation) // Admin Routes - groupAdmin.GET("", handleAdmin) + groupAdmin.GET("", web_handlers.HandleAdmin) - groupAdmin.GET("/documents/upload", handleAdminDocumentsUpload) + groupAdmin.GET("/documents/upload", web_handlers.HandleAdminDocumentsUpload) - groupAdmin.POST("/documents/upload", handleAdminDocumentsUploadPOST) + groupAdmin.POST("/documents/upload", web_handlers.HandleAdminDocumentsUploadPOST) e.Logger.Fatal(e.Start( fmt.Sprintf(":%d", cfg.Server.Port))) @@ -254,224 +251,3 @@ func RunServer() { func (t *Template) Render(w io.Writer, name string, data interface{}, c echo.Context) error { return t.templates.ExecuteTemplate(w, name, data) } - -// HTML Handlers - -func handleIndex(c echo.Context) error { - return c.Render(http.StatusOK, "index-html", nil) -} - -/* -func handleAPropos(c echo.Context) error { - return c.Render(http.StatusOK, "a-propos-html", nil) -} -*/ - -/* -func handleActualite(c echo.Context) error { - return c.Render(http.StatusOK, "actualite-html", nil) -} -*/ - -/* -func handleActualiteArticle(c echo.Context) error { - article := c.Param("article") - return c.String(http.StatusOK, fmt.Sprintf("Article: %s", article)) -} -*/ - -func handleVieEtudiante(c echo.Context) error { - return c.Render(http.StatusOK, "vie-etudiante-html", nil) -} - -func handleVieEtudianteOrganisme(c echo.Context) error { - organisme := c.Param("organisme") - return c.String(http.StatusOK, fmt.Sprintf("Organisme: %s", organisme)) -} - -func handleDocumentation(c echo.Context) error { - client, err := api.NewApiClientFromViper() - if err != nil { - return c.Render(http.StatusInternalServerError, "documentation-html", nil) - } - - result, err := client.Call(http.MethodGet, "/v1/bucket") - if err != nil { - return c.Render(http.StatusInternalServerError, "documentation-html", nil) - } - - var buckets map[string]string - - err = json.Unmarshal(result, &buckets) - if err != nil { - return c.Render(http.StatusInternalServerError, "documentation-html", nil) - } - - var data []models.Bucket - - for bucket, displayName := range buckets { - content, err := client.Call(http.MethodGet, fmt.Sprintf("/v1/bucket/%s", bucket)) - if err != nil { - return c.Render(http.StatusInternalServerError, "documentation-html", nil) - } - - var documents []string - - err = json.Unmarshal(content, &documents) - if err != nil { - return c.Render(http.StatusInternalServerError, "documentation-html", nil) - } - - // Ce bloc retire tous les caractères spéciaux d'une string - // N'est pas présentement activé, car les fichiers sont processed - // à la création de toute façon. - /* - reg, err := regexp.Compile("[^.a-zA-Z0-9_-]+") - if err != nil { - return c.Render(http.StatusInternalServerError, "documentation-html", nil) - } - - var documents_processed []string - - for _, document := range documents { - document_processed := reg.ReplaceAllString(document, "") - documents_processed = append(documents_processed, document_processed) - } - documents_processed := documents - */ - - data = append(data, models.Bucket{ - Name: bucket, - DisplayName: displayName, - Documents: documents, - }) - } - - sort.SliceStable(data, func(i, j int) bool { return data[i].Name < data[j].Name }) - - return c.Render(http.StatusOK, "documentation-html", data) -} - -func handleFormulaires(c echo.Context) error { - return c.Render(http.StatusOK, "formulaires-html", nil) -} - -func handlePublicDocumentation(c echo.Context) error { - client, err := api.NewApiClientFromViper() - if err != nil { - return c.JSON(http.StatusNotFound, map[string]string{"message": "Not Found"}) - } - - bucket := c.Param("bucket") - document := c.Param("document") - - result, err := client.Call(http.MethodGet, fmt.Sprintf("/v1/bucket/%s/%s", bucket, document)) - if err != nil { - return c.JSON(http.StatusNotFound, map[string]string{"message": "Not Found"}) - } - - // Check if result can fit inside a map containing a message - var result_map map[string]string - - err = json.Unmarshal(result, &result_map) - if err == nil { - return c.JSON(http.StatusBadRequest, result_map) - } - - return c.Blob(http.StatusOK, "application/octet-stream", result) -} - -func handleAdmin(c echo.Context) error { - return c.Render(http.StatusOK, "admin-html", nil) -} - -func handleAdminDocumentsUpload(c echo.Context) error { - client, err := api.NewApiClientFromViper() - if err != nil { - return c.Render(http.StatusInternalServerError, "documentation-html", nil) - } - - result, err := client.Call(http.MethodGet, "/v1/bucket") - if err != nil { - return c.Render(http.StatusInternalServerError, "documentation-html", nil) - } - - var buckets map[string]string - - err = json.Unmarshal(result, &buckets) - if err != nil { - return c.Render(http.StatusInternalServerError, "documentation-html", nil) - } - - var data struct { - Buckets []models.Bucket - Message string - } - - for bucketName, displayName := range buckets { - data.Buckets = append(data.Buckets, models.Bucket{ - Name: bucketName, - DisplayName: displayName, - }) - } - - return c.Render(http.StatusOK, "admin-upload-html", data) -} - -func handleAdminDocumentsUploadPOST(c echo.Context) error { - var data struct { - Buckets []models.Bucket - Message string - } - - client, err := api.NewApiClientFromViper() - if err != nil { - data.Message = fmt.Sprintf("handleAdminDocumentsUploadPOST#api.New: %s", err) - return c.Render(http.StatusInternalServerError, "admin-upload-html", data) - } - - result, err := client.Call(http.MethodGet, "/v1/bucket") - if err != nil { - data.Message = "Error during GET /v1/bucket" - return c.Render(http.StatusInternalServerError, "documentation-html", data) - } - - var buckets map[string]string - - err = json.Unmarshal(result, &buckets) - if err != nil { - return c.Render(http.StatusInternalServerError, "documentation-html", nil) - } - - for bucketName, displayName := range buckets { - data.Buckets = append(data.Buckets, models.Bucket{ - Name: bucketName, - DisplayName: displayName, - }) - } - - bucket := c.FormValue("bucket") - - document, err := c.FormFile("document") - if err != nil { - data.Message = fmt.Sprintf("handleAdminDocumentsUploadPOST#c.FormFile: %s", err) - return c.Render(http.StatusBadRequest, "admin-upload-html", data) - } - - response, err := client.UploadDocument(bucket, document) - if err != nil { - data.Message = fmt.Sprintf("handleAdminDocumentsUploadPOST#client.UploadDocument: %s", err) - return c.Render(http.StatusInternalServerError, "admin-upload-html", data) - } - - // Format response - var info, status string - - info = fmt.Sprintf("[%.0f] /public/documentation/%s/%s", response.Data.Size, response.Data.Bucket, response.Data.Object) - - status = response.Message - - data.Message = fmt.Sprintf("%s - %s", status, info) - - return c.Render(http.StatusOK, "admin-upload-html", data) -} diff --git a/web_handlers/web_handlers.go b/web_handlers/web_handlers.go new file mode 100644 index 0000000..e9639cd --- /dev/null +++ b/web_handlers/web_handlers.go @@ -0,0 +1,231 @@ +package web_handlers + +import ( + "encoding/json" + "fmt" + "net/http" + "sort" + + "git.agecem.com/agecem/agecem-org/api" + "git.agecem.com/agecem/agecem-org/models" + "github.com/labstack/echo/v4" +) + +func HandleIndex(c echo.Context) error { + return c.Render(http.StatusOK, "index-html", nil) +} + +/* +func HandleAPropos(c echo.Context) error { + return c.Render(http.StatusOK, "a-propos-html", nil) +} +*/ + +/* +func HandleActualite(c echo.Context) error { + return c.Render(http.StatusOK, "actualite-html", nil) +} +*/ + +/* +func HandleActualiteArticle(c echo.Context) error { + article := c.Param("article") + return c.String(http.StatusOK, fmt.Sprintf("Article: %s", article)) +} +*/ + +func HandleVieEtudiante(c echo.Context) error { + return c.Render(http.StatusOK, "vie-etudiante-html", nil) +} + +func HandleVieEtudianteOrganisme(c echo.Context) error { + organisme := c.Param("organisme") + return c.String(http.StatusOK, fmt.Sprintf("Organisme: %s", organisme)) +} + +func HandleDocumentation(c echo.Context) error { + client, err := api.NewApiClientFromViper() + if err != nil { + return c.Render(http.StatusInternalServerError, "documentation-html", nil) + } + + result, err := client.Call(http.MethodGet, "/v1/bucket") + if err != nil { + return c.Render(http.StatusInternalServerError, "documentation-html", nil) + } + + var buckets map[string]string + + err = json.Unmarshal(result, &buckets) + if err != nil { + return c.Render(http.StatusInternalServerError, "documentation-html", nil) + } + + var data []models.Bucket + + for bucket, displayName := range buckets { + content, err := client.Call(http.MethodGet, fmt.Sprintf("/v1/bucket/%s", bucket)) + if err != nil { + return c.Render(http.StatusInternalServerError, "documentation-html", nil) + } + + var documents []string + + err = json.Unmarshal(content, &documents) + if err != nil { + return c.Render(http.StatusInternalServerError, "documentation-html", nil) + } + + // Ce bloc retire tous les caractères spéciaux d'une string + // N'est pas présentement activé, car les fichiers sont processed + // à la création de toute façon. + /* + reg, err := regexp.Compile("[^.a-zA-Z0-9_-]+") + if err != nil { + return c.Render(http.StatusInternalServerError, "documentation-html", nil) + } + + var documents_processed []string + + for _, document := range documents { + document_processed := reg.ReplaceAllString(document, "") + documents_processed = append(documents_processed, document_processed) + } + documents_processed := documents + */ + + data = append(data, models.Bucket{ + Name: bucket, + DisplayName: displayName, + Documents: documents, + }) + } + + sort.SliceStable(data, func(i, j int) bool { return data[i].Name < data[j].Name }) + + return c.Render(http.StatusOK, "documentation-html", data) +} + +func HandleFormulaires(c echo.Context) error { + return c.Render(http.StatusOK, "formulaires-html", nil) +} + +func HandlePublicDocumentation(c echo.Context) error { + client, err := api.NewApiClientFromViper() + if err != nil { + return c.JSON(http.StatusNotFound, map[string]string{"message": "Not Found"}) + } + + bucket := c.Param("bucket") + document := c.Param("document") + + result, err := client.Call(http.MethodGet, fmt.Sprintf("/v1/bucket/%s/%s", bucket, document)) + if err != nil { + return c.JSON(http.StatusNotFound, map[string]string{"message": "Not Found"}) + } + + // Check if result can fit inside a map containing a message + var result_map map[string]string + + err = json.Unmarshal(result, &result_map) + if err == nil { + return c.JSON(http.StatusBadRequest, result_map) + } + + return c.Blob(http.StatusOK, "application/octet-stream", result) +} + +func HandleAdmin(c echo.Context) error { + return c.Render(http.StatusOK, "admin-html", nil) +} + +func HandleAdminDocumentsUpload(c echo.Context) error { + client, err := api.NewApiClientFromViper() + if err != nil { + return c.Render(http.StatusInternalServerError, "documentation-html", nil) + } + + result, err := client.Call(http.MethodGet, "/v1/bucket") + if err != nil { + return c.Render(http.StatusInternalServerError, "documentation-html", nil) + } + + var buckets map[string]string + + err = json.Unmarshal(result, &buckets) + if err != nil { + return c.Render(http.StatusInternalServerError, "documentation-html", nil) + } + + var data struct { + Buckets []models.Bucket + Message string + } + + for bucketName, displayName := range buckets { + data.Buckets = append(data.Buckets, models.Bucket{ + Name: bucketName, + DisplayName: displayName, + }) + } + + return c.Render(http.StatusOK, "admin-upload-html", data) +} + +func HandleAdminDocumentsUploadPOST(c echo.Context) error { + var data struct { + Buckets []models.Bucket + Message string + } + + client, err := api.NewApiClientFromViper() + if err != nil { + data.Message = fmt.Sprintf("HandleAdminDocumentsUploadPOST#api.New: %s", err) + return c.Render(http.StatusInternalServerError, "admin-upload-html", data) + } + + result, err := client.Call(http.MethodGet, "/v1/bucket") + if err != nil { + data.Message = "Error during GET /v1/bucket" + return c.Render(http.StatusInternalServerError, "documentation-html", data) + } + + var buckets map[string]string + + err = json.Unmarshal(result, &buckets) + if err != nil { + return c.Render(http.StatusInternalServerError, "documentation-html", nil) + } + + for bucketName, displayName := range buckets { + data.Buckets = append(data.Buckets, models.Bucket{ + Name: bucketName, + DisplayName: displayName, + }) + } + + bucket := c.FormValue("bucket") + + document, err := c.FormFile("document") + if err != nil { + data.Message = fmt.Sprintf("HandleAdminDocumentsUploadPOST#c.FormFile: %s", err) + return c.Render(http.StatusBadRequest, "admin-upload-html", data) + } + + response, err := client.UploadDocument(bucket, document) + if err != nil { + data.Message = fmt.Sprintf("HandleAdminDocumentsUploadPOST#client.UploadDocument: %s", err) + return c.Render(http.StatusInternalServerError, "admin-upload-html", data) + } + + // Format response + var info, status string + + info = fmt.Sprintf("[%.0f] /public/documentation/%s/%s", response.Data.Size, response.Data.Bucket, response.Data.Object) + + status = response.Message + + data.Message = fmt.Sprintf("%s - %s", status, info) + + return c.Render(http.StatusOK, "admin-upload-html", data) +} From 3a602486df06076712d3792c87b2ce759ae03f1a Mon Sep 17 00:00:00 2001 From: Victor Lacasse-Beaudoin Date: Sun, 20 Aug 2023 16:21:44 -0400 Subject: [PATCH 2/2] =?UTF-8?q?Mettre=20=C3=A0=20jour=20Dockerfile=20avec?= =?UTF-8?q?=20refactor=20de=20packages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index a53152d..a0fac5f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,6 +12,8 @@ ADD cmd/ cmd/ ADD api/ api/ +ADD api_handlers/ api_handlers/ + ADD config/ config/ ADD media/ media/ @@ -20,7 +22,7 @@ ADD models/ models/ ADD templates/ templates/ -ADD serverhandlers/ serverhandlers/ +ADD web_handlers/ web_handlers/ RUN CGO_ENABLED=0 go build -a -installsuffix cgo -o agecem-org .