From f5a22be60c0c7652259ac3b71e234923ef4e98ca Mon Sep 17 00:00:00 2001 From: DeveloperDurp Date: Sat, 8 Apr 2023 10:19:32 -0500 Subject: [PATCH] updates --- .gitignore | 3 +- controller/accounts.go | 191 ----------------------------------------- controller/admin.go | 42 --------- controller/bottles.go | 61 ------------- controller/examples.go | 160 ---------------------------------- controller/openai.go | 71 +++++++++++++-- go.mod | 1 + go.sum | 2 + main.go | 43 +--------- 9 files changed, 68 insertions(+), 506 deletions(-) delete mode 100644 controller/accounts.go delete mode 100644 controller/admin.go delete mode 100644 controller/bottles.go delete mode 100644 controller/examples.go diff --git a/.gitignore b/.gitignore index f8acb29..83c5bc4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ __debug_bin docs -.vscode \ No newline at end of file +.vscode +.env diff --git a/controller/accounts.go b/controller/accounts.go deleted file mode 100644 index 2815e02..0000000 --- a/controller/accounts.go +++ /dev/null @@ -1,191 +0,0 @@ -package controller - -import ( - "fmt" - "net/http" - "strconv" - - "github.com/gin-gonic/gin" - "github.com/swaggo/swag/example/celler/httputil" - "github.com/swaggo/swag/example/celler/model" -) - -// ShowAccount godoc -// -// @Summary Show an account -// @Description get string by ID -// @Tags accounts -// @Accept json -// @Produce json -// @Param id path int true "Account ID" -// @Success 200 {object} model.Account -// @Failure 400 {object} httputil.HTTPError -// @Failure 404 {object} httputil.HTTPError -// @Failure 500 {object} httputil.HTTPError -// @Router /accounts/{id} [get] -func (c *Controller) ShowAccount(ctx *gin.Context) { - id := ctx.Param("id") - aid, err := strconv.Atoi(id) - if err != nil { - httputil.NewError(ctx, http.StatusBadRequest, err) - return - } - account, err := model.AccountOne(aid) - if err != nil { - httputil.NewError(ctx, http.StatusNotFound, err) - return - } - ctx.JSON(http.StatusOK, account) -} - -// ListAccounts godoc -// -// @Summary List accounts -// @Description get accounts -// @Tags accounts -// @Accept json -// @Produce json -// @Param q query string false "name search by q" Format(email) -// @Success 200 {array} model.Account -// @Failure 400 {object} httputil.HTTPError -// @Failure 404 {object} httputil.HTTPError -// @Failure 500 {object} httputil.HTTPError -// @Router /accounts [get] -func (c *Controller) ListAccounts(ctx *gin.Context) { - q := ctx.Request.URL.Query().Get("q") - accounts, err := model.AccountsAll(q) - if err != nil { - httputil.NewError(ctx, http.StatusNotFound, err) - return - } - ctx.JSON(http.StatusOK, accounts) -} - -// AddAccount godoc -// -// @Summary Add an account -// @Description add by json account -// @Tags accounts -// @Accept json -// @Produce json -// @Param account body model.AddAccount true "Add account" -// @Success 200 {object} model.Account -// @Failure 400 {object} httputil.HTTPError -// @Failure 404 {object} httputil.HTTPError -// @Failure 500 {object} httputil.HTTPError -// @Router /accounts [post] -func (c *Controller) AddAccount(ctx *gin.Context) { - var addAccount model.AddAccount - if err := ctx.ShouldBindJSON(&addAccount); err != nil { - httputil.NewError(ctx, http.StatusBadRequest, err) - return - } - if err := addAccount.Validation(); err != nil { - httputil.NewError(ctx, http.StatusBadRequest, err) - return - } - account := model.Account{ - Name: addAccount.Name, - } - lastID, err := account.Insert() - if err != nil { - httputil.NewError(ctx, http.StatusBadRequest, err) - return - } - account.ID = lastID - ctx.JSON(http.StatusOK, account) -} - -// UpdateAccount godoc -// -// @Summary Update an account -// @Description Update by json account -// @Tags accounts -// @Accept json -// @Produce json -// @Param id path int true "Account ID" -// @Param account body model.UpdateAccount true "Update account" -// @Success 200 {object} model.Account -// @Failure 400 {object} httputil.HTTPError -// @Failure 404 {object} httputil.HTTPError -// @Failure 500 {object} httputil.HTTPError -// @Router /accounts/{id} [patch] -func (c *Controller) UpdateAccount(ctx *gin.Context) { - id := ctx.Param("id") - aid, err := strconv.Atoi(id) - if err != nil { - httputil.NewError(ctx, http.StatusBadRequest, err) - return - } - var updateAccount model.UpdateAccount - if err := ctx.ShouldBindJSON(&updateAccount); err != nil { - httputil.NewError(ctx, http.StatusBadRequest, err) - return - } - account := model.Account{ - ID: aid, - Name: updateAccount.Name, - } - err = account.Update() - if err != nil { - httputil.NewError(ctx, http.StatusNotFound, err) - return - } - ctx.JSON(http.StatusOK, account) -} - -// DeleteAccount godoc -// -// @Summary Delete an account -// @Description Delete by account ID -// @Tags accounts -// @Accept json -// @Produce json -// @Param id path int true "Account ID" Format(int64) -// @Success 204 {object} model.Account -// @Failure 400 {object} httputil.HTTPError -// @Failure 404 {object} httputil.HTTPError -// @Failure 500 {object} httputil.HTTPError -// @Router /accounts/{id} [delete] -func (c *Controller) DeleteAccount(ctx *gin.Context) { - id := ctx.Param("id") - aid, err := strconv.Atoi(id) - if err != nil { - httputil.NewError(ctx, http.StatusBadRequest, err) - return - } - err = model.Delete(aid) - if err != nil { - httputil.NewError(ctx, http.StatusNotFound, err) - return - } - ctx.JSON(http.StatusNoContent, gin.H{}) -} - -// UploadAccountImage godoc -// -// @Summary Upload account image -// @Description Upload file -// @Tags accounts -// @Accept multipart/form-data -// @Produce json -// @Param id path int true "Account ID" -// @Param file formData file true "account image" -// @Success 200 {object} controller.Message -// @Failure 400 {object} httputil.HTTPError -// @Failure 404 {object} httputil.HTTPError -// @Failure 500 {object} httputil.HTTPError -// @Router /accounts/{id}/images [post] -func (c *Controller) UploadAccountImage(ctx *gin.Context) { - id, err := strconv.Atoi(ctx.Param("id")) - if err != nil { - httputil.NewError(ctx, http.StatusBadRequest, err) - return - } - file, err := ctx.FormFile("file") - if err != nil { - httputil.NewError(ctx, http.StatusBadRequest, err) - return - } - ctx.JSON(http.StatusOK, Message{Message: fmt.Sprintf("upload complete userID=%d filename=%s", id, file.Filename)}) -} diff --git a/controller/admin.go b/controller/admin.go deleted file mode 100644 index b288d34..0000000 --- a/controller/admin.go +++ /dev/null @@ -1,42 +0,0 @@ -package controller - -import ( - "errors" - "fmt" - "net/http" - - "github.com/gin-gonic/gin" - "github.com/swaggo/swag/example/celler/httputil" - "github.com/swaggo/swag/example/celler/model" -) - -// Auth godoc -// -// @Summary Auth admin -// @Description get admin info -// @Tags accounts,admin -// @Accept json -// @Produce json -// @Success 200 {object} model.Admin -// @Failure 400 {object} httputil.HTTPError -// @Failure 401 {object} httputil.HTTPError -// @Failure 404 {object} httputil.HTTPError -// @Failure 500 {object} httputil.HTTPError -// @Security ApiKeyAuth -// @Router /admin/auth [post] -func (c *Controller) Auth(ctx *gin.Context) { - authHeader := ctx.GetHeader("Authorization") - if len(authHeader) == 0 { - httputil.NewError(ctx, http.StatusBadRequest, errors.New("please set Header Authorization")) - return - } - if authHeader != "admin" { - httputil.NewError(ctx, http.StatusUnauthorized, fmt.Errorf("this user isn't authorized to operation key=%s expected=admin", authHeader)) - return - } - admin := model.Admin{ - ID: 1, - Name: "admin", - } - ctx.JSON(http.StatusOK, admin) -} diff --git a/controller/bottles.go b/controller/bottles.go deleted file mode 100644 index 925414d..0000000 --- a/controller/bottles.go +++ /dev/null @@ -1,61 +0,0 @@ -package controller - -import ( - "net/http" - "strconv" - - "github.com/gin-gonic/gin" - - "github.com/swaggo/swag/example/celler/httputil" - "github.com/swaggo/swag/example/celler/model" -) - -// ShowBottle godoc -// -// @Summary Show a bottle -// @Description get string by ID -// @ID get-string-by-int -// @Tags bottles -// @Accept json -// @Produce json -// @Param id path int true "Bottle ID" -// @Success 200 {object} model.Bottle -// @Failure 400 {object} httputil.HTTPError -// @Failure 404 {object} httputil.HTTPError -// @Failure 500 {object} httputil.HTTPError -// @Router /bottles/{id} [get] -func (c *Controller) ShowBottle(ctx *gin.Context) { - id := ctx.Param("id") - bid, err := strconv.Atoi(id) - if err != nil { - httputil.NewError(ctx, http.StatusBadRequest, err) - return - } - bottle, err := model.BottleOne(bid) - if err != nil { - httputil.NewError(ctx, http.StatusNotFound, err) - return - } - ctx.JSON(http.StatusOK, bottle) -} - -// ListBottles godoc -// -// @Summary List bottles -// @Description get bottles -// @Tags bottles -// @Accept json -// @Produce json -// @Success 200 {array} model.Bottle -// @Failure 400 {object} httputil.HTTPError -// @Failure 404 {object} httputil.HTTPError -// @Failure 500 {object} httputil.HTTPError -// @Router /bottles [get] -func (c *Controller) ListBottles(ctx *gin.Context) { - bottles, err := model.BottlesAll() - if err != nil { - httputil.NewError(ctx, http.StatusNotFound, err) - return - } - ctx.JSON(http.StatusOK, bottles) -} diff --git a/controller/examples.go b/controller/examples.go deleted file mode 100644 index e27a4c3..0000000 --- a/controller/examples.go +++ /dev/null @@ -1,160 +0,0 @@ -package controller - -import ( - "fmt" - "net/http" - "strconv" - - "github.com/gin-gonic/gin" - "github.com/swaggo/swag/example/celler/httputil" -) - -// PingExample godoc -// -// @Summary ping example -// @Description do ping -// @Tags example -// @Accept json -// @Produce plain -// @Success 200 {string} string "pong" -// @Failure 400 {string} string "ok" -// @Failure 404 {string} string "ok" -// @Failure 500 {string} string "ok" -// @Router /examples/ping [get] -func (c *Controller) PingExample(ctx *gin.Context) { - ctx.String(http.StatusOK, "pong") -} - -// CalcExample godoc -// -// @Summary calc example -// @Description plus -// @Tags example -// @Accept json -// @Produce plain -// @Param val1 query int true "used for calc" -// @Param val2 query int true "used for calc" -// @Success 200 {integer} string "answer" -// @Failure 400 {string} string "ok" -// @Failure 404 {string} string "ok" -// @Failure 500 {string} string "ok" -// @Router /examples/calc [get] -func (c *Controller) CalcExample(ctx *gin.Context) { - val1, err := strconv.Atoi(ctx.Query("val1")) - if err != nil { - httputil.NewError(ctx, http.StatusBadRequest, err) - return - } - val2, err := strconv.Atoi(ctx.Query("val2")) - if err != nil { - httputil.NewError(ctx, http.StatusBadRequest, err) - return - } - ans := val1 + val2 - ctx.String(http.StatusOK, "%d", ans) -} - -// PathParamsExample godoc -// -// @Summary path params example -// @Description path params -// @Tags example -// @Accept json -// @Produce plain -// @Param group_id path int true "Group ID" -// @Param account_id path int true "Account ID" -// @Success 200 {string} string "answer" -// @Failure 400 {string} string "ok" -// @Failure 404 {string} string "ok" -// @Failure 500 {string} string "ok" -// @Router /examples/groups/{group_id}/accounts/{account_id} [get] -func (c *Controller) PathParamsExample(ctx *gin.Context) { - groupID, err := strconv.Atoi(ctx.Param("group_id")) - if err != nil { - httputil.NewError(ctx, http.StatusBadRequest, err) - return - } - accountID, err := strconv.Atoi(ctx.Param("account_id")) - if err != nil { - httputil.NewError(ctx, http.StatusBadRequest, err) - return - } - ctx.String(http.StatusOK, "group_id=%d account_id=%d", groupID, accountID) -} - -// HeaderExample godoc -// -// @Summary custome header example -// @Description custome header -// @Tags example -// @Accept json -// @Produce plain -// @Param Authorization header string true "Authentication header" -// @Success 200 {string} string "answer" -// @Failure 400 {string} string "ok" -// @Failure 404 {string} string "ok" -// @Failure 500 {string} string "ok" -// @Router /examples/header [get] -func (c *Controller) HeaderExample(ctx *gin.Context) { - ctx.String(http.StatusOK, ctx.GetHeader("Authorization")) -} - -// SecuritiesExample godoc -// -// @Summary custome header example -// @Description custome header -// @Tags example -// @Accept json -// @Produce json -// @Param Authorization header string true "Authentication header" -// @Success 200 {string} string "answer" -// @Failure 400 {string} string "ok" -// @Failure 404 {string} string "ok" -// @Failure 500 {string} string "ok" -// @Security ApiKeyAuth -// @Security OAuth2Implicit[admin, write] -// @Router /examples/securities [get] -func (c *Controller) SecuritiesExample(ctx *gin.Context) { -} - -// AttributeExample godoc -// -// @Summary attribute example -// @Description attribute -// @Tags example -// @Accept json -// @Produce plain -// @Param enumstring query string false "string enums" Enums(A, B, C) -// @Param enumint query int false "int enums" Enums(1, 2, 3) -// @Param enumnumber query number false "int enums" Enums(1.1, 1.2, 1.3) -// @Param string query string false "string valid" minlength(5) maxlength(10) -// @Param int query int false "int valid" minimum(1) maximum(10) -// @Param default query string false "string default" default(A) -// @Success 200 {string} string "answer" -// @Failure 400 {string} string "ok" -// @Failure 404 {string} string "ok" -// @Failure 500 {string} string "ok" -// @Router /examples/attribute [get] -func (c *Controller) AttributeExample(ctx *gin.Context) { - ctx.String(http.StatusOK, fmt.Sprintf("enumstring=%s enumint=%s enumnumber=%s string=%s int=%s default=%s", - ctx.Query("enumstring"), - ctx.Query("enumint"), - ctx.Query("enumnumber"), - ctx.Query("string"), - ctx.Query("int"), - ctx.Query("default"), - )) -} - -// PostExample godoc -// -// @Summary post request example -// @Description post request example -// @Accept json -// @Produce plain -// @Param message body model.Account true "Account Info" -// @Success 200 {string} string "success" -// @Failure 500 {string} string "fail" -// @Router /examples/post [post] -func (c *Controller) PostExample(ctx *gin.Context) { -} diff --git a/controller/openai.go b/controller/openai.go index 0036b01..71c1823 100644 --- a/controller/openai.go +++ b/controller/openai.go @@ -2,30 +2,83 @@ package controller import ( "context" + "fmt" "net/http" + "os" "github.com/gin-gonic/gin" + "github.com/joho/godotenv" openai "github.com/sashabaranov/go-openai" ) -var client = openai.NewClient("") +var ( + // Declare global variables + apiKey string + + config *configStruct +) + +type configStruct struct { + apiKey string `json : "API_KEY"` +} + +func init() { + // Load values for global variables from environment variables + err := godotenv.Load(".env") + + if err != nil { + fmt.Println(err.Error()) + //return err + } + apiKey = os.Getenv("API_KEY") + +} // GeneralOpenAI godoc // -// @Summary ping example -// @Description do ping +// @Summary Gerneral ChatGPT +// @Description Ask ChatGPT a general question // @Tags openai // @Accept json // @Produce plain // @Param message query string true "Ask ChatGPT a general question" // @Success 200 {string} string "response" -// @Failure 400 {string} string "ok" -// @Failure 404 {string} string "ok" -// @Failure 500 {string} string "ok" -// @Router /openai/GeneralOpenAI [get] +// @Router /openai/general [get] func (c *Controller) GeneralOpenAI(ctx *gin.Context) { message := ctx.Query("message") + result, err := createChatCompletion(message) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, err) + } + + ctx.String(http.StatusOK, result) +} + +// TravelAgentOpenAI godoc +// +// @Summary Travel Agent ChatGPT +// @Description Ask ChatGPT for suggestions as if it was a travel agent +// @Tags openai +// @Accept json +// @Produce plain +// @Param message query string true "Ask ChatGPT for suggestions as a travel agent" +// @Success 200 {string} string "response" +// @Router /openai/travelagent [get] +func (c *Controller) TravelAgentOpenAI(ctx *gin.Context) { + message := "want you to act as a travel guide. I will give you my location and you will give me suggestions " + ctx.Query("message") + + result, err := createChatCompletion(message) + if err != nil { + ctx.AbortWithError(http.StatusInternalServerError, err) + } + + ctx.String(http.StatusOK, result) +} + +func createChatCompletion(message string) (string, error) { + + var client = openai.NewClient(apiKey) resp, err := client.CreateChatCompletion( context.Background(), openai.ChatCompletionRequest{ @@ -39,8 +92,8 @@ func (c *Controller) GeneralOpenAI(ctx *gin.Context) { }, ) if err != nil { - ctx.AbortWithError(http.StatusInternalServerError, err) + return "", err } - ctx.String(http.StatusOK, resp.Choices[0].Message.Content) + return resp.Choices[0].Message.Content, nil } diff --git a/go.mod b/go.mod index e839cb2..42109e7 100644 --- a/go.mod +++ b/go.mod @@ -27,6 +27,7 @@ require ( github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.11.2 // indirect github.com/goccy/go-json v0.10.0 // indirect + github.com/joho/godotenv v1.5.1 github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.0.9 // indirect diff --git a/go.sum b/go.sum index 9ef19bb..abd86b1 100644 --- a/go.sum +++ b/go.sum @@ -44,6 +44,8 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= diff --git a/main.go b/main.go index 9008dac..5100110 100644 --- a/main.go +++ b/main.go @@ -2,10 +2,7 @@ package main import ( "errors" - "fmt" "net/http" - "os" - "os/exec" "github.com/DeveloperDurp/DurpAPI/controller" _ "github.com/DeveloperDurp/DurpAPI/docs" @@ -67,37 +64,10 @@ func main() { v1 := r.Group("/api/v1") { - accounts := v1.Group("/accounts") - { - accounts.GET(":id", c.ShowAccount) - accounts.GET("", c.ListAccounts) - accounts.POST("", c.AddAccount) - accounts.DELETE(":id", c.DeleteAccount) - accounts.PATCH(":id", c.UpdateAccount) - accounts.POST(":id/images", c.UploadAccountImage) - } - bottles := v1.Group("/bottles") - { - bottles.GET(":id", c.ShowBottle) - bottles.GET("", c.ListBottles) - } - admin := v1.Group("/admin") - { - admin.Use(auth()) - admin.POST("/auth", c.Auth) - } - examples := v1.Group("/examples") - { - examples.GET("ping", c.PingExample) - examples.GET("calc", c.CalcExample) - examples.GET("groups/:group_id/accounts/:account_id", c.PathParamsExample) - examples.GET("header", c.HeaderExample) - examples.GET("securities", c.SecuritiesExample) - examples.GET("attribute", c.AttributeExample) - } openai := v1.Group("/openai") { openai.GET("general", c.GeneralOpenAI) + openai.GET("travelagent", c.TravelAgentOpenAI) } } r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) @@ -113,14 +83,3 @@ func auth() gin.HandlerFunc { c.Next() } } - -func init() { - fmt.Println("Running swag init...") - cmd := exec.Command("swag", "init") - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - if err := cmd.Run(); err != nil { - fmt.Println("Error running swag init:", err) - os.Exit(1) - } -}