From 1bb73c866a45ee30afb417908b540eac03fa5dfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=20Jurmanovi=C4=87?= Date: Tue, 9 Jul 2024 23:42:26 +0200 Subject: [PATCH] init --- cmd/api/main.go | 29 ++++++++++++++++ go.mod | 20 +++++++++++ go.sum | 31 +++++++++++++++++ local/api/api.go | 21 ++++++++++++ local/api/routes.go | 34 +++++++++++++++++++ local/controller/api.go | 44 ++++++++++++++++++++++++ local/controller/controller.go | 62 ++++++++++++++++++++++++++++++++++ local/model/api.go | 5 +++ local/model/model.go | 45 ++++++++++++++++++++++++ local/service/api.go | 28 +++++++++++++++ local/service/service.go | 17 ++++++++++ local/utl/common/common.go | 56 ++++++++++++++++++++++++++++++ local/utl/configs/configs.go | 8 +++++ local/utl/server/server.go | 25 ++++++++++++++ logs.log | 0 15 files changed, 425 insertions(+) create mode 100644 cmd/api/main.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 local/api/api.go create mode 100644 local/api/routes.go create mode 100644 local/controller/api.go create mode 100644 local/controller/controller.go create mode 100644 local/model/api.go create mode 100644 local/model/model.go create mode 100644 local/service/api.go create mode 100644 local/service/service.go create mode 100644 local/utl/common/common.go create mode 100644 local/utl/configs/configs.go create mode 100644 local/utl/server/server.go create mode 100644 logs.log diff --git a/cmd/api/main.go b/cmd/api/main.go new file mode 100644 index 0000000..9f9ca9e --- /dev/null +++ b/cmd/api/main.go @@ -0,0 +1,29 @@ +package main + +import ( + "acc-server-manager/local/api" + "acc-server-manager/local/utl/server" + "log" + "os" + + "github.com/gofiber/fiber/v2" + "github.com/joho/godotenv" +) + +func main() { + godotenv.Load() + + app := fiber.New(fiber.Config{ + Immutable: true, + }) + + file, err := os.OpenFile("logs.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666) + if err != nil { + log.Print("Cannot open file logs.log") + } + log.SetOutput(file) + + api.Init(app) + + server.Start(app) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..91bd79a --- /dev/null +++ b/go.mod @@ -0,0 +1,20 @@ +module acc-server-manager + +go 1.22.3 + +require ( + github.com/andybalholm/brotli v1.0.5 // indirect + github.com/gofiber/fiber/v2 v2.52.5 // indirect + github.com/google/uuid v1.5.0 // indirect + github.com/joho/godotenv v1.5.1 // indirect + github.com/klauspost/compress v1.17.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/rivo/uniseg v0.2.0 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/valyala/fasthttp v1.51.0 // indirect + github.com/valyala/tcplisten v1.0.0 // indirect + go.uber.org/dig v1.17.1 // indirect + golang.org/x/sys v0.15.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..8125446 --- /dev/null +++ b/go.sum @@ -0,0 +1,31 @@ +github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= +github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/gofiber/fiber/v2 v2.52.5 h1:tWoP1MJQjGEe4GB5TUGOi7P2E0ZMMRx5ZTG4rT+yGMo= +github.com/gofiber/fiber/v2 v2.52.5/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ= +github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= +github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM= +github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA= +github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g= +github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= +github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= +go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= +go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= diff --git a/local/api/api.go b/local/api/api.go new file mode 100644 index 0000000..5d914eb --- /dev/null +++ b/local/api/api.go @@ -0,0 +1,21 @@ +package api + +import ( + "github.com/gofiber/fiber/v2" +) + +/* +Init + +Initializes Web API Routes. + + Args: + *fiber.App: Fiber Application. +*/ +func Init(app *fiber.App) { + Routes(app) +} + +type API struct { + Api string `json:"api"` +} diff --git a/local/api/routes.go b/local/api/routes.go new file mode 100644 index 0000000..c630bf8 --- /dev/null +++ b/local/api/routes.go @@ -0,0 +1,34 @@ +package api + +import ( + "acc-server-manager/local/controller" + "acc-server-manager/local/utl/common" + "acc-server-manager/local/utl/configs" + + "github.com/gofiber/fiber/v2" + "go.uber.org/dig" +) + +/* +Routes + +Initializes web api controllers and its corresponding routes. + + Args: + *fiber.App: Fiber Application +*/ +func Routes(app *fiber.App) { + c := dig.New() + groups := app.Group(configs.Prefix) + + apiGroup := groups.Group("api") + routeGroups := &common.RouteGroups{ + Api: apiGroup, + } + + c.Provide(func() *common.RouteGroups { + return routeGroups + }) + + controller.InitializeControllers(c) +} diff --git a/local/controller/api.go b/local/controller/api.go new file mode 100644 index 0000000..a9dfd56 --- /dev/null +++ b/local/controller/api.go @@ -0,0 +1,44 @@ +package controller + +import ( + "acc-server-manager/local/service" + "acc-server-manager/local/utl/common" + + "github.com/gofiber/fiber/v2" +) + +type ApiController struct { + service *service.ApiService +} + +/* +NewApiController + +Initializes ApiController. + + Args: + *services.ApiService: API service + *Fiber.RouterGroup: Fiber Router Group + Returns: + *ApiController: Controller for "api" interactions +*/ +func NewApiController(as *service.ApiService, routeGroups *common.RouteGroups) *ApiController { + ac := &ApiController{ + service: as, + } + + routeGroups.Api.Get("", ac.getFirst) + + return ac +} + +/* +getFirst + Args: + *fiber.Ctx: Fiber Application Context +*/ +// ROUTE (GET /api). +func (ac *ApiController) getFirst(c *fiber.Ctx) error { + apiModel := ac.service.GetFirst(c) + return c.SendString(apiModel) +} diff --git a/local/controller/controller.go b/local/controller/controller.go new file mode 100644 index 0000000..2702012 --- /dev/null +++ b/local/controller/controller.go @@ -0,0 +1,62 @@ +package controller + +import ( + "acc-server-manager/local/model" + "acc-server-manager/local/service" + "acc-server-manager/local/utl/common" + "fmt" + "strconv" + "strings" + + "github.com/gofiber/fiber/v2" + "go.uber.org/dig" +) + +/* +InitializeControllers + +Initializes Dependency Injection modules and registers controllers + + Args: + *dig.Container: Dig Container +*/ +func InitializeControllers(c *dig.Container) { + service.InitializeServices(c) + + c.Invoke(NewApiController) + +} + +/* +FilteredResponse + +Gets query parameters and populates FilteredResponse model. + + Args: + *gin.Context: Gin Application Context + Returns: + *model.FilteredResponse: Filtered response +*/ +func FilteredResponse(c *fiber.Ctx) *model.FilteredResponse { + filtered := new(model.FilteredResponse) + page := c.Params("page") + rpp := c.Params("rpp") + sortBy := c.Params("sortBy") + + dividers := [5]string{"|", " ", ".", "/", ","} + + for _, div := range dividers { + sortArr := strings.Split(sortBy, div) + + if len(sortArr) >= 2 { + sortBy = fmt.Sprintf("%s %s", common.ToSnakeCase(sortArr[0]), strings.ToUpper(sortArr[1])) + } + } + + filtered.Embed = c.Params("embed") + filtered.Page, _ = strconv.Atoi(page) + filtered.Rpp, _ = strconv.Atoi(rpp) + filtered.SortBy = sortBy + + return filtered +} diff --git a/local/model/api.go b/local/model/api.go new file mode 100644 index 0000000..8ce20a3 --- /dev/null +++ b/local/model/api.go @@ -0,0 +1,5 @@ +package model + +type ApiModel struct { + Api string `json:"api"` +} diff --git a/local/model/model.go b/local/model/model.go new file mode 100644 index 0000000..86e599f --- /dev/null +++ b/local/model/model.go @@ -0,0 +1,45 @@ +package model + +import ( + "time" + + "github.com/gofiber/fiber/v2" + "github.com/google/uuid" +) + +type FilteredResponse struct { + Items interface{} `json:"items"` + Params +} + +type ResponseFunc func(*fiber.Ctx) *[]interface{} + +type MessageResponse struct { + Message string `json:"message"` +} + +type Params struct { + SortBy string `json:"sortBy"` + Embed string `json:"embed"` + Page int `json:"page"` + Rpp int `json:"rpp"` + TotalRecords int `json:"totalRecords"` +} + +type BaseModel struct { + Id string `json:"id"` + DateCreated time.Time `json:"dateCreated"` + DateUpdated time.Time `json:"dateUpdated"` +} + +/* +Init + +Initializes base model with DateCreated, DateUpdated, and Id values. +*/ +func (cm *BaseModel) Init() { + date := time.Now() + cm.Id = uuid.NewString() + cm.DateCreated = date + cm.DateUpdated = date +} diff --git a/local/service/api.go b/local/service/api.go new file mode 100644 index 0000000..2153a82 --- /dev/null +++ b/local/service/api.go @@ -0,0 +1,28 @@ +package service + +import ( + "acc-server-manager/local/utl/configs" + + "github.com/gofiber/fiber/v2" +) + +type ApiService struct { +} + +func NewApiService() *ApiService { + return &ApiService{} +} + +/* +GetFirst + +Gets first row from API table. + + Args: + context.Context: Application context + Returns: + string: Application version +*/ +func (as ApiService) GetFirst(ctx *fiber.Ctx) string { + return configs.Version +} diff --git a/local/service/service.go b/local/service/service.go new file mode 100644 index 0000000..10f2da1 --- /dev/null +++ b/local/service/service.go @@ -0,0 +1,17 @@ +package service + +import ( + "go.uber.org/dig" +) + +/* +InitializeServices + +Initializes Dependency Injection modules for services + + Args: + *dig.Container: Dig Container +*/ +func InitializeServices(c *dig.Container) { + c.Provide(NewApiService) +} diff --git a/local/utl/common/common.go b/local/utl/common/common.go new file mode 100644 index 0000000..f972b9d --- /dev/null +++ b/local/utl/common/common.go @@ -0,0 +1,56 @@ +package common + +import ( + "log" + "net" + "os" + "regexp" + "strings" + + "github.com/gofiber/fiber/v2" +) + +type RouteGroups struct { + Api fiber.Router +} + +func CheckError(err error) { + if err != nil { + log.Printf("Error occured. %v", err) + } +} + +var matchFirstCap = regexp.MustCompile("(.)([A-Z][a-z]+)") +var matchAllCap = regexp.MustCompile("([a-z0-9])([A-Z])") + +func ToSnakeCase(str string) string { + snake := matchFirstCap.ReplaceAllString(str, "${1}_${2}") + snake = matchAllCap.ReplaceAllString(snake, "${1}_${2}") + return strings.ToLower(snake) +} + +func GetIP() string { + addrs, err := net.InterfaceAddrs() + if err != nil { + os.Stderr.WriteString("Oops: " + err.Error() + "\n") + os.Exit(1) + } + + for _, a := range addrs { + if ipnet, ok := a.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { + if ipnet.IP.To4() != nil { + return ipnet.IP.String() + } + } + } + return "" +} + +func Find[T any](lst *[]T, callback func(item *T) bool) *T { + for _, item := range *lst { + if callback(&item) { + return &item + } + } + return nil +} diff --git a/local/utl/configs/configs.go b/local/utl/configs/configs.go new file mode 100644 index 0000000..6f21a63 --- /dev/null +++ b/local/utl/configs/configs.go @@ -0,0 +1,8 @@ +package configs + +const ( + Version = "0.0.1" + Prefix = "v1" + Secret = "Donde4sta" + SecretCode = "brasno" +) diff --git a/local/utl/server/server.go b/local/utl/server/server.go new file mode 100644 index 0000000..55706c0 --- /dev/null +++ b/local/utl/server/server.go @@ -0,0 +1,25 @@ +package server + +import ( + "acc-server-manager/local/utl/common" + "fmt" + "os" + + "github.com/gofiber/fiber/v2" +) + +func Start(r *fiber.App) *fiber.App { + r.Get("/ping", func(c *fiber.Ctx) error { + return c.SendString("pong") + }) + port := os.Getenv("PORT") + if port == "" { + port = "4000" + } + err := r.Listen(":" + port) + if err != nil { + msg := fmt.Sprintf("Running on %s:%s", common.GetIP(), port) + println(msg) + } + return r +} diff --git a/logs.log b/logs.log new file mode 100644 index 0000000..e69de29