From 071e598f1f7eb4c158d36e1ae511cc4500267ed9 Mon Sep 17 00:00:00 2001 From: rspk2207 <83638002+rspk2207@users.noreply.github.com> Date: Fri, 20 Jan 2023 21:59:48 +0530 Subject: [PATCH 01/21] Add files via upload --- helpers/resource.go | 83 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 helpers/resource.go diff --git a/helpers/resource.go b/helpers/resource.go new file mode 100644 index 0000000..0fcedd9 --- /dev/null +++ b/helpers/resource.go @@ -0,0 +1,83 @@ +package helpers + +import ( + "log" + "mime/multipart" + + "github.com/ecea-nitt/ecea-server/models" + "github.com/ecea-nitt/ecea-server/repositories" + "github.com/ecea-nitt/ecea-server/utils" +) + +func FetchSubjectID(channel chan int, studyMaterialDetails models.StudyMaterialRequest, id int, repo repositories.StudyMaterialRepository) { + subID, err := repo.GetSubjectID(studyMaterialDetails.SubjectCode) + if err != nil { + subID, err = repo.CreateSubjectAndReturnID(studyMaterialDetails, uint(id)) + if err != nil { + log.Println(err) + channel <- -1 + return + } + channel <- int(subID) + return + } + channel <- int(subID) + +} + +func FetchSubjectCategoryID(channel chan int, subjectCategory string, repo repositories.StudyMaterialRepository) { + id, err := repo.GetSubjectCategoryID(subjectCategory) + if err != nil { + log.Println("hehehaha") + channel <- -1 + return + } + channel <- int(id) + +} + +func UploadFileAndFetchAssetID(channel chan int, file *multipart.FileHeader, repo repositories.StudyMaterialRepository) { + + fileName, err := utils.UploadDocument(file) + if err != nil { + log.Println(err) + channel <- -1 + return + } + id, err := repo.InsertAsset(fileName) + if err != nil { + log.Println(err) + channel <- -1 + return + } + channel <- int(id) +} + +func UpdateFileAndFetchAssetID(dbID uint, dbName string, document *multipart.FileHeader, repo repositories.StudyMaterialRepository) int { + + if dbName == document.Filename { + return int(dbID) + } + + err := utils.DeleteDocument(dbName) + + if err != nil { + log.Println(err) + return -1 + } + + fileName, err := utils.UploadDocument(document) + if err != nil { + log.Println(err) + return -1 + } + + err = repo.UpdateAsset(dbID, fileName) + + if err != nil { + log.Println(err) + return -1 + } + + return int(dbID) +} From e88645c016c1bf20c63e1d8b5b0805cc76aac88c Mon Sep 17 00:00:00 2001 From: rspk2207 <83638002+rspk2207@users.noreply.github.com> Date: Fri, 20 Jan 2023 22:26:48 +0530 Subject: [PATCH 02/21] Add files via upload --- config/database.go | 3 + controllers/app_controller.go | 14 +- controllers/resource_controller.go | 226 +++++++++++++++++++++++++++++ controllers/team_controller.go | 2 + 4 files changed, 241 insertions(+), 4 deletions(-) create mode 100644 controllers/resource_controller.go diff --git a/config/database.go b/config/database.go index bb5a8dd..ca7536b 100644 --- a/config/database.go +++ b/config/database.go @@ -47,6 +47,9 @@ func MigrateDB() { &schemas.Team{}, &schemas.Role{}, &schemas.Member{}, + &schemas.Subject{}, + &schemas.StudyMaterial{}, + &schemas.SubjectCategory{}, } { if err := db.AutoMigrate(&schema); err != nil { panic(err) diff --git a/controllers/app_controller.go b/controllers/app_controller.go index 2f99e31..312bce9 100644 --- a/controllers/app_controller.go +++ b/controllers/app_controller.go @@ -8,9 +8,10 @@ import ( ) type AppController struct { - User interface{ UserController } - Team interface{ TeamController } - Seed interface{ SeedController } + User interface{ UserController } + Team interface{ TeamController } + Seed interface{ SeedController } + StudyMaterial interface{ StudyMaterialController } } type seedController struct { @@ -41,6 +42,11 @@ func (s *seedController) SeedDB() error { log.Panic(err) return err } - log.Println(color.GreenString("Seeded Successfully")) + err = s.seed.StudyMaterialSeeder() + if err != nil { + log.Panic(err) + return err + } + log.Println(color.GreenString(" Seeded Successfully")) return nil } diff --git a/controllers/resource_controller.go b/controllers/resource_controller.go new file mode 100644 index 0000000..b09c459 --- /dev/null +++ b/controllers/resource_controller.go @@ -0,0 +1,226 @@ +package controllers + +import ( + "log" + "net/http" + + "github.com/ecea-nitt/ecea-server/middlewares" + "github.com/ecea-nitt/ecea-server/models" + "github.com/ecea-nitt/ecea-server/services" + "github.com/fatih/color" + "github.com/labstack/echo/v4" +) + +type studyMaterialController struct { + rs services.StudyMaterialService +} + +type StudyMaterialController interface { + AddStudyMaterial(c echo.Context) error + GetCategoryStudyMaterials(c echo.Context) error + GetStudyMaterial(c echo.Context) error + UpdateStudyMaterialSubject(c echo.Context) error + UpdateStudyMaterialURL(c echo.Context) error + DeleteStudyMaterial(c echo.Context) error +} + +func NewStudyMaterialController(rs services.StudyMaterialService) StudyMaterialController { + return &studyMaterialController{rs} +} + +// AddStudyMaterial godoc +// +// @Summary Add a study material +// @Description Creates a new study material and adds to Database +// @Tags StudyMaterial +// @Accept multipart/form-data +// @Produce json +// @Param name formData string true "Enter material name" +// @Param subject formData string true "Enter subject name" +// @Param code formData string true "Enter subject code" +// @Param category formData models.SubjectCategory true "Choose a category" +// @Param document formData file true "Upload Document" +// @Success 200 {object} string +// @Failure 400 {object} models.Error +// +// @Security ApiKeyAuth +// @Router /v1/studymaterial/add [post] +func (rc *studyMaterialController) AddStudyMaterial(c echo.Context) error { + request := new(models.StudyMaterialRequest) + if err := c.Bind(request); err != nil { + log.Println(err) + return err + } + file, err := c.FormFile("document") + if err != nil { + log.Println(err) + return err + } + log.Println(request) + err = rc.rs.CreateNewStudyMaterial(*request, file) + if err != nil { + log.Println(err) + return middlewares.Responder(c, http.StatusConflict, "Conflict") + } + return middlewares.Responder(c, http.StatusOK, "Success") +} + +// GetStudyMaterial godoc +// +// @Summary Get a study material +// @Description Fetches a study material and removes form database +// @Tags StudyMaterial +// @Accept json +// @Produce json +// @Param name path string true "Get study material" +// @Success 200 {object} models.StudyMaterials +// @Failure 400 {object} models.Error +// +// @Security ApiKeyAuth +// @Router /v1/studymaterial/get/{name} [get] +func (rc *studyMaterialController) GetStudyMaterial(c echo.Context) error { + rname := c.Param("name") + res, err := rc.rs.GetStudyMaterial(rname) + if err != nil { + log.Println(color.RedString(err.Error())) + return middlewares.Responder(c, http.StatusConflict, "Error Occurred") + } + + return middlewares.Responder(c, http.StatusOK, &res) +} + +// GetCategoryStudyMaterials godoc +// +// @Summary Get study materials from a category +// @Description Fetches all study materials belonging to a category from Database +// @Tags StudyMaterial +// @Accept json +// @Produce json +// @Param category path models.SubjectCategory true "Get study material from category" +// @Success 200 {object} []models.StudyMaterials +// @Failure 400 {object} models.Error +// +// @Security ApiKeyAuth +// @Router /v1/studymaterial/getcat/{category} [get] +func (rc *studyMaterialController) GetCategoryStudyMaterials(c echo.Context) error { + /* + request := new(models.StudyMaterialRequest) + if err := c.Bind(request); err != nil { + return err + } + */ + res, err := rc.rs.GetCategoryStudyMaterials(c.Param("category")) + log.Println(c.Param("category")) + if err != nil { + log.Println(color.RedString(err.Error())) + return middlewares.Responder(c, http.StatusConflict, "Conflict") + } + return middlewares.Responder(c, http.StatusOK, res) +} + +// UpdateStudyMaterialSubject godoc +// +// @Summary Updates a studymaterial's subject name +// @Description Updates a subject name and updates to Database +// @Tags StudyMaterial +// @Accept multipart/form-data +// @Produce json +// @Param subject formData string true "Edit name" +// @Param subjectCode formData string true "Enter subject code" +// @Success 200 {object} string +// @Failure 400 {object} models.Error +// +// @Security ApiKeyAuth +// @Router /v1/studymaterial/edit/subject [put] +func (rc *studyMaterialController) UpdateStudyMaterialSubject(c echo.Context) error { + + request := new(models.StudyMaterialRequest) + if err := c.Bind(request); err != nil { + log.Println(err) + return middlewares.Responder(c, http.StatusBadRequest, "Bad Request") + } + /* + subject := c.Param("subject") + subjectCode := c.Param("subjectCode") + if err := c.Bind(request); err != nil { + log.Println(err) + return middlewares.Responder(c, http.StatusBadRequest, "Bad Request") + } + */ + log.Println(request.Subject, request.SubjectCode) + err := rc.rs.EditStudyMaterialSubject(request.Subject, request.SubjectCode) + if err != nil { + log.Println(color.RedString(err.Error())) + return middlewares.Responder(c, http.StatusConflict, err) + } + return middlewares.Responder(c, http.StatusOK, "Success") +} + +// UpdateStudyMaterialURL godoc +// +// @Summary Update a study material's document +// @Description Update a document and update it on Database +// @Tags StudyMaterial +// @Accept multipart/form-data +// @Produce json +// @Param name formData string true "Enter the name of material" +// @Param document formData file true "Edit Document" +// @Success 200 {object} string +// @Failure 400 {object} models.Error +// +// @Security ApiKeyAuth +// @Router /v1/studymaterial/edit/document [put] +func (rc *studyMaterialController) UpdateStudyMaterialURL(c echo.Context) error { + + request := new(models.StudyMaterialRequest) + if err := c.Bind(request); err != nil { + log.Println(err) + return middlewares.Responder(c, http.StatusBadRequest, "Bad Request") + } + /* + name := c.Param("name") + request := new(models.StudyMaterialRequest) + if err := c.Bind(request); err != nil { + log.Println(err) + return middlewares.Responder(c, http.StatusBadRequest, "Bad Request") + } + */ + file, err := c.FormFile("document") + if err != nil { + log.Println(err) + return err + } + + err = rc.rs.EditStudyMaterialURL(request.Name, file) + if err != nil { + log.Println(color.RedString(err.Error())) + return middlewares.Responder(c, http.StatusConflict, err) + } + return middlewares.Responder(c, http.StatusOK, "Success") +} + +// DeleteStudyMaterial godoc +// +// @Summary Deletes a study material +// @Description Deletes a study material along with its document and remove form Database +// @Tags StudyMaterial +// @Accept json +// @Produce json +// @Param name path string true "Delete study material" +// @Success 200 {object} string +// @Failure 400 {object} models.Error +// +// @Security ApiKeyAuth +// @Router /v1/studymaterial/delete/{name} [delete] +func (rc *studyMaterialController) DeleteStudyMaterial(c echo.Context) error { + rname := c.Param("name") + + err := rc.rs.RemoveStudyMaterial(rname) + log.Println(rname) + if err != nil { + log.Println(color.RedString(err.Error())) + return middlewares.Responder(c, http.StatusConflict, "Error Occurred") + } + + return middlewares.Responder(c, http.StatusOK, "Success") +} diff --git a/controllers/team_controller.go b/controllers/team_controller.go index 6cbde60..bb98f9f 100644 --- a/controllers/team_controller.go +++ b/controllers/team_controller.go @@ -108,6 +108,8 @@ func (tc *teamController) AddMember(c echo.Context) error { log.Println(err) return middlewares.Responder(c, http.StatusBadRequest, "Bad Request") } + log.Println(request.Team) + log.Println(request.Role) file, err := c.FormFile("image") if err != nil { log.Println(err) From 894fc19c0c71abe60fec81f191584aa0f2ff7fa4 Mon Sep 17 00:00:00 2001 From: rspk2207 <83638002+rspk2207@users.noreply.github.com> Date: Fri, 20 Jan 2023 22:29:36 +0530 Subject: [PATCH 03/21] Add files via upload --- docs/docs.go | 343 ++++++++++++++++++++++++++++ docs/swagger.json | 343 ++++++++++++++++++++++++++++ docs/swagger.yaml | 226 ++++++++++++++++++ models/resource.go | 28 +++ registry/registry.go | 7 +- registry/resource_registry.go | 19 ++ repositories/resource_repository.go | 184 +++++++++++++++ repositories/seeder_repository.go | 5 + repositories/user_repository.go | 2 +- router/resource.go | 21 ++ router/router.go | 1 + 11 files changed, 1175 insertions(+), 4 deletions(-) create mode 100644 models/resource.go create mode 100644 registry/resource_registry.go create mode 100644 repositories/resource_repository.go create mode 100644 router/resource.go diff --git a/docs/docs.go b/docs/docs.go index 2f0243d..f18a9f3 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -24,6 +24,329 @@ const docTemplate = `{ "host": "{{.Host}}", "basePath": "{{.BasePath}}", "paths": { + "/v1/studymaterial/add": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Creates a new study material and adds to Database", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "StudyMaterial" + ], + "summary": "Add a study material", + "parameters": [ + { + "type": "string", + "description": "Enter material name", + "name": "name", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "Enter subject name", + "name": "subject", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "Enter subject code", + "name": "code", + "in": "formData", + "required": true + }, + { + "enum": [ + "DIGITAL ELECTRONICS", + "ANALOG ELECTRONICS", + "TELECOMMUNICATION", + "COMMUNICATION CHANNELING", + "SYSTEM DESIGN AND ARCHITECTURE", + "BASIC ENGINEERING", + "MATHEMATICS", + "OTHERS" + ], + "type": "string", + "description": "Choose a category", + "name": "category", + "in": "formData", + "required": true + }, + { + "type": "file", + "description": "Upload Document", + "name": "document", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, + "/v1/studymaterial/delete/{name}": { + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Deletes a study material along with its document and remove form Database", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "StudyMaterial" + ], + "summary": "Deletes a study material", + "parameters": [ + { + "type": "string", + "description": "Delete study material", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, + "/v1/studymaterial/edit/document": { + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Update a document and update it on Database", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "StudyMaterial" + ], + "summary": "Update a study material's document", + "parameters": [ + { + "type": "string", + "description": "Enter the name of material", + "name": "name", + "in": "formData", + "required": true + }, + { + "type": "file", + "description": "Edit Document", + "name": "document", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, + "/v1/studymaterial/edit/subject": { + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Updates a subject name and updates to Database", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "StudyMaterial" + ], + "summary": "Updates a studymaterial's subject name", + "parameters": [ + { + "type": "string", + "description": "Edit name", + "name": "subject", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "Enter subject code", + "name": "subjectCode", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, + "/v1/studymaterial/get/{name}": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Fetches a study material and removes form database", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "StudyMaterial" + ], + "summary": "Get a study material", + "parameters": [ + { + "type": "string", + "description": "Get study material", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.StudyMaterials" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, + "/v1/studymaterial/getcat/{category}": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Fetches all study materials belonging to a category from Database", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "StudyMaterial" + ], + "summary": "Get study materials from a categroy", + "parameters": [ + { + "enum": [ + "DIGITAL ELECTRONICS", + "ANALOG ELECTRONICS", + "TELECOMMUNICATION", + "COMMUNICATION CHANNELING", + "SYSTEM DESIGN AND ARCHITECTURE", + "BASIC ENGINEERING", + "MATHEMATICS", + "OTHERS" + ], + "type": "string", + "description": "Get study material from category", + "name": "category", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/models.StudyMaterials" + } + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, "/v1/team/add": { "post": { "security": [ @@ -604,6 +927,26 @@ const docTemplate = `{ "type": "string" } } + }, + "models.StudyMaterials": { + "type": "object", + "properties": { + "document_url": { + "type": "string" + }, + "name": { + "type": "string" + }, + "subject": { + "type": "string" + }, + "subjectCode": { + "type": "string" + }, + "subject_category": { + "type": "string" + } + } } }, "securityDefinitions": { diff --git a/docs/swagger.json b/docs/swagger.json index b74456a..14f5671 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -15,6 +15,329 @@ "version": "1.0" }, "paths": { + "/v1/studymaterial/add": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Creates a new study material and adds to Database", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "StudyMaterial" + ], + "summary": "Add a study material", + "parameters": [ + { + "type": "string", + "description": "Enter material name", + "name": "name", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "Enter subject name", + "name": "subject", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "Enter subject code", + "name": "code", + "in": "formData", + "required": true + }, + { + "enum": [ + "DIGITAL ELECTRONICS", + "ANALOG ELECTRONICS", + "TELECOMMUNICATION", + "COMMUNICATION CHANNELING", + "SYSTEM DESIGN AND ARCHITECTURE", + "BASIC ENGINEERING", + "MATHEMATICS", + "OTHERS" + ], + "type": "string", + "description": "Choose a category", + "name": "category", + "in": "formData", + "required": true + }, + { + "type": "file", + "description": "Upload Document", + "name": "document", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, + "/v1/studymaterial/delete/{name}": { + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Deletes a study material along with its document and remove form Database", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "StudyMaterial" + ], + "summary": "Deletes a study material", + "parameters": [ + { + "type": "string", + "description": "Delete study material", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, + "/v1/studymaterial/edit/document": { + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Update a document and update it on Database", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "StudyMaterial" + ], + "summary": "Update a study material's document", + "parameters": [ + { + "type": "string", + "description": "Enter the name of material", + "name": "name", + "in": "formData", + "required": true + }, + { + "type": "file", + "description": "Edit Document", + "name": "document", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, + "/v1/studymaterial/edit/subject": { + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Updates a subject name and updates to Database", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "StudyMaterial" + ], + "summary": "Updates a studymaterial's subject name", + "parameters": [ + { + "type": "string", + "description": "Edit name", + "name": "subject", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "Enter subject code", + "name": "subjectCode", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, + "/v1/studymaterial/get/{name}": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Fetches a study material and removes form database", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "StudyMaterial" + ], + "summary": "Get a study material", + "parameters": [ + { + "type": "string", + "description": "Get study material", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.StudyMaterials" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, + "/v1/studymaterial/getcat/{category}": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Fetches all study materials belonging to a category from Database", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "StudyMaterial" + ], + "summary": "Get study materials from a categroy", + "parameters": [ + { + "enum": [ + "DIGITAL ELECTRONICS", + "ANALOG ELECTRONICS", + "TELECOMMUNICATION", + "COMMUNICATION CHANNELING", + "SYSTEM DESIGN AND ARCHITECTURE", + "BASIC ENGINEERING", + "MATHEMATICS", + "OTHERS" + ], + "type": "string", + "description": "Get study material from category", + "name": "category", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/models.StudyMaterials" + } + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, "/v1/team/add": { "post": { "security": [ @@ -595,6 +918,26 @@ "type": "string" } } + }, + "models.StudyMaterials": { + "type": "object", + "properties": { + "document_url": { + "type": "string" + }, + "name": { + "type": "string" + }, + "subject": { + "type": "string" + }, + "subjectCode": { + "type": "string" + }, + "subject_category": { + "type": "string" + } + } } }, "securityDefinitions": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 4f5429a..89fa075 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -63,6 +63,19 @@ definitions: message: type: string type: object + models.StudyMaterials: + properties: + document_url: + type: string + name: + type: string + subject: + type: string + subject_category: + type: string + subjectCode: + type: string + type: object info: contact: email: probe.eceanitt@gmail.com @@ -75,6 +88,219 @@ info: title: Probe Admin version: "1.0" paths: + /v1/studymaterial/add: + post: + consumes: + - multipart/form-data + description: Creates a new study material and adds to Database + parameters: + - description: Enter material name + in: formData + name: name + required: true + type: string + - description: Enter subject name + in: formData + name: subject + required: true + type: string + - description: Enter subject code + in: formData + name: code + required: true + type: string + - description: Choose a category + enum: + - DIGITAL ELECTRONICS + - ANALOG ELECTRONICS + - TELECOMMUNICATION + - COMMUNICATION CHANNELING + - SYSTEM DESIGN AND ARCHITECTURE + - BASIC ENGINEERING + - MATHEMATICS + - OTHERS + in: formData + name: category + required: true + type: string + - description: Upload Document + in: formData + name: document + required: true + type: file + produces: + - application/json + responses: + "200": + description: OK + schema: + type: string + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.Error' + security: + - ApiKeyAuth: [] + summary: Add a study material + tags: + - StudyMaterial + /v1/studymaterial/delete/{name}: + delete: + consumes: + - application/json + description: Deletes a study material along with its document and remove form + Database + parameters: + - description: Delete study material + in: path + name: name + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + type: string + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.Error' + security: + - ApiKeyAuth: [] + summary: Deletes a study material + tags: + - StudyMaterial + /v1/studymaterial/edit/document: + put: + consumes: + - multipart/form-data + description: Update a document and update it on Database + parameters: + - description: Enter the name of material + in: formData + name: name + required: true + type: string + - description: Edit Document + in: formData + name: document + required: true + type: file + produces: + - application/json + responses: + "200": + description: OK + schema: + type: string + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.Error' + security: + - ApiKeyAuth: [] + summary: Update a study material's document + tags: + - StudyMaterial + /v1/studymaterial/edit/subject: + put: + consumes: + - multipart/form-data + description: Updates a subject name and updates to Database + parameters: + - description: Edit name + in: formData + name: subject + required: true + type: string + - description: Enter subject code + in: formData + name: subjectCode + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + type: string + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.Error' + security: + - ApiKeyAuth: [] + summary: Updates a studymaterial's subject name + tags: + - StudyMaterial + /v1/studymaterial/get/{name}: + get: + consumes: + - application/json + description: Fetches a study material and removes form database + parameters: + - description: Get study material + in: path + name: name + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.StudyMaterials' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.Error' + security: + - ApiKeyAuth: [] + summary: Get a study material + tags: + - StudyMaterial + /v1/studymaterial/getcat/{category}: + get: + consumes: + - application/json + description: Fetches all study materials belonging to a category from Database + parameters: + - description: Get study material from category + enum: + - DIGITAL ELECTRONICS + - ANALOG ELECTRONICS + - TELECOMMUNICATION + - COMMUNICATION CHANNELING + - SYSTEM DESIGN AND ARCHITECTURE + - BASIC ENGINEERING + - MATHEMATICS + - OTHERS + in: path + name: category + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/models.StudyMaterials' + type: array + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.Error' + security: + - ApiKeyAuth: [] + summary: Get study materials from a categroy + tags: + - StudyMaterial /v1/team/add: post: consumes: diff --git a/models/resource.go b/models/resource.go new file mode 100644 index 0000000..02f7981 --- /dev/null +++ b/models/resource.go @@ -0,0 +1,28 @@ +package models + +type StudyMaterialRequest struct { + Name string `json:"name" form:"name"` + Subject string `json:"subject" form:"subject"` + SubjectCategory string `json:"subject_category" form:"category"` + SubjectCode string `json:"subject_code" form:"code"` +} +type StudyMaterials struct { + Name string `json:"name"` + Subject string `json:"subject"` + SubjectCategory string `json:"subject_category"` + SubjectCode string `hson:"subject_code"` + DocumentURL string `json:"document_url"` +} + +type SubjectCategory string + +const ( + DigitalElectronics SubjectCategory = "DIGITAL ELECTRONICS" + AnalogElectronics SubjectCategory = "ANALOG ELECTRONICS" + Telecommunication SubjectCategory = "TELECOMMUNICATION" + CommunicationChanneling SubjectCategory = "COMMUNICATION CHANNELING" + SystemDesignAndArchitechture SubjectCategory = "SYSTEM DESIGN AND ARCHITECTURE" + BasicEngineering SubjectCategory = "BASIC ENGINEERING" + Mathematics SubjectCategory = "MATHEMATICS" + Others SubjectCategory = "OTHERS" +) diff --git a/registry/registry.go b/registry/registry.go index 1142ec8..32c4dc7 100644 --- a/registry/registry.go +++ b/registry/registry.go @@ -19,8 +19,9 @@ func NewRegistry(db *gorm.DB) Registry { func (r *registry) NewAppController() controllers.AppController { return controllers.AppController{ - User: r.NewUserController(), - Team: r.NewTeamController(), - Seed: r.NewSeedController(), + User: r.NewUserController(), + Team: r.NewTeamController(), + Seed: r.NewSeedController(), + StudyMaterial: r.NewStudyMaterialController(), } } diff --git a/registry/resource_registry.go b/registry/resource_registry.go new file mode 100644 index 0000000..8e9324e --- /dev/null +++ b/registry/resource_registry.go @@ -0,0 +1,19 @@ +package registry + +import ( + "github.com/ecea-nitt/ecea-server/controllers" + "github.com/ecea-nitt/ecea-server/repositories" + "github.com/ecea-nitt/ecea-server/services" +) + +func (r *registry) NewStudyMaterialController() controllers.StudyMaterialController { + return controllers.NewStudyMaterialController(r.NewStudyMaterialService()) +} + +func (r *registry) NewStudyMaterialService() services.StudyMaterialService { + return services.NewStudyMaterialService(r.NewStudyMaterialRepository()) +} + +func (r *registry) NewStudyMaterialRepository() repositories.StudyMaterialRepository { + return repositories.NewStudyMaterialRepository(r.db) +} diff --git a/repositories/resource_repository.go b/repositories/resource_repository.go new file mode 100644 index 0000000..7354082 --- /dev/null +++ b/repositories/resource_repository.go @@ -0,0 +1,184 @@ +package repositories + +import ( + "github.com/ecea-nitt/ecea-server/config" + "github.com/ecea-nitt/ecea-server/models" + "github.com/ecea-nitt/ecea-server/schemas" + "gorm.io/gorm" + "gorm.io/gorm/clause" +) + +type studyMaterialRepository struct { + db *gorm.DB +} + +type StudyMaterialRepository interface { + GetCategoryStudyMaterials(name string) ([]models.StudyMaterials, error) + FindStudyMaterialByName(name string) (models.StudyMaterials, error) + FindStudyMaterialByNameReturnSchema(name string) (schemas.StudyMaterial, error) + GetSubjectID(name string) (uint, error) + GetSubjectCategoryID(name string) (uint, error) + GetSubjectCategory(subject string) (string, error) + GetSubjectIDByName(name string) (uint, error) + GetAssetIDByName(name string) (uint, error) + InsertAsset(name string) (uint, error) + UpdateAsset(id uint, name string) error + CreateSubjectAndReturnID(studyMaterialDetails models.StudyMaterialRequest, id uint) (uint, error) + CreateStudyMaterial(studyMaterial *schemas.StudyMaterial) error + UpdateStudyMaterialSubject(editrequest *schemas.Subject, name string, code string) error + UpdateStudyMaterial(studyMaterial *schemas.StudyMaterial) error + DeleteStudyMaterial(name string, subjectID uint, assetID uint) error +} + +func NewStudyMaterialRepository(db *gorm.DB) StudyMaterialRepository { + return &studyMaterialRepository{db} +} + +func (rr *studyMaterialRepository) UpdateStudyMaterialSubject(editrequest *schemas.Subject, name string, code string) error { + /* + return rr.db.Table("subjects").Where("subjects.subject_code = ?", code).Update("subjects.name", name).Error + return rr.db.Model(&schemas.Subject{}).Where("subjects.subject_code = ?", code).Update("name", name).Error + */ + return rr.db.Model(&editrequest).Where("subject_code = ?", code).Updates(&editrequest).Error +} + +func (rr *studyMaterialRepository) CreateStudyMaterial(studyMaterial *schemas.StudyMaterial) error { + return rr.db.Create(&studyMaterial).Error +} + +func (rr *studyMaterialRepository) GetSubjectIDByName(name string) (uint, error) { + var studyMaterial schemas.StudyMaterial + res := rr.db.Where("name = ?", name).First(&studyMaterial) + if res.Error != nil { + return 0, res.Error + } + return studyMaterial.SubjectID, nil +} +func (rr *studyMaterialRepository) DeleteStudyMaterial(name string, subjectID uint, assetID uint) error { + err := rr.db.Unscoped().Where("id = ?", subjectID).Delete(&schemas.Subject{}).Error + if err != nil { + return err + } + err = rr.db.Unscoped().Where("id = ?", assetID).Delete(&schemas.Asset{}).Error + if err != nil { + return err + } + return rr.db.Unscoped().Where("name = ?", name).Delete(&schemas.StudyMaterial{}).Error +} + +func (rr *studyMaterialRepository) GetSubjectID(name string) (uint, error) { + var subject schemas.Subject + res := rr.db.Where("subject_code = ?", name).First(&subject) + if res.Error != nil { + return 0, res.Error + } + return subject.ID, nil +} + +func (rr *studyMaterialRepository) GetSubjectCategoryID(name string) (uint, error) { + var subjectCategory schemas.SubjectCategory + res := rr.db.Where("name = ?", name).First(&subjectCategory) + if res.Error != nil { + return 0, res.Error + } + return subjectCategory.ID, nil +} + +func (rr *studyMaterialRepository) GetAssetIDByName(name string) (uint, error) { + var studyMaterial schemas.StudyMaterial + res := rr.db.Where("name = ?", name).First(&studyMaterial) + if res.Error != nil { + return 0, res.Error + } + return studyMaterial.AssetID, nil +} + +func (rr *studyMaterialRepository) InsertAsset(name string) (uint, error) { + var assetType schemas.AssetType + if err := rr.db.Where("name = ?", schemas.Document).First(&assetType).Error; err != nil { + return 0, err + } + asset := schemas.Asset{ + Name: name, + AssetTypeID: assetType.ID, + } + if err := rr.db.Create(&asset).Error; err != nil { + return 0, err + } + return asset.ID, nil +} + +func (rr *studyMaterialRepository) FindStudyMaterialByName(name string) (models.StudyMaterials, error) { + /* + var studyMaterial schemas.StudyMaterial + + err := rr.db.Preload(clause.Associations).Where("name = ?", name).First(&studyMaterial).Error + return studyMaterial, err + */ + var studyMaterials models.StudyMaterials + err := rr.db.Table("study_materials").Select( + `study_materials.name as name,subjects.name as subject,subjects.subject_code as subject_code,CONCAT(?::text,'/static/documents','/',assets.name) as document_url`, config.Origin, + ).Joins( + "JOIN assets on assets.id = study_materials.asset_id").Joins( + "JOIN subjects on subjects.id = study_materials.subject_id").Where( + "study_materials.name = ?", name).First( + &studyMaterials).Error + if err != nil { + return models.StudyMaterials{}, err + } + return studyMaterials, nil +} + +func (rr *studyMaterialRepository) UpdateStudyMaterial(studyMaterial *schemas.StudyMaterial) error { + return rr.db.Model(&studyMaterial).Where("id = ?", studyMaterial.ID).Updates(&studyMaterial).Error +} + +func (rr *studyMaterialRepository) GetCategoryStudyMaterials(name string) ([]models.StudyMaterials, error) { + var studyMaterials []models.StudyMaterials + if err := rr.db.Table("study_materials").Select( + `study_materials.name as name,subjects.name as subject,subject_categories.name as subject_category,subjects.subject_code as subject_code, CONCAT(?::text,'/static/documents','/',assets.name) as document_url`, config.Origin, + ).Joins( + "JOIN assets on assets.id = study_materials.asset_id").Joins( + "JOIN subjects on subjects.id = study_materials.subject_id").Joins("JOIN subject_categories on subject_categories.id = subjects.subject_category_id").Where("subject_categories.name = ?", name).Scan( + &studyMaterials).Error; err != nil { + return nil, err + } + + return studyMaterials, nil +} + +func (rr *studyMaterialRepository) UpdateAsset(id uint, name string) error { + return rr.db.Model(&schemas.Asset{}).Where("id = ?", id).Update("name", name).Error +} + +func (rr *studyMaterialRepository) CreateSubjectAndReturnID(studyMaterialDetails models.StudyMaterialRequest, id uint) (uint, error) { + subject := schemas.Subject{ + Name: studyMaterialDetails.Subject, + SubjectCategoryID: id, + SubjectCode: studyMaterialDetails.SubjectCode, + } + res := rr.db.Create(&subject) + if res.Error != nil { + return 0, res.Error + } + return subject.ID, nil +} + +func (rr *studyMaterialRepository) GetSubjectCategory(subject string) (string, error) { + var category string + if err := rr.db.Table("subject_categories").Select( + `subject_categories.name`, + ).Joins( + "JOIN subjects on subjects.subject_category_id = subject_categories.id").Where("subjects.name = ?", subject).Scan( + &category).Error; err != nil { + return "", err + } + return category, nil +} + +func (rr *studyMaterialRepository) FindStudyMaterialByNameReturnSchema(name string) (schemas.StudyMaterial, error) { + var studyMaterial schemas.StudyMaterial + + err := rr.db.Preload(clause.Associations).Where("name = ?", name).First(&studyMaterial).Error + return studyMaterial, err +} diff --git a/repositories/seeder_repository.go b/repositories/seeder_repository.go index f71db45..71f79d5 100644 --- a/repositories/seeder_repository.go +++ b/repositories/seeder_repository.go @@ -13,6 +13,7 @@ type SeedRepository interface { InsertTeams(teams []schemas.Team) error InsertRoles(roles []schemas.Role) error InsertAssetTypes(types []schemas.AssetType) error + InsertSubjectCategory(sc []schemas.SubjectCategory) error } func NewSeedRepository(db *gorm.DB) SeedRepository { @@ -31,3 +32,7 @@ func (sr *seedRepository) InsertRoles(roles []schemas.Role) error { func (sr *seedRepository) InsertAssetTypes(types []schemas.AssetType) error { return sr.db.Create(&types).Error } + +func (sr *seedRepository) InsertSubjectCategory(sc []schemas.SubjectCategory) error { + return sr.db.Create(&sc).Error +} diff --git a/repositories/user_repository.go b/repositories/user_repository.go index d0fc51d..6a25cf6 100644 --- a/repositories/user_repository.go +++ b/repositories/user_repository.go @@ -38,7 +38,7 @@ func (ur *userRepository) UpdateVerification(code string) error { return res.Error } if res.RowsAffected == 0 { - err = fmt.Errorf("No Matching User Found") + err = fmt.Errorf(" No Matching User Found") } return err } diff --git a/router/resource.go b/router/resource.go new file mode 100644 index 0000000..15d0db5 --- /dev/null +++ b/router/resource.go @@ -0,0 +1,21 @@ +package router + +import ( + "github.com/ecea-nitt/ecea-server/controllers" + "github.com/ecea-nitt/ecea-server/middlewares" + "github.com/labstack/echo/v4" +) + +func StudyMaterialRoutes(e *echo.Group, c controllers.StudyMaterialController) { + studyMaterial := e.Group("/studymaterial") + + studyMaterial.POST("/add", middlewares.Authorizer(c.AddStudyMaterial)) + studyMaterial.PUT("/edit/document", middlewares.Authorizer(c.UpdateStudyMaterialURL)) + // studyMaterial.PUT("/edit/name", middlewares.Authorizer(c.EditRessourceName)) + // studyMaterial.PUT("/edit/bookid", middlewares.Authorizer(c.EditMemberRole)) + studyMaterial.PUT("/edit/subject", middlewares.Authorizer(c.UpdateStudyMaterialSubject)) + studyMaterial.GET("/getcat/:category", c.GetCategoryStudyMaterials) + studyMaterial.GET("/get/:name", c.GetStudyMaterial) + studyMaterial.DELETE("/delete/:name", middlewares.Authorizer(c.DeleteStudyMaterial)) + +} diff --git a/router/router.go b/router/router.go index 20a3ac4..48d3897 100644 --- a/router/router.go +++ b/router/router.go @@ -16,5 +16,6 @@ func NewRouter(e *echo.Echo, c controllers.AppController) { UserRoutes(api, c.User) TeamRoutes(api, c.Team) + StudyMaterialRoutes(api, c.StudyMaterial) SwaggerRoutes(api) } From 23901ce830bd5973e744098f3d0aa1d7518bdf0d Mon Sep 17 00:00:00 2001 From: rspk2207 <83638002+rspk2207@users.noreply.github.com> Date: Fri, 20 Jan 2023 22:36:34 +0530 Subject: [PATCH 04/21] Add files via upload --- docker-compose.yml | 14 ++-- go.sum | 2 +- main.go | 2 +- schemas/Schemas.md | 3 + schemas/asset.go | 2 +- schemas/resource.go | 25 +++++++ services/resource_service.go | 128 +++++++++++++++++++++++++++++++++++ services/seeder_service.go | 31 +++++++++ utils/document.go | 51 ++++++++++++++ utils/validator.go | 4 +- 10 files changed, 251 insertions(+), 11 deletions(-) create mode 100644 schemas/Schemas.md create mode 100644 schemas/resource.go create mode 100644 services/resource_service.go create mode 100644 utils/document.go diff --git a/docker-compose.yml b/docker-compose.yml index 1c09ed0..a43e35b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -29,10 +29,12 @@ services: ports: - ${POSTGRES_PORT}:${POSTGRES_PORT} command: -p ${POSTGRES_PORT} - volumes: - - ./database:/data/postgres +# volumes: +# - database:/data/postgres +#volumes: +# database: -networks: - default: - external: - name: thirumathikart_network +# networks: +# default: +# external: +# name: thirumathikart_network \ No newline at end of file diff --git a/go.sum b/go.sum index adf54a6..a4d5512 100644 --- a/go.sum +++ b/go.sum @@ -163,7 +163,7 @@ github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXY github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIDttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= diff --git a/main.go b/main.go index bcb207a..92acc95 100644 --- a/main.go +++ b/main.go @@ -36,7 +36,7 @@ func main() { appController := reg.NewAppController() // Seed database - // appController.Seed.SeedDB() + //appController.Seed.SeedDB() // Create and Setup Echo Server server := echo.New() diff --git a/schemas/Schemas.md b/schemas/Schemas.md new file mode 100644 index 0000000..70537a3 --- /dev/null +++ b/schemas/Schemas.md @@ -0,0 +1,3 @@ +# Schemas + +![eceadb](https://user-images.githubusercontent.com/63253383/210140288-b791f989-0729-4a8d-ac4d-e501347bc7ad.jpg) \ No newline at end of file diff --git a/schemas/asset.go b/schemas/asset.go index 7ab5f23..c63c7e4 100644 --- a/schemas/asset.go +++ b/schemas/asset.go @@ -11,7 +11,7 @@ type Asset struct { type AssetType struct { gorm.Model - Name string `gorm:"not null;unique"` + Name string `gorm:"not null;"` } type AssetTypes string diff --git a/schemas/resource.go b/schemas/resource.go new file mode 100644 index 0000000..56e976e --- /dev/null +++ b/schemas/resource.go @@ -0,0 +1,25 @@ +package schemas + +import "gorm.io/gorm" + +type StudyMaterial struct { + gorm.Model + Name string `gorm:"not null; unique"` + AssetID uint `gorm:"default: null"` + Asset Asset `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` + SubjectID uint `gorm:"default: null"` + Subject Subject `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` +} + +type Subject struct { + gorm.Model + SubjectCode string `gorm:"not null; unique"` + Name string `gorm:"not null"` + SubjectCategoryID uint `gorm:"default: null"` + SubjectCategory SubjectCategory `gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"` +} + +type SubjectCategory struct { + gorm.Model + Name string `gorm:"not null; unique"` +} diff --git a/services/resource_service.go b/services/resource_service.go new file mode 100644 index 0000000..888dce3 --- /dev/null +++ b/services/resource_service.go @@ -0,0 +1,128 @@ +package services + +import ( + "errors" + "log" + "mime/multipart" + + "github.com/ecea-nitt/ecea-server/helpers" + "github.com/ecea-nitt/ecea-server/models" + "github.com/ecea-nitt/ecea-server/repositories" + "github.com/ecea-nitt/ecea-server/schemas" +) + +type studyMaterialService struct { + repo repositories.StudyMaterialRepository +} + +type StudyMaterialService interface { + CreateNewStudyMaterial(studyMaterialDetails models.StudyMaterialRequest, studyMaterialFile *multipart.FileHeader) error + EditStudyMaterialSubject(subject string, code string) error + EditStudyMaterialURL(name string, file *multipart.FileHeader) error + GetStudyMaterial(name string) (models.StudyMaterials, error) + GetCategoryStudyMaterials(name string) ([]models.StudyMaterials, error) + RemoveStudyMaterial(name string) error +} + +func NewStudyMaterialService(repo repositories.StudyMaterialRepository) StudyMaterialService { + return &studyMaterialService{repo} +} + +func (rs *studyMaterialService) CreateNewStudyMaterial(studyMaterialDetails models.StudyMaterialRequest, studyMaterialFile *multipart.FileHeader) error { + assetChannel := make(chan int) + subjectChannel := make(chan int) + subjectCategoryChannel := make(chan int) + /* + subjectCategoryID, err := rs.repo.GetSubjectCategoryID(studyMaterialDetails.SubjectCategory) + if err != nil { + return err + } + */ + go helpers.FetchSubjectCategoryID(subjectCategoryChannel, studyMaterialDetails.SubjectCategory, rs.repo) + subjectCategoryID := <-subjectCategoryChannel + go helpers.FetchSubjectID(subjectChannel, studyMaterialDetails, subjectCategoryID, rs.repo) + go helpers.UploadFileAndFetchAssetID(assetChannel, studyMaterialFile, rs.repo) + subjectID := <-subjectChannel + assetID := <-assetChannel + if subjectID == -1 || assetID == -1 || subjectCategoryID == -1 { + return errors.New("could not fetch data") + } + studyMaterial := schemas.StudyMaterial{ + Name: studyMaterialDetails.Name, + SubjectID: uint(subjectID), + AssetID: uint(assetID), + } + log.Println(subjectCategoryID, studyMaterialDetails.SubjectCategory) + return rs.repo.CreateStudyMaterial(&studyMaterial) +} + +func (rs *studyMaterialService) EditStudyMaterialSubject(subject string, code string) error { + editrequest := schemas.Subject{ + Name: subject, + SubjectCode: code, + } + /* + subjectID, err := rs.repo.GetSubjectIDByCode(code) + if err != nil { + return err + } + */ + return rs.repo.UpdateStudyMaterialSubject(&editrequest, subject, code) +} + +func (rs *studyMaterialService) EditStudyMaterialURL(name string, file *multipart.FileHeader) error { + dbStudyMaterial, err := rs.repo.FindStudyMaterialByNameReturnSchema(name) + if err != nil { + return err + } + + assetID := helpers.UpdateFileAndFetchAssetID(dbStudyMaterial.AssetID, dbStudyMaterial.Asset.Name, file, rs.repo) + + if assetID == -1 { + return errors.New(" Error Occurred") + } + + studyMaterial := schemas.StudyMaterial{ + AssetID: uint(assetID), + } + studyMaterial.ID = dbStudyMaterial.ID + + return rs.repo.UpdateStudyMaterial(&studyMaterial) +} + +func (rs *studyMaterialService) RemoveStudyMaterial(name string) error { + subjectID, err1 := rs.repo.GetSubjectIDByName(name) + if err1 != nil { + return err1 + } + assetID, err2 := rs.repo.GetAssetIDByName(name) + if err2 != nil { + return err2 + } + return rs.repo.DeleteStudyMaterial(name, subjectID, assetID) +} + +func (rs *studyMaterialService) GetStudyMaterial(name string) (models.StudyMaterials, error) { + studyMaterial, err := rs.repo.FindStudyMaterialByName(name) + if err != nil { + return models.StudyMaterials{}, err + } + subjectCategory, err1 := rs.repo.GetSubjectCategory(studyMaterial.Subject) + if err1 != nil { + return models.StudyMaterials{}, err1 + } + result := models.StudyMaterials{ + Name: studyMaterial.Name, + Subject: studyMaterial.Subject, + SubjectCategory: subjectCategory, + SubjectCode: studyMaterial.SubjectCode, + DocumentURL: studyMaterial.DocumentURL, + } + log.Println(studyMaterial) + log.Println(result) + return result, err +} + +func (rs *studyMaterialService) GetCategoryStudyMaterials(name string) ([]models.StudyMaterials, error) { + return rs.repo.GetCategoryStudyMaterials(name) +} diff --git a/services/seeder_service.go b/services/seeder_service.go index 9837b41..125cea4 100644 --- a/services/seeder_service.go +++ b/services/seeder_service.go @@ -14,6 +14,7 @@ type SeederService interface { AssetTypesSeeder() error TeamsSeeder() error RolesSeeder() error + StudyMaterialSeeder() error } var teams = []schemas.Team{ @@ -60,6 +61,32 @@ var assetTypes = []schemas.AssetType{ Name: string(schemas.Document), }, } +var subjectCategory = []schemas.SubjectCategory{ + { + Name: string(models.AnalogElectronics), + }, + { + Name: string(models.CommunicationChanneling), + }, + { + Name: string(models.DigitalElectronics), + }, + { + Name: string(models.SystemDesignAndArchitechture), + }, + { + Name: string(models.BasicEngineering), + }, + { + Name: string(models.Mathematics), + }, + { + Name: string(models.Telecommunication), + }, + { + Name: string(models.Others), + }, +} func NewSeeder(repo repositories.SeedRepository) SeederService { return &seederService{repo} @@ -76,3 +103,7 @@ func (s *seederService) RolesSeeder() error { func (s *seederService) AssetTypesSeeder() error { return s.repo.InsertAssetTypes(assetTypes) } + +func (s *seederService) StudyMaterialSeeder() error { + return s.repo.InsertSubjectCategory(subjectCategory) +} diff --git a/utils/document.go b/utils/document.go new file mode 100644 index 0000000..74704b1 --- /dev/null +++ b/utils/document.go @@ -0,0 +1,51 @@ +package utils + +import ( + "io" + "log" + "mime/multipart" + "os" + "time" + + "github.com/fatih/color" +) + +var DocumentPath = "static/documents/" + +func UploadDocument(file *multipart.FileHeader) (string, error) { + + src, err := file.Open() + if err != nil { + return "", err + } + defer src.Close() + + // Destination + timeStamp := time.Now() + + if _, err := os.Stat(DocumentPath); os.IsNotExist(err) { + _ = os.Mkdir(DocumentPath, 0777) + } + fileName := timeStamp.Format(time.RFC3339) + ".pdf" + path := DocumentPath + fileName + dst, err := os.Create(path) + if err != nil { + return "", err + } + defer dst.Close() + // Copy + if _, err = io.Copy(dst, src); err != nil { + return "", err + } + return fileName, nil +} + +func DeleteDocument(fileName string) error { + path := DocumentPath + fileName + log.Println(color.MagentaString("Deleting: " + path)) + e := os.Remove(path) + if e != nil { + return e + } + return nil +} diff --git a/utils/validator.go b/utils/validator.go index f033495..b1d990b 100644 --- a/utils/validator.go +++ b/utils/validator.go @@ -17,7 +17,7 @@ import ( func NameValidator(s string) (string, error) { var IsLetter = regexp.MustCompile(`^[a-zA-Z ]+$`).MatchString if !IsLetter(s) { - return s, fmt.Errorf("Name should only contain characters") + return s, fmt.Errorf(" Name should only contain characters") } name := cases.Lower(language.Und).String(s) name = cases.Title(language.Und).String(name) @@ -37,7 +37,7 @@ func NumericValidator(s string) (string, error) { func EmailValidator(s string) (string, error) { var IsValid = regexp.MustCompile(`^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$`).MatchString if !IsValid(s) { - return s, errors.New("Invalid Email format") + return s, errors.New(" Invalid Email format") } return s, nil } From c4dc65fb5b4c1886d59bf126004697f593de47a5 Mon Sep 17 00:00:00 2001 From: rspk2207 <83638002+rspk2207@users.noreply.github.com> Date: Fri, 20 Jan 2023 23:07:51 +0530 Subject: [PATCH 05/21] Add files via upload --- models/resource.go | 56 ++--- repositories/resource_repository.go | 368 ++++++++++++++-------------- repositories/user_repository.go | 2 +- 3 files changed, 213 insertions(+), 213 deletions(-) diff --git a/models/resource.go b/models/resource.go index 02f7981..b70f1a0 100644 --- a/models/resource.go +++ b/models/resource.go @@ -1,28 +1,28 @@ -package models - -type StudyMaterialRequest struct { - Name string `json:"name" form:"name"` - Subject string `json:"subject" form:"subject"` - SubjectCategory string `json:"subject_category" form:"category"` - SubjectCode string `json:"subject_code" form:"code"` -} -type StudyMaterials struct { - Name string `json:"name"` - Subject string `json:"subject"` - SubjectCategory string `json:"subject_category"` - SubjectCode string `hson:"subject_code"` - DocumentURL string `json:"document_url"` -} - -type SubjectCategory string - -const ( - DigitalElectronics SubjectCategory = "DIGITAL ELECTRONICS" - AnalogElectronics SubjectCategory = "ANALOG ELECTRONICS" - Telecommunication SubjectCategory = "TELECOMMUNICATION" - CommunicationChanneling SubjectCategory = "COMMUNICATION CHANNELING" - SystemDesignAndArchitechture SubjectCategory = "SYSTEM DESIGN AND ARCHITECTURE" - BasicEngineering SubjectCategory = "BASIC ENGINEERING" - Mathematics SubjectCategory = "MATHEMATICS" - Others SubjectCategory = "OTHERS" -) +package models + +type StudyMaterialRequest struct { + Name string `json:"name" form:"name"` + Subject string `json:"subject" form:"subject"` + SubjectCategory string `json:"subject_category" form:"category"` + SubjectCode string `json:"subject_code" form:"code"` +} +type StudyMaterials struct { + Name string `json:"name"` + Subject string `json:"subject"` + SubjectCategory string `json:"subject_category"` + SubjectCode string `hson:"subject_code"` + DocumentURL string `json:"document_url"` +} + +type SubjectCategory string + +const ( + DigitalElectronics SubjectCategory = "DIGITAL ELECTRONICS" + AnalogElectronics SubjectCategory = "ANALOG ELECTRONICS" + Telecommunication SubjectCategory = "TELECOMMUNICATION" + CommunicationChanneling SubjectCategory = "COMMUNICATION CHANNELING" + SystemDesignAndArchitechture SubjectCategory = "SYSTEM DESIGN AND ARCHITECTURE" + BasicEngineering SubjectCategory = "BASIC ENGINEERING" + Mathematics SubjectCategory = "MATHEMATICS" + Others SubjectCategory = "OTHERS" +) diff --git a/repositories/resource_repository.go b/repositories/resource_repository.go index 7354082..f2be5cf 100644 --- a/repositories/resource_repository.go +++ b/repositories/resource_repository.go @@ -1,184 +1,184 @@ -package repositories - -import ( - "github.com/ecea-nitt/ecea-server/config" - "github.com/ecea-nitt/ecea-server/models" - "github.com/ecea-nitt/ecea-server/schemas" - "gorm.io/gorm" - "gorm.io/gorm/clause" -) - -type studyMaterialRepository struct { - db *gorm.DB -} - -type StudyMaterialRepository interface { - GetCategoryStudyMaterials(name string) ([]models.StudyMaterials, error) - FindStudyMaterialByName(name string) (models.StudyMaterials, error) - FindStudyMaterialByNameReturnSchema(name string) (schemas.StudyMaterial, error) - GetSubjectID(name string) (uint, error) - GetSubjectCategoryID(name string) (uint, error) - GetSubjectCategory(subject string) (string, error) - GetSubjectIDByName(name string) (uint, error) - GetAssetIDByName(name string) (uint, error) - InsertAsset(name string) (uint, error) - UpdateAsset(id uint, name string) error - CreateSubjectAndReturnID(studyMaterialDetails models.StudyMaterialRequest, id uint) (uint, error) - CreateStudyMaterial(studyMaterial *schemas.StudyMaterial) error - UpdateStudyMaterialSubject(editrequest *schemas.Subject, name string, code string) error - UpdateStudyMaterial(studyMaterial *schemas.StudyMaterial) error - DeleteStudyMaterial(name string, subjectID uint, assetID uint) error -} - -func NewStudyMaterialRepository(db *gorm.DB) StudyMaterialRepository { - return &studyMaterialRepository{db} -} - -func (rr *studyMaterialRepository) UpdateStudyMaterialSubject(editrequest *schemas.Subject, name string, code string) error { - /* - return rr.db.Table("subjects").Where("subjects.subject_code = ?", code).Update("subjects.name", name).Error - return rr.db.Model(&schemas.Subject{}).Where("subjects.subject_code = ?", code).Update("name", name).Error - */ - return rr.db.Model(&editrequest).Where("subject_code = ?", code).Updates(&editrequest).Error -} - -func (rr *studyMaterialRepository) CreateStudyMaterial(studyMaterial *schemas.StudyMaterial) error { - return rr.db.Create(&studyMaterial).Error -} - -func (rr *studyMaterialRepository) GetSubjectIDByName(name string) (uint, error) { - var studyMaterial schemas.StudyMaterial - res := rr.db.Where("name = ?", name).First(&studyMaterial) - if res.Error != nil { - return 0, res.Error - } - return studyMaterial.SubjectID, nil -} -func (rr *studyMaterialRepository) DeleteStudyMaterial(name string, subjectID uint, assetID uint) error { - err := rr.db.Unscoped().Where("id = ?", subjectID).Delete(&schemas.Subject{}).Error - if err != nil { - return err - } - err = rr.db.Unscoped().Where("id = ?", assetID).Delete(&schemas.Asset{}).Error - if err != nil { - return err - } - return rr.db.Unscoped().Where("name = ?", name).Delete(&schemas.StudyMaterial{}).Error -} - -func (rr *studyMaterialRepository) GetSubjectID(name string) (uint, error) { - var subject schemas.Subject - res := rr.db.Where("subject_code = ?", name).First(&subject) - if res.Error != nil { - return 0, res.Error - } - return subject.ID, nil -} - -func (rr *studyMaterialRepository) GetSubjectCategoryID(name string) (uint, error) { - var subjectCategory schemas.SubjectCategory - res := rr.db.Where("name = ?", name).First(&subjectCategory) - if res.Error != nil { - return 0, res.Error - } - return subjectCategory.ID, nil -} - -func (rr *studyMaterialRepository) GetAssetIDByName(name string) (uint, error) { - var studyMaterial schemas.StudyMaterial - res := rr.db.Where("name = ?", name).First(&studyMaterial) - if res.Error != nil { - return 0, res.Error - } - return studyMaterial.AssetID, nil -} - -func (rr *studyMaterialRepository) InsertAsset(name string) (uint, error) { - var assetType schemas.AssetType - if err := rr.db.Where("name = ?", schemas.Document).First(&assetType).Error; err != nil { - return 0, err - } - asset := schemas.Asset{ - Name: name, - AssetTypeID: assetType.ID, - } - if err := rr.db.Create(&asset).Error; err != nil { - return 0, err - } - return asset.ID, nil -} - -func (rr *studyMaterialRepository) FindStudyMaterialByName(name string) (models.StudyMaterials, error) { - /* - var studyMaterial schemas.StudyMaterial - - err := rr.db.Preload(clause.Associations).Where("name = ?", name).First(&studyMaterial).Error - return studyMaterial, err - */ - var studyMaterials models.StudyMaterials - err := rr.db.Table("study_materials").Select( - `study_materials.name as name,subjects.name as subject,subjects.subject_code as subject_code,CONCAT(?::text,'/static/documents','/',assets.name) as document_url`, config.Origin, - ).Joins( - "JOIN assets on assets.id = study_materials.asset_id").Joins( - "JOIN subjects on subjects.id = study_materials.subject_id").Where( - "study_materials.name = ?", name).First( - &studyMaterials).Error - if err != nil { - return models.StudyMaterials{}, err - } - return studyMaterials, nil -} - -func (rr *studyMaterialRepository) UpdateStudyMaterial(studyMaterial *schemas.StudyMaterial) error { - return rr.db.Model(&studyMaterial).Where("id = ?", studyMaterial.ID).Updates(&studyMaterial).Error -} - -func (rr *studyMaterialRepository) GetCategoryStudyMaterials(name string) ([]models.StudyMaterials, error) { - var studyMaterials []models.StudyMaterials - if err := rr.db.Table("study_materials").Select( - `study_materials.name as name,subjects.name as subject,subject_categories.name as subject_category,subjects.subject_code as subject_code, CONCAT(?::text,'/static/documents','/',assets.name) as document_url`, config.Origin, - ).Joins( - "JOIN assets on assets.id = study_materials.asset_id").Joins( - "JOIN subjects on subjects.id = study_materials.subject_id").Joins("JOIN subject_categories on subject_categories.id = subjects.subject_category_id").Where("subject_categories.name = ?", name).Scan( - &studyMaterials).Error; err != nil { - return nil, err - } - - return studyMaterials, nil -} - -func (rr *studyMaterialRepository) UpdateAsset(id uint, name string) error { - return rr.db.Model(&schemas.Asset{}).Where("id = ?", id).Update("name", name).Error -} - -func (rr *studyMaterialRepository) CreateSubjectAndReturnID(studyMaterialDetails models.StudyMaterialRequest, id uint) (uint, error) { - subject := schemas.Subject{ - Name: studyMaterialDetails.Subject, - SubjectCategoryID: id, - SubjectCode: studyMaterialDetails.SubjectCode, - } - res := rr.db.Create(&subject) - if res.Error != nil { - return 0, res.Error - } - return subject.ID, nil -} - -func (rr *studyMaterialRepository) GetSubjectCategory(subject string) (string, error) { - var category string - if err := rr.db.Table("subject_categories").Select( - `subject_categories.name`, - ).Joins( - "JOIN subjects on subjects.subject_category_id = subject_categories.id").Where("subjects.name = ?", subject).Scan( - &category).Error; err != nil { - return "", err - } - return category, nil -} - -func (rr *studyMaterialRepository) FindStudyMaterialByNameReturnSchema(name string) (schemas.StudyMaterial, error) { - var studyMaterial schemas.StudyMaterial - - err := rr.db.Preload(clause.Associations).Where("name = ?", name).First(&studyMaterial).Error - return studyMaterial, err -} +package repositories + +import ( + "github.com/ecea-nitt/ecea-server/config" + "github.com/ecea-nitt/ecea-server/models" + "github.com/ecea-nitt/ecea-server/schemas" + "gorm.io/gorm" + "gorm.io/gorm/clause" +) + +type studyMaterialRepository struct { + db *gorm.DB +} + +type StudyMaterialRepository interface { + GetCategoryStudyMaterials(name string) ([]models.StudyMaterials, error) + FindStudyMaterialByName(name string) (models.StudyMaterials, error) + FindStudyMaterialByNameReturnSchema(name string) (schemas.StudyMaterial, error) + GetSubjectID(name string) (uint, error) + GetSubjectCategoryID(name string) (uint, error) + GetSubjectCategory(subject string) (string, error) + GetSubjectIDByName(name string) (uint, error) + GetAssetIDByName(name string) (uint, error) + InsertAsset(name string) (uint, error) + UpdateAsset(id uint, name string) error + CreateSubjectAndReturnID(studyMaterialDetails models.StudyMaterialRequest, id uint) (uint, error) + CreateStudyMaterial(studyMaterial *schemas.StudyMaterial) error + UpdateStudyMaterialSubject(editrequest *schemas.Subject, name string, code string) error + UpdateStudyMaterial(studyMaterial *schemas.StudyMaterial) error + DeleteStudyMaterial(name string, subjectID uint, assetID uint) error +} + +func NewStudyMaterialRepository(db *gorm.DB) StudyMaterialRepository { + return &studyMaterialRepository{db} +} + +func (rr *studyMaterialRepository) UpdateStudyMaterialSubject(editrequest *schemas.Subject, name string, code string) error { + /* + return rr.db.Table("subjects").Where("subjects.subject_code = ?", code).Update("subjects.name", name).Error + return rr.db.Model(&schemas.Subject{}).Where("subjects.subject_code = ?", code).Update("name", name).Error + */ + return rr.db.Model(&editrequest).Where("subject_code = ?", code).Updates(&editrequest).Error +} + +func (rr *studyMaterialRepository) CreateStudyMaterial(studyMaterial *schemas.StudyMaterial) error { + return rr.db.Create(&studyMaterial).Error +} + +func (rr *studyMaterialRepository) GetSubjectIDByName(name string) (uint, error) { + var studyMaterial schemas.StudyMaterial + res := rr.db.Where("name = ?", name).First(&studyMaterial) + if res.Error != nil { + return 0, res.Error + } + return studyMaterial.SubjectID, nil +} +func (rr *studyMaterialRepository) DeleteStudyMaterial(name string, subjectID uint, assetID uint) error { + err := rr.db.Unscoped().Where("id = ?", subjectID).Delete(&schemas.Subject{}).Error + if err != nil { + return err + } + err = rr.db.Unscoped().Where("id = ?", assetID).Delete(&schemas.Asset{}).Error + if err != nil { + return err + } + return rr.db.Unscoped().Where("name = ?", name).Delete(&schemas.StudyMaterial{}).Error +} + +func (rr *studyMaterialRepository) GetSubjectID(name string) (uint, error) { + var subject schemas.Subject + res := rr.db.Where("subject_code = ?", name).First(&subject) + if res.Error != nil { + return 0, res.Error + } + return subject.ID, nil +} + +func (rr *studyMaterialRepository) GetSubjectCategoryID(name string) (uint, error) { + var subjectCategory schemas.SubjectCategory + res := rr.db.Where("name = ?", name).First(&subjectCategory) + if res.Error != nil { + return 0, res.Error + } + return subjectCategory.ID, nil +} + +func (rr *studyMaterialRepository) GetAssetIDByName(name string) (uint, error) { + var studyMaterial schemas.StudyMaterial + res := rr.db.Where("name = ?", name).First(&studyMaterial) + if res.Error != nil { + return 0, res.Error + } + return studyMaterial.AssetID, nil +} + +func (rr *studyMaterialRepository) InsertAsset(name string) (uint, error) { + var assetType schemas.AssetType + if err := rr.db.Where("name = ?", schemas.Document).First(&assetType).Error; err != nil { + return 0, err + } + asset := schemas.Asset{ + Name: name, + AssetTypeID: assetType.ID, + } + if err := rr.db.Create(&asset).Error; err != nil { + return 0, err + } + return asset.ID, nil +} + +func (rr *studyMaterialRepository) FindStudyMaterialByName(name string) (models.StudyMaterials, error) { + /* + var studyMaterial schemas.StudyMaterial + + err := rr.db.Preload(clause.Associations).Where("name = ?", name).First(&studyMaterial).Error + return studyMaterial, err + */ + var studyMaterials models.StudyMaterials + err := rr.db.Table("study_materials").Select( + `study_materials.name as name,subjects.name as subject,subjects.subject_code as subject_code,CONCAT(?::text,'/static/documents','/',assets.name) as document_url`, config.Origin, + ).Joins( + "JOIN assets on assets.id = study_materials.asset_id").Joins( + "JOIN subjects on subjects.id = study_materials.subject_id").Where( + "study_materials.name = ?", name).First( + &studyMaterials).Error + if err != nil { + return models.StudyMaterials{}, err + } + return studyMaterials, nil +} + +func (rr *studyMaterialRepository) UpdateStudyMaterial(studyMaterial *schemas.StudyMaterial) error { + return rr.db.Model(&studyMaterial).Where("id = ?", studyMaterial.ID).Updates(&studyMaterial).Error +} + +func (rr *studyMaterialRepository) GetCategoryStudyMaterials(name string) ([]models.StudyMaterials, error) { + var studyMaterials []models.StudyMaterials + if err := rr.db.Table("study_materials").Select( + `study_materials.name as name,subjects.name as subject,subject_categories.name as subject_category,subjects.subject_code as subject_code, CONCAT(?::text,'/static/documents','/',assets.name) as document_url`, config.Origin, + ).Joins( + "JOIN assets on assets.id = study_materials.asset_id").Joins( + "JOIN subjects on subjects.id = study_materials.subject_id").Joins("JOIN subject_categories on subject_categories.id = subjects.subject_category_id").Where("subject_categories.name = ?", name).Scan( + &studyMaterials).Error; err != nil { + return nil, err + } + + return studyMaterials, nil +} + +func (rr *studyMaterialRepository) UpdateAsset(id uint, name string) error { + return rr.db.Model(&schemas.Asset{}).Where("id = ?", id).Update("name", name).Error +} + +func (rr *studyMaterialRepository) CreateSubjectAndReturnID(studyMaterialDetails models.StudyMaterialRequest, id uint) (uint, error) { + subject := schemas.Subject{ + Name: studyMaterialDetails.Subject, + SubjectCategoryID: id, + SubjectCode: studyMaterialDetails.SubjectCode, + } + res := rr.db.Create(&subject) + if res.Error != nil { + return 0, res.Error + } + return subject.ID, nil +} + +func (rr *studyMaterialRepository) GetSubjectCategory(subject string) (string, error) { + var category string + if err := rr.db.Table("subject_categories").Select( + `subject_categories.name`, + ).Joins( + "JOIN subjects on subjects.subject_category_id = subject_categories.id").Where("subjects.name = ?", subject).Scan( + &category).Error; err != nil { + return "", err + } + return category, nil +} + +func (rr *studyMaterialRepository) FindStudyMaterialByNameReturnSchema(name string) (schemas.StudyMaterial, error) { + var studyMaterial schemas.StudyMaterial + + err := rr.db.Preload(clause.Associations).Where("name = ?", name).First(&studyMaterial).Error + return studyMaterial, err +} diff --git a/repositories/user_repository.go b/repositories/user_repository.go index 6a25cf6..d0fc51d 100644 --- a/repositories/user_repository.go +++ b/repositories/user_repository.go @@ -38,7 +38,7 @@ func (ur *userRepository) UpdateVerification(code string) error { return res.Error } if res.RowsAffected == 0 { - err = fmt.Errorf(" No Matching User Found") + err = fmt.Errorf("No Matching User Found") } return err } From 4bc70da903abfbe2bc0ce2cbb72e8f7ba6d97ac8 Mon Sep 17 00:00:00 2001 From: rspk2207 <83638002+rspk2207@users.noreply.github.com> Date: Fri, 20 Jan 2023 23:22:13 +0530 Subject: [PATCH 06/21] Add files via upload --- helpers/resource.go | 166 ++++++++++++++++++++++---------------------- schemas/resource.go | 50 ++++++------- utils/document.go | 102 +++++++++++++-------------- utils/validator.go | 2 +- 4 files changed, 160 insertions(+), 160 deletions(-) diff --git a/helpers/resource.go b/helpers/resource.go index 0fcedd9..c51dca5 100644 --- a/helpers/resource.go +++ b/helpers/resource.go @@ -1,83 +1,83 @@ -package helpers - -import ( - "log" - "mime/multipart" - - "github.com/ecea-nitt/ecea-server/models" - "github.com/ecea-nitt/ecea-server/repositories" - "github.com/ecea-nitt/ecea-server/utils" -) - -func FetchSubjectID(channel chan int, studyMaterialDetails models.StudyMaterialRequest, id int, repo repositories.StudyMaterialRepository) { - subID, err := repo.GetSubjectID(studyMaterialDetails.SubjectCode) - if err != nil { - subID, err = repo.CreateSubjectAndReturnID(studyMaterialDetails, uint(id)) - if err != nil { - log.Println(err) - channel <- -1 - return - } - channel <- int(subID) - return - } - channel <- int(subID) - -} - -func FetchSubjectCategoryID(channel chan int, subjectCategory string, repo repositories.StudyMaterialRepository) { - id, err := repo.GetSubjectCategoryID(subjectCategory) - if err != nil { - log.Println("hehehaha") - channel <- -1 - return - } - channel <- int(id) - -} - -func UploadFileAndFetchAssetID(channel chan int, file *multipart.FileHeader, repo repositories.StudyMaterialRepository) { - - fileName, err := utils.UploadDocument(file) - if err != nil { - log.Println(err) - channel <- -1 - return - } - id, err := repo.InsertAsset(fileName) - if err != nil { - log.Println(err) - channel <- -1 - return - } - channel <- int(id) -} - -func UpdateFileAndFetchAssetID(dbID uint, dbName string, document *multipart.FileHeader, repo repositories.StudyMaterialRepository) int { - - if dbName == document.Filename { - return int(dbID) - } - - err := utils.DeleteDocument(dbName) - - if err != nil { - log.Println(err) - return -1 - } - - fileName, err := utils.UploadDocument(document) - if err != nil { - log.Println(err) - return -1 - } - - err = repo.UpdateAsset(dbID, fileName) - - if err != nil { - log.Println(err) - return -1 - } - - return int(dbID) -} +package helpers + +import ( + "log" + "mime/multipart" + + "github.com/ecea-nitt/ecea-server/models" + "github.com/ecea-nitt/ecea-server/repositories" + "github.com/ecea-nitt/ecea-server/utils" +) + +func FetchSubjectID(channel chan int, studyMaterialDetails models.StudyMaterialRequest, id int, repo repositories.StudyMaterialRepository) { + subID, err := repo.GetSubjectID(studyMaterialDetails.SubjectCode) + if err != nil { + subID, err = repo.CreateSubjectAndReturnID(studyMaterialDetails, uint(id)) + if err != nil { + log.Println(err) + channel <- -1 + return + } + channel <- int(subID) + return + } + channel <- int(subID) + +} + +func FetchSubjectCategoryID(channel chan int, subjectCategory string, repo repositories.StudyMaterialRepository) { + id, err := repo.GetSubjectCategoryID(subjectCategory) + if err != nil { + log.Println("hehehaha") + channel <- -1 + return + } + channel <- int(id) + +} + +func UploadFileAndFetchAssetID(channel chan int, file *multipart.FileHeader, repo repositories.StudyMaterialRepository) { + + fileName, err := utils.UploadDocument(file) + if err != nil { + log.Println(err) + channel <- -1 + return + } + id, err := repo.InsertAsset(fileName) + if err != nil { + log.Println(err) + channel <- -1 + return + } + channel <- int(id) +} + +func UpdateFileAndFetchAssetID(dbID uint, dbName string, document *multipart.FileHeader, repo repositories.StudyMaterialRepository) int { + + if dbName == document.Filename { + return int(dbID) + } + + err := utils.DeleteDocument(dbName) + + if err != nil { + log.Println(err) + return -1 + } + + fileName, err := utils.UploadDocument(document) + if err != nil { + log.Println(err) + return -1 + } + + err = repo.UpdateAsset(dbID, fileName) + + if err != nil { + log.Println(err) + return -1 + } + + return int(dbID) +} diff --git a/schemas/resource.go b/schemas/resource.go index 56e976e..aef7d2a 100644 --- a/schemas/resource.go +++ b/schemas/resource.go @@ -1,25 +1,25 @@ -package schemas - -import "gorm.io/gorm" - -type StudyMaterial struct { - gorm.Model - Name string `gorm:"not null; unique"` - AssetID uint `gorm:"default: null"` - Asset Asset `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` - SubjectID uint `gorm:"default: null"` - Subject Subject `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` -} - -type Subject struct { - gorm.Model - SubjectCode string `gorm:"not null; unique"` - Name string `gorm:"not null"` - SubjectCategoryID uint `gorm:"default: null"` - SubjectCategory SubjectCategory `gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"` -} - -type SubjectCategory struct { - gorm.Model - Name string `gorm:"not null; unique"` -} +package schemas + +import "gorm.io/gorm" + +type StudyMaterial struct { + gorm.Model + Name string `gorm:"not null; unique"` + AssetID uint `gorm:"default: null"` + Asset Asset `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` + SubjectID uint `gorm:"default: null"` + Subject Subject `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` +} + +type Subject struct { + gorm.Model + SubjectCode string `gorm:"not null; unique"` + Name string `gorm:"not null"` + SubjectCategoryID uint `gorm:"default: null"` + SubjectCategory SubjectCategory `gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"` +} + +type SubjectCategory struct { + gorm.Model + Name string `gorm:"not null; unique"` +} diff --git a/utils/document.go b/utils/document.go index 74704b1..cec54ba 100644 --- a/utils/document.go +++ b/utils/document.go @@ -1,51 +1,51 @@ -package utils - -import ( - "io" - "log" - "mime/multipart" - "os" - "time" - - "github.com/fatih/color" -) - -var DocumentPath = "static/documents/" - -func UploadDocument(file *multipart.FileHeader) (string, error) { - - src, err := file.Open() - if err != nil { - return "", err - } - defer src.Close() - - // Destination - timeStamp := time.Now() - - if _, err := os.Stat(DocumentPath); os.IsNotExist(err) { - _ = os.Mkdir(DocumentPath, 0777) - } - fileName := timeStamp.Format(time.RFC3339) + ".pdf" - path := DocumentPath + fileName - dst, err := os.Create(path) - if err != nil { - return "", err - } - defer dst.Close() - // Copy - if _, err = io.Copy(dst, src); err != nil { - return "", err - } - return fileName, nil -} - -func DeleteDocument(fileName string) error { - path := DocumentPath + fileName - log.Println(color.MagentaString("Deleting: " + path)) - e := os.Remove(path) - if e != nil { - return e - } - return nil -} +package utils + +import ( + "io" + "log" + "mime/multipart" + "os" + "time" + + "github.com/fatih/color" +) + +var DocumentPath = "static/documents/" + +func UploadDocument(file *multipart.FileHeader) (string, error) { + + src, err := file.Open() + if err != nil { + return "", err + } + defer src.Close() + + // Destination + timeStamp := time.Now() + + if _, err := os.Stat(DocumentPath); os.IsNotExist(err) { + _ = os.Mkdir(DocumentPath, 0777) + } + fileName := timeStamp.Format(time.RFC3339) + ".pdf" + path := DocumentPath + fileName + dst, err := os.Create(path) + if err != nil { + return "", err + } + defer dst.Close() + // Copy + if _, err = io.Copy(dst, src); err != nil { + return "", err + } + return fileName, nil +} + +func DeleteDocument(fileName string) error { + path := DocumentPath + fileName + log.Println(color.MagentaString("Deleting: " + path)) + e := os.Remove(path) + if e != nil { + return e + } + return nil +} diff --git a/utils/validator.go b/utils/validator.go index b1d990b..5941c78 100644 --- a/utils/validator.go +++ b/utils/validator.go @@ -17,7 +17,7 @@ import ( func NameValidator(s string) (string, error) { var IsLetter = regexp.MustCompile(`^[a-zA-Z ]+$`).MatchString if !IsLetter(s) { - return s, fmt.Errorf(" Name should only contain characters") + return s, fmt.Errorf("Name should only contain characters") } name := cases.Lower(language.Und).String(s) name = cases.Title(language.Und).String(name) From a5ef490ee9d602c6719e1027f8cc41a859f9678b Mon Sep 17 00:00:00 2001 From: rspk2207 <83638002+rspk2207@users.noreply.github.com> Date: Fri, 20 Jan 2023 23:26:49 +0530 Subject: [PATCH 07/21] Add files via upload --- controllers/resource_controller.go | 452 ++++++++++++++--------------- registry/resource_registry.go | 38 +-- services/resource_service.go | 256 ++++++++-------- 3 files changed, 373 insertions(+), 373 deletions(-) diff --git a/controllers/resource_controller.go b/controllers/resource_controller.go index b09c459..4051b24 100644 --- a/controllers/resource_controller.go +++ b/controllers/resource_controller.go @@ -1,226 +1,226 @@ -package controllers - -import ( - "log" - "net/http" - - "github.com/ecea-nitt/ecea-server/middlewares" - "github.com/ecea-nitt/ecea-server/models" - "github.com/ecea-nitt/ecea-server/services" - "github.com/fatih/color" - "github.com/labstack/echo/v4" -) - -type studyMaterialController struct { - rs services.StudyMaterialService -} - -type StudyMaterialController interface { - AddStudyMaterial(c echo.Context) error - GetCategoryStudyMaterials(c echo.Context) error - GetStudyMaterial(c echo.Context) error - UpdateStudyMaterialSubject(c echo.Context) error - UpdateStudyMaterialURL(c echo.Context) error - DeleteStudyMaterial(c echo.Context) error -} - -func NewStudyMaterialController(rs services.StudyMaterialService) StudyMaterialController { - return &studyMaterialController{rs} -} - -// AddStudyMaterial godoc -// -// @Summary Add a study material -// @Description Creates a new study material and adds to Database -// @Tags StudyMaterial -// @Accept multipart/form-data -// @Produce json -// @Param name formData string true "Enter material name" -// @Param subject formData string true "Enter subject name" -// @Param code formData string true "Enter subject code" -// @Param category formData models.SubjectCategory true "Choose a category" -// @Param document formData file true "Upload Document" -// @Success 200 {object} string -// @Failure 400 {object} models.Error -// -// @Security ApiKeyAuth -// @Router /v1/studymaterial/add [post] -func (rc *studyMaterialController) AddStudyMaterial(c echo.Context) error { - request := new(models.StudyMaterialRequest) - if err := c.Bind(request); err != nil { - log.Println(err) - return err - } - file, err := c.FormFile("document") - if err != nil { - log.Println(err) - return err - } - log.Println(request) - err = rc.rs.CreateNewStudyMaterial(*request, file) - if err != nil { - log.Println(err) - return middlewares.Responder(c, http.StatusConflict, "Conflict") - } - return middlewares.Responder(c, http.StatusOK, "Success") -} - -// GetStudyMaterial godoc -// -// @Summary Get a study material -// @Description Fetches a study material and removes form database -// @Tags StudyMaterial -// @Accept json -// @Produce json -// @Param name path string true "Get study material" -// @Success 200 {object} models.StudyMaterials -// @Failure 400 {object} models.Error -// -// @Security ApiKeyAuth -// @Router /v1/studymaterial/get/{name} [get] -func (rc *studyMaterialController) GetStudyMaterial(c echo.Context) error { - rname := c.Param("name") - res, err := rc.rs.GetStudyMaterial(rname) - if err != nil { - log.Println(color.RedString(err.Error())) - return middlewares.Responder(c, http.StatusConflict, "Error Occurred") - } - - return middlewares.Responder(c, http.StatusOK, &res) -} - -// GetCategoryStudyMaterials godoc -// -// @Summary Get study materials from a category -// @Description Fetches all study materials belonging to a category from Database -// @Tags StudyMaterial -// @Accept json -// @Produce json -// @Param category path models.SubjectCategory true "Get study material from category" -// @Success 200 {object} []models.StudyMaterials -// @Failure 400 {object} models.Error -// -// @Security ApiKeyAuth -// @Router /v1/studymaterial/getcat/{category} [get] -func (rc *studyMaterialController) GetCategoryStudyMaterials(c echo.Context) error { - /* - request := new(models.StudyMaterialRequest) - if err := c.Bind(request); err != nil { - return err - } - */ - res, err := rc.rs.GetCategoryStudyMaterials(c.Param("category")) - log.Println(c.Param("category")) - if err != nil { - log.Println(color.RedString(err.Error())) - return middlewares.Responder(c, http.StatusConflict, "Conflict") - } - return middlewares.Responder(c, http.StatusOK, res) -} - -// UpdateStudyMaterialSubject godoc -// -// @Summary Updates a studymaterial's subject name -// @Description Updates a subject name and updates to Database -// @Tags StudyMaterial -// @Accept multipart/form-data -// @Produce json -// @Param subject formData string true "Edit name" -// @Param subjectCode formData string true "Enter subject code" -// @Success 200 {object} string -// @Failure 400 {object} models.Error -// -// @Security ApiKeyAuth -// @Router /v1/studymaterial/edit/subject [put] -func (rc *studyMaterialController) UpdateStudyMaterialSubject(c echo.Context) error { - - request := new(models.StudyMaterialRequest) - if err := c.Bind(request); err != nil { - log.Println(err) - return middlewares.Responder(c, http.StatusBadRequest, "Bad Request") - } - /* - subject := c.Param("subject") - subjectCode := c.Param("subjectCode") - if err := c.Bind(request); err != nil { - log.Println(err) - return middlewares.Responder(c, http.StatusBadRequest, "Bad Request") - } - */ - log.Println(request.Subject, request.SubjectCode) - err := rc.rs.EditStudyMaterialSubject(request.Subject, request.SubjectCode) - if err != nil { - log.Println(color.RedString(err.Error())) - return middlewares.Responder(c, http.StatusConflict, err) - } - return middlewares.Responder(c, http.StatusOK, "Success") -} - -// UpdateStudyMaterialURL godoc -// -// @Summary Update a study material's document -// @Description Update a document and update it on Database -// @Tags StudyMaterial -// @Accept multipart/form-data -// @Produce json -// @Param name formData string true "Enter the name of material" -// @Param document formData file true "Edit Document" -// @Success 200 {object} string -// @Failure 400 {object} models.Error -// -// @Security ApiKeyAuth -// @Router /v1/studymaterial/edit/document [put] -func (rc *studyMaterialController) UpdateStudyMaterialURL(c echo.Context) error { - - request := new(models.StudyMaterialRequest) - if err := c.Bind(request); err != nil { - log.Println(err) - return middlewares.Responder(c, http.StatusBadRequest, "Bad Request") - } - /* - name := c.Param("name") - request := new(models.StudyMaterialRequest) - if err := c.Bind(request); err != nil { - log.Println(err) - return middlewares.Responder(c, http.StatusBadRequest, "Bad Request") - } - */ - file, err := c.FormFile("document") - if err != nil { - log.Println(err) - return err - } - - err = rc.rs.EditStudyMaterialURL(request.Name, file) - if err != nil { - log.Println(color.RedString(err.Error())) - return middlewares.Responder(c, http.StatusConflict, err) - } - return middlewares.Responder(c, http.StatusOK, "Success") -} - -// DeleteStudyMaterial godoc -// -// @Summary Deletes a study material -// @Description Deletes a study material along with its document and remove form Database -// @Tags StudyMaterial -// @Accept json -// @Produce json -// @Param name path string true "Delete study material" -// @Success 200 {object} string -// @Failure 400 {object} models.Error -// -// @Security ApiKeyAuth -// @Router /v1/studymaterial/delete/{name} [delete] -func (rc *studyMaterialController) DeleteStudyMaterial(c echo.Context) error { - rname := c.Param("name") - - err := rc.rs.RemoveStudyMaterial(rname) - log.Println(rname) - if err != nil { - log.Println(color.RedString(err.Error())) - return middlewares.Responder(c, http.StatusConflict, "Error Occurred") - } - - return middlewares.Responder(c, http.StatusOK, "Success") -} +package controllers + +import ( + "log" + "net/http" + + "github.com/ecea-nitt/ecea-server/middlewares" + "github.com/ecea-nitt/ecea-server/models" + "github.com/ecea-nitt/ecea-server/services" + "github.com/fatih/color" + "github.com/labstack/echo/v4" +) + +type studyMaterialController struct { + rs services.StudyMaterialService +} + +type StudyMaterialController interface { + AddStudyMaterial(c echo.Context) error + GetCategoryStudyMaterials(c echo.Context) error + GetStudyMaterial(c echo.Context) error + UpdateStudyMaterialSubject(c echo.Context) error + UpdateStudyMaterialURL(c echo.Context) error + DeleteStudyMaterial(c echo.Context) error +} + +func NewStudyMaterialController(rs services.StudyMaterialService) StudyMaterialController { + return &studyMaterialController{rs} +} + +// AddStudyMaterial godoc +// +// @Summary Add a study material +// @Description Creates a new study material and adds to Database +// @Tags StudyMaterial +// @Accept multipart/form-data +// @Produce json +// @Param name formData string true "Enter material name" +// @Param subject formData string true "Enter subject name" +// @Param code formData string true "Enter subject code" +// @Param category formData models.SubjectCategory true "Choose a category" +// @Param document formData file true "Upload Document" +// @Success 200 {object} string +// @Failure 400 {object} models.Error +// +// @Security ApiKeyAuth +// @Router /v1/studymaterial/add [post] +func (rc *studyMaterialController) AddStudyMaterial(c echo.Context) error { + request := new(models.StudyMaterialRequest) + if err := c.Bind(request); err != nil { + log.Println(err) + return err + } + file, err := c.FormFile("document") + if err != nil { + log.Println(err) + return err + } + log.Println(request) + err = rc.rs.CreateNewStudyMaterial(*request, file) + if err != nil { + log.Println(err) + return middlewares.Responder(c, http.StatusConflict, "Conflict") + } + return middlewares.Responder(c, http.StatusOK, "Success") +} + +// GetStudyMaterial godoc +// +// @Summary Get a study material +// @Description Fetches a study material and removes form database +// @Tags StudyMaterial +// @Accept json +// @Produce json +// @Param name path string true "Get study material" +// @Success 200 {object} models.StudyMaterials +// @Failure 400 {object} models.Error +// +// @Security ApiKeyAuth +// @Router /v1/studymaterial/get/{name} [get] +func (rc *studyMaterialController) GetStudyMaterial(c echo.Context) error { + rname := c.Param("name") + res, err := rc.rs.GetStudyMaterial(rname) + if err != nil { + log.Println(color.RedString(err.Error())) + return middlewares.Responder(c, http.StatusConflict, "Error Occurred") + } + + return middlewares.Responder(c, http.StatusOK, &res) +} + +// GetCategoryStudyMaterials godoc +// +// @Summary Get study materials from a category +// @Description Fetches all study materials belonging to a category from Database +// @Tags StudyMaterial +// @Accept json +// @Produce json +// @Param category path models.SubjectCategory true "Get study material from category" +// @Success 200 {object} []models.StudyMaterials +// @Failure 400 {object} models.Error +// +// @Security ApiKeyAuth +// @Router /v1/studymaterial/getcat/{category} [get] +func (rc *studyMaterialController) GetCategoryStudyMaterials(c echo.Context) error { + /* + request := new(models.StudyMaterialRequest) + if err := c.Bind(request); err != nil { + return err + } + */ + res, err := rc.rs.GetCategoryStudyMaterials(c.Param("category")) + log.Println(c.Param("category")) + if err != nil { + log.Println(color.RedString(err.Error())) + return middlewares.Responder(c, http.StatusConflict, "Conflict") + } + return middlewares.Responder(c, http.StatusOK, res) +} + +// UpdateStudyMaterialSubject godoc +// +// @Summary Updates a studymaterial's subject name +// @Description Updates a subject name and updates to Database +// @Tags StudyMaterial +// @Accept multipart/form-data +// @Produce json +// @Param subject formData string true "Edit name" +// @Param subjectCode formData string true "Enter subject code" +// @Success 200 {object} string +// @Failure 400 {object} models.Error +// +// @Security ApiKeyAuth +// @Router /v1/studymaterial/edit/subject [put] +func (rc *studyMaterialController) UpdateStudyMaterialSubject(c echo.Context) error { + + request := new(models.StudyMaterialRequest) + if err := c.Bind(request); err != nil { + log.Println(err) + return middlewares.Responder(c, http.StatusBadRequest, "Bad Request") + } + /* + subject := c.Param("subject") + subjectCode := c.Param("subjectCode") + if err := c.Bind(request); err != nil { + log.Println(err) + return middlewares.Responder(c, http.StatusBadRequest, "Bad Request") + } + */ + log.Println(request.Subject, request.SubjectCode) + err := rc.rs.EditStudyMaterialSubject(request.Subject, request.SubjectCode) + if err != nil { + log.Println(color.RedString(err.Error())) + return middlewares.Responder(c, http.StatusConflict, err) + } + return middlewares.Responder(c, http.StatusOK, "Success") +} + +// UpdateStudyMaterialURL godoc +// +// @Summary Update a study material's document +// @Description Update a document and update it on Database +// @Tags StudyMaterial +// @Accept multipart/form-data +// @Produce json +// @Param name formData string true "Enter the name of material" +// @Param document formData file true "Edit Document" +// @Success 200 {object} string +// @Failure 400 {object} models.Error +// +// @Security ApiKeyAuth +// @Router /v1/studymaterial/edit/document [put] +func (rc *studyMaterialController) UpdateStudyMaterialURL(c echo.Context) error { + + request := new(models.StudyMaterialRequest) + if err := c.Bind(request); err != nil { + log.Println(err) + return middlewares.Responder(c, http.StatusBadRequest, "Bad Request") + } + /* + name := c.Param("name") + request := new(models.StudyMaterialRequest) + if err := c.Bind(request); err != nil { + log.Println(err) + return middlewares.Responder(c, http.StatusBadRequest, "Bad Request") + } + */ + file, err := c.FormFile("document") + if err != nil { + log.Println(err) + return err + } + + err = rc.rs.EditStudyMaterialURL(request.Name, file) + if err != nil { + log.Println(color.RedString(err.Error())) + return middlewares.Responder(c, http.StatusConflict, err) + } + return middlewares.Responder(c, http.StatusOK, "Success") +} + +// DeleteStudyMaterial godoc +// +// @Summary Deletes a study material +// @Description Deletes a study material along with its document and remove form Database +// @Tags StudyMaterial +// @Accept json +// @Produce json +// @Param name path string true "Delete study material" +// @Success 200 {object} string +// @Failure 400 {object} models.Error +// +// @Security ApiKeyAuth +// @Router /v1/studymaterial/delete/{name} [delete] +func (rc *studyMaterialController) DeleteStudyMaterial(c echo.Context) error { + rname := c.Param("name") + + err := rc.rs.RemoveStudyMaterial(rname) + log.Println(rname) + if err != nil { + log.Println(color.RedString(err.Error())) + return middlewares.Responder(c, http.StatusConflict, "Error Occurred") + } + + return middlewares.Responder(c, http.StatusOK, "Success") +} diff --git a/registry/resource_registry.go b/registry/resource_registry.go index 8e9324e..3dc3b73 100644 --- a/registry/resource_registry.go +++ b/registry/resource_registry.go @@ -1,19 +1,19 @@ -package registry - -import ( - "github.com/ecea-nitt/ecea-server/controllers" - "github.com/ecea-nitt/ecea-server/repositories" - "github.com/ecea-nitt/ecea-server/services" -) - -func (r *registry) NewStudyMaterialController() controllers.StudyMaterialController { - return controllers.NewStudyMaterialController(r.NewStudyMaterialService()) -} - -func (r *registry) NewStudyMaterialService() services.StudyMaterialService { - return services.NewStudyMaterialService(r.NewStudyMaterialRepository()) -} - -func (r *registry) NewStudyMaterialRepository() repositories.StudyMaterialRepository { - return repositories.NewStudyMaterialRepository(r.db) -} +package registry + +import ( + "github.com/ecea-nitt/ecea-server/controllers" + "github.com/ecea-nitt/ecea-server/repositories" + "github.com/ecea-nitt/ecea-server/services" +) + +func (r *registry) NewStudyMaterialController() controllers.StudyMaterialController { + return controllers.NewStudyMaterialController(r.NewStudyMaterialService()) +} + +func (r *registry) NewStudyMaterialService() services.StudyMaterialService { + return services.NewStudyMaterialService(r.NewStudyMaterialRepository()) +} + +func (r *registry) NewStudyMaterialRepository() repositories.StudyMaterialRepository { + return repositories.NewStudyMaterialRepository(r.db) +} diff --git a/services/resource_service.go b/services/resource_service.go index 888dce3..67620c2 100644 --- a/services/resource_service.go +++ b/services/resource_service.go @@ -1,128 +1,128 @@ -package services - -import ( - "errors" - "log" - "mime/multipart" - - "github.com/ecea-nitt/ecea-server/helpers" - "github.com/ecea-nitt/ecea-server/models" - "github.com/ecea-nitt/ecea-server/repositories" - "github.com/ecea-nitt/ecea-server/schemas" -) - -type studyMaterialService struct { - repo repositories.StudyMaterialRepository -} - -type StudyMaterialService interface { - CreateNewStudyMaterial(studyMaterialDetails models.StudyMaterialRequest, studyMaterialFile *multipart.FileHeader) error - EditStudyMaterialSubject(subject string, code string) error - EditStudyMaterialURL(name string, file *multipart.FileHeader) error - GetStudyMaterial(name string) (models.StudyMaterials, error) - GetCategoryStudyMaterials(name string) ([]models.StudyMaterials, error) - RemoveStudyMaterial(name string) error -} - -func NewStudyMaterialService(repo repositories.StudyMaterialRepository) StudyMaterialService { - return &studyMaterialService{repo} -} - -func (rs *studyMaterialService) CreateNewStudyMaterial(studyMaterialDetails models.StudyMaterialRequest, studyMaterialFile *multipart.FileHeader) error { - assetChannel := make(chan int) - subjectChannel := make(chan int) - subjectCategoryChannel := make(chan int) - /* - subjectCategoryID, err := rs.repo.GetSubjectCategoryID(studyMaterialDetails.SubjectCategory) - if err != nil { - return err - } - */ - go helpers.FetchSubjectCategoryID(subjectCategoryChannel, studyMaterialDetails.SubjectCategory, rs.repo) - subjectCategoryID := <-subjectCategoryChannel - go helpers.FetchSubjectID(subjectChannel, studyMaterialDetails, subjectCategoryID, rs.repo) - go helpers.UploadFileAndFetchAssetID(assetChannel, studyMaterialFile, rs.repo) - subjectID := <-subjectChannel - assetID := <-assetChannel - if subjectID == -1 || assetID == -1 || subjectCategoryID == -1 { - return errors.New("could not fetch data") - } - studyMaterial := schemas.StudyMaterial{ - Name: studyMaterialDetails.Name, - SubjectID: uint(subjectID), - AssetID: uint(assetID), - } - log.Println(subjectCategoryID, studyMaterialDetails.SubjectCategory) - return rs.repo.CreateStudyMaterial(&studyMaterial) -} - -func (rs *studyMaterialService) EditStudyMaterialSubject(subject string, code string) error { - editrequest := schemas.Subject{ - Name: subject, - SubjectCode: code, - } - /* - subjectID, err := rs.repo.GetSubjectIDByCode(code) - if err != nil { - return err - } - */ - return rs.repo.UpdateStudyMaterialSubject(&editrequest, subject, code) -} - -func (rs *studyMaterialService) EditStudyMaterialURL(name string, file *multipart.FileHeader) error { - dbStudyMaterial, err := rs.repo.FindStudyMaterialByNameReturnSchema(name) - if err != nil { - return err - } - - assetID := helpers.UpdateFileAndFetchAssetID(dbStudyMaterial.AssetID, dbStudyMaterial.Asset.Name, file, rs.repo) - - if assetID == -1 { - return errors.New(" Error Occurred") - } - - studyMaterial := schemas.StudyMaterial{ - AssetID: uint(assetID), - } - studyMaterial.ID = dbStudyMaterial.ID - - return rs.repo.UpdateStudyMaterial(&studyMaterial) -} - -func (rs *studyMaterialService) RemoveStudyMaterial(name string) error { - subjectID, err1 := rs.repo.GetSubjectIDByName(name) - if err1 != nil { - return err1 - } - assetID, err2 := rs.repo.GetAssetIDByName(name) - if err2 != nil { - return err2 - } - return rs.repo.DeleteStudyMaterial(name, subjectID, assetID) -} - -func (rs *studyMaterialService) GetStudyMaterial(name string) (models.StudyMaterials, error) { - studyMaterial, err := rs.repo.FindStudyMaterialByName(name) - if err != nil { - return models.StudyMaterials{}, err - } - subjectCategory, err1 := rs.repo.GetSubjectCategory(studyMaterial.Subject) - if err1 != nil { - return models.StudyMaterials{}, err1 - } - result := models.StudyMaterials{ - Name: studyMaterial.Name, - Subject: studyMaterial.Subject, - SubjectCategory: subjectCategory, - SubjectCode: studyMaterial.SubjectCode, - DocumentURL: studyMaterial.DocumentURL, - } - log.Println(studyMaterial) - log.Println(result) - return result, err -} - -func (rs *studyMaterialService) GetCategoryStudyMaterials(name string) ([]models.StudyMaterials, error) { - return rs.repo.GetCategoryStudyMaterials(name) -} +package services + +import ( + "errors" + "log" + "mime/multipart" + + "github.com/ecea-nitt/ecea-server/helpers" + "github.com/ecea-nitt/ecea-server/models" + "github.com/ecea-nitt/ecea-server/repositories" + "github.com/ecea-nitt/ecea-server/schemas" +) + +type studyMaterialService struct { + repo repositories.StudyMaterialRepository +} + +type StudyMaterialService interface { + CreateNewStudyMaterial(studyMaterialDetails models.StudyMaterialRequest, studyMaterialFile *multipart.FileHeader) error + EditStudyMaterialSubject(subject string, code string) error + EditStudyMaterialURL(name string, file *multipart.FileHeader) error + GetStudyMaterial(name string) (models.StudyMaterials, error) + GetCategoryStudyMaterials(name string) ([]models.StudyMaterials, error) + RemoveStudyMaterial(name string) error +} + +func NewStudyMaterialService(repo repositories.StudyMaterialRepository) StudyMaterialService { + return &studyMaterialService{repo} +} + +func (rs *studyMaterialService) CreateNewStudyMaterial(studyMaterialDetails models.StudyMaterialRequest, studyMaterialFile *multipart.FileHeader) error { + assetChannel := make(chan int) + subjectChannel := make(chan int) + subjectCategoryChannel := make(chan int) + /* + subjectCategoryID, err := rs.repo.GetSubjectCategoryID(studyMaterialDetails.SubjectCategory) + if err != nil { + return err + } + */ + go helpers.FetchSubjectCategoryID(subjectCategoryChannel, studyMaterialDetails.SubjectCategory, rs.repo) + subjectCategoryID := <-subjectCategoryChannel + go helpers.FetchSubjectID(subjectChannel, studyMaterialDetails, subjectCategoryID, rs.repo) + go helpers.UploadFileAndFetchAssetID(assetChannel, studyMaterialFile, rs.repo) + subjectID := <-subjectChannel + assetID := <-assetChannel + if subjectID == -1 || assetID == -1 || subjectCategoryID == -1 { + return errors.New("could not fetch data") + } + studyMaterial := schemas.StudyMaterial{ + Name: studyMaterialDetails.Name, + SubjectID: uint(subjectID), + AssetID: uint(assetID), + } + log.Println(subjectCategoryID, studyMaterialDetails.SubjectCategory) + return rs.repo.CreateStudyMaterial(&studyMaterial) +} + +func (rs *studyMaterialService) EditStudyMaterialSubject(subject string, code string) error { + editrequest := schemas.Subject{ + Name: subject, + SubjectCode: code, + } + /* + subjectID, err := rs.repo.GetSubjectIDByCode(code) + if err != nil { + return err + } + */ + return rs.repo.UpdateStudyMaterialSubject(&editrequest, subject, code) +} + +func (rs *studyMaterialService) EditStudyMaterialURL(name string, file *multipart.FileHeader) error { + dbStudyMaterial, err := rs.repo.FindStudyMaterialByNameReturnSchema(name) + if err != nil { + return err + } + + assetID := helpers.UpdateFileAndFetchAssetID(dbStudyMaterial.AssetID, dbStudyMaterial.Asset.Name, file, rs.repo) + + if assetID == -1 { + return errors.New(" Error Occurred") + } + + studyMaterial := schemas.StudyMaterial{ + AssetID: uint(assetID), + } + studyMaterial.ID = dbStudyMaterial.ID + + return rs.repo.UpdateStudyMaterial(&studyMaterial) +} + +func (rs *studyMaterialService) RemoveStudyMaterial(name string) error { + subjectID, err1 := rs.repo.GetSubjectIDByName(name) + if err1 != nil { + return err1 + } + assetID, err2 := rs.repo.GetAssetIDByName(name) + if err2 != nil { + return err2 + } + return rs.repo.DeleteStudyMaterial(name, subjectID, assetID) +} + +func (rs *studyMaterialService) GetStudyMaterial(name string) (models.StudyMaterials, error) { + studyMaterial, err := rs.repo.FindStudyMaterialByName(name) + if err != nil { + return models.StudyMaterials{}, err + } + subjectCategory, err1 := rs.repo.GetSubjectCategory(studyMaterial.Subject) + if err1 != nil { + return models.StudyMaterials{}, err1 + } + result := models.StudyMaterials{ + Name: studyMaterial.Name, + Subject: studyMaterial.Subject, + SubjectCategory: subjectCategory, + SubjectCode: studyMaterial.SubjectCode, + DocumentURL: studyMaterial.DocumentURL, + } + log.Println(studyMaterial) + log.Println(result) + return result, err +} + +func (rs *studyMaterialService) GetCategoryStudyMaterials(name string) ([]models.StudyMaterials, error) { + return rs.repo.GetCategoryStudyMaterials(name) +} From 6441d6173f8eef17b96aeeaad2c5ab59a667676f Mon Sep 17 00:00:00 2001 From: rspk2207 <83638002+rspk2207@users.noreply.github.com> Date: Fri, 20 Jan 2023 23:29:23 +0530 Subject: [PATCH 08/21] Add files via upload --- router/resource.go | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/router/resource.go b/router/resource.go index 15d0db5..b8bbc8d 100644 --- a/router/resource.go +++ b/router/resource.go @@ -1,21 +1,21 @@ -package router - -import ( - "github.com/ecea-nitt/ecea-server/controllers" - "github.com/ecea-nitt/ecea-server/middlewares" - "github.com/labstack/echo/v4" -) - -func StudyMaterialRoutes(e *echo.Group, c controllers.StudyMaterialController) { - studyMaterial := e.Group("/studymaterial") - - studyMaterial.POST("/add", middlewares.Authorizer(c.AddStudyMaterial)) - studyMaterial.PUT("/edit/document", middlewares.Authorizer(c.UpdateStudyMaterialURL)) - // studyMaterial.PUT("/edit/name", middlewares.Authorizer(c.EditRessourceName)) - // studyMaterial.PUT("/edit/bookid", middlewares.Authorizer(c.EditMemberRole)) - studyMaterial.PUT("/edit/subject", middlewares.Authorizer(c.UpdateStudyMaterialSubject)) - studyMaterial.GET("/getcat/:category", c.GetCategoryStudyMaterials) - studyMaterial.GET("/get/:name", c.GetStudyMaterial) - studyMaterial.DELETE("/delete/:name", middlewares.Authorizer(c.DeleteStudyMaterial)) - -} +package router + +import ( + "github.com/ecea-nitt/ecea-server/controllers" + "github.com/ecea-nitt/ecea-server/middlewares" + "github.com/labstack/echo/v4" +) + +func StudyMaterialRoutes(e *echo.Group, c controllers.StudyMaterialController) { + studyMaterial := e.Group("/studymaterial") + + studyMaterial.POST("/add", middlewares.Authorizer(c.AddStudyMaterial)) + studyMaterial.PUT("/edit/document", middlewares.Authorizer(c.UpdateStudyMaterialURL)) + // studyMaterial.PUT("/edit/name", middlewares.Authorizer(c.EditRessourceName)) + // studyMaterial.PUT("/edit/bookid", middlewares.Authorizer(c.EditMemberRole)) + studyMaterial.PUT("/edit/subject", middlewares.Authorizer(c.UpdateStudyMaterialSubject)) + studyMaterial.GET("/getcat/:category", c.GetCategoryStudyMaterials) + studyMaterial.GET("/get/:name", c.GetStudyMaterial) + studyMaterial.DELETE("/delete/:name", middlewares.Authorizer(c.DeleteStudyMaterial)) + +} From c49f5eefe9729573a290e71d1c71bf922637711a Mon Sep 17 00:00:00 2001 From: RevanthSPK Date: Tue, 24 Jan 2023 22:14:07 +0530 Subject: [PATCH 09/21] feat(controller): added resource controller --- controllers/app_controller.go | 14 +- controllers/resource_controller.go | 278 +++++++++++++++++++++++++++++ controllers/team_controller.go | 2 + 3 files changed, 290 insertions(+), 4 deletions(-) create mode 100644 controllers/resource_controller.go diff --git a/controllers/app_controller.go b/controllers/app_controller.go index 2f99e31..312bce9 100644 --- a/controllers/app_controller.go +++ b/controllers/app_controller.go @@ -8,9 +8,10 @@ import ( ) type AppController struct { - User interface{ UserController } - Team interface{ TeamController } - Seed interface{ SeedController } + User interface{ UserController } + Team interface{ TeamController } + Seed interface{ SeedController } + StudyMaterial interface{ StudyMaterialController } } type seedController struct { @@ -41,6 +42,11 @@ func (s *seedController) SeedDB() error { log.Panic(err) return err } - log.Println(color.GreenString("Seeded Successfully")) + err = s.seed.StudyMaterialSeeder() + if err != nil { + log.Panic(err) + return err + } + log.Println(color.GreenString(" Seeded Successfully")) return nil } diff --git a/controllers/resource_controller.go b/controllers/resource_controller.go new file mode 100644 index 0000000..5afe519 --- /dev/null +++ b/controllers/resource_controller.go @@ -0,0 +1,278 @@ +package controllers + +import ( + "log" + "net/http" + + "github.com/ecea-nitt/ecea-server/middlewares" + "github.com/ecea-nitt/ecea-server/models" + "github.com/ecea-nitt/ecea-server/services" + "github.com/fatih/color" + "github.com/labstack/echo/v4" +) + +type studyMaterialController struct { + rs services.StudyMaterialService +} + +type StudyMaterialController interface { + AddStudyMaterial(c echo.Context) error + GetCategoryStudyMaterials(c echo.Context) error + GetAllMaterials(c echo.Context) error + GetStudyMaterial(c echo.Context) error + AddSubject(c echo.Context) error + // UpdateStudyMaterialSubject(c echo.Context) error + UpdateStudyMaterialURL(c echo.Context) error + DeleteStudyMaterial(c echo.Context) error +} + +func NewStudyMaterialController(rs services.StudyMaterialService) StudyMaterialController { + return &studyMaterialController{rs} +} + +// AddStudyMaterial godoc +// +// @Summary Add a study material +// @Description Creates a new study material and adds to Database +// @Tags StudyMaterial +// @Accept multipart/form-data +// @Produce json +// @Param name formData string true "Enter material name" +// @Param code formData string true "Enter subject code" +// @Param document formData file true "Upload Document" +// @Success 200 {object} string +// @Failure 400 {object} models.Error +// +// @Security ApiKeyAuth +// @Router /v1/studymaterial/addMaterial [post] +func (rc *studyMaterialController) AddStudyMaterial(c echo.Context) error { + request := new(models.StudyMaterialRequest) + if err := c.Bind(request); err != nil { + log.Println(err) + return err + } + file, err := c.FormFile("document") + if err != nil { + log.Println(err) + return err + } + log.Println(request) + err = rc.rs.CreateNewStudyMaterial(*request, file) + if err != nil { + log.Println(err) + return middlewares.Responder(c, http.StatusConflict, "Conflict") + } + return middlewares.Responder(c, http.StatusOK, "Success") +} + +// GetStudyMaterial godoc +// +// @Summary Get a study material +// @Description Fetches a study material and removes form database +// @Tags StudyMaterial +// @Accept json +// @Produce json +// @Param name path string true "Get study material" +// @Success 200 {object} models.StudyMaterials +// @Failure 400 {object} models.Error +// +// @Security ApiKeyAuth +// @Router /v1/studymaterial/get/{name} [get] +func (rc *studyMaterialController) GetStudyMaterial(c echo.Context) error { + rname := c.Param("name") + res, err := rc.rs.GetStudyMaterial(rname) + if err != nil { + log.Println(color.RedString(err.Error())) + return middlewares.Responder(c, http.StatusConflict, "Error Occurred") + } + + return middlewares.Responder(c, http.StatusOK, &res) +} + +// GetCategoryStudyMaterials godoc +// +// @Summary Get study materials from a category +// @Description Fetches all study materials belonging to a category from Database +// @Tags StudyMaterial +// @Accept json +// @Produce json +// @Param category path models.SubjectCategory true "Get study material from category" +// @Success 200 {object} []models.StudyMaterials +// @Failure 400 {object} models.Error +// +// @Security ApiKeyAuth +// @Router /v1/studymaterial/getcat/{category} [get] +func (rc *studyMaterialController) GetCategoryStudyMaterials(c echo.Context) error { + /* + request := new(models.StudyMaterialRequest) + if err := c.Bind(request); err != nil { + return err + } + */ + res, err := rc.rs.GetCategoryStudyMaterials(c.Param("category")) + log.Println(c.Param("category")) + if err != nil { + log.Println(color.RedString(err.Error())) + return middlewares.Responder(c, http.StatusConflict, "Conflict") + } + return middlewares.Responder(c, http.StatusOK, res) +} + +// UpdateStudyMaterialSubject godoc +// +// @Summary Updates a studymaterial's subject name +// @Description Updates a subject name and updates to Database +// @Tags StudyMaterial +// @Accept multipart/form-data +// @Produce json +// @Param subject formData string true "Edit name" +// @Param subjectCode formData string true "Enter subject code" +// @Success 200 {object} string +// @Failure 400 {object} models.Error +// +// @Security ApiKeyAuth +// @Router /v1/studymaterial/edit/subject [put] + +/* +func (rc *studyMaterialController) UpdateStudyMaterialSubject(c echo.Context) error { + + request := new(models.StudyMaterialRequest) + if err := c.Bind(request); err != nil { + log.Println(err) + return middlewares.Responder(c, http.StatusBadRequest, "Bad Request") + } + subject := c.Param("subject") + subjectCode := c.Param("subjectCode") + if err := c.Bind(request); err != nil { + log.Println(err) + return middlewares.Responder(c, http.StatusBadRequest, "Bad Request") + } + + log.Println(request.Subject, request.SubjectCode) + err := rc.rs.EditStudyMaterialSubject(request.Subject, request.SubjectCode) + if err != nil { + log.Println(color.RedString(err.Error())) + return middlewares.Responder(c, http.StatusConflict, err) + } + return middlewares.Responder(c, http.StatusOK, "Success") +} +*/ + +// UpdateStudyMaterialURL godoc +// +// @Summary Update a study material's document +// @Description Update a document and update it on Database +// @Tags StudyMaterial +// @Accept multipart/form-data +// @Produce json +// @Param name formData string true "Enter the name of material" +// @Param document formData file true "Edit Document" +// @Success 200 {object} string +// @Failure 400 {object} models.Error +// +// @Security ApiKeyAuth +// @Router /v1/studymaterial/edit/document [put] +func (rc *studyMaterialController) UpdateStudyMaterialURL(c echo.Context) error { + + request := new(models.StudyMaterialRequest) + if err := c.Bind(request); err != nil { + log.Println(err) + return middlewares.Responder(c, http.StatusBadRequest, "Bad Request") + } + /* + name := c.Param("name") + request := new(models.StudyMaterialRequest) + if err := c.Bind(request); err != nil { + log.Println(err) + return middlewares.Responder(c, http.StatusBadRequest, "Bad Request") + } + */ + file, err := c.FormFile("document") + if err != nil { + log.Println(err) + return err + } + + err = rc.rs.EditStudyMaterialURL(request.Name, file) + if err != nil { + log.Println(color.RedString(err.Error())) + return middlewares.Responder(c, http.StatusConflict, err) + } + return middlewares.Responder(c, http.StatusOK, "Success") +} + +// DeleteStudyMaterial godoc +// +// @Summary Deletes a study material +// @Description Deletes a study material along with its document and remove form Database +// @Tags StudyMaterial +// @Accept json +// @Produce json +// @Param name path string true "Delete study material" +// @Success 200 {object} string +// @Failure 400 {object} models.Error +// +// @Security ApiKeyAuth +// @Router /v1/studymaterial/delete/{name} [delete] +func (rc *studyMaterialController) DeleteStudyMaterial(c echo.Context) error { + rname := c.Param("name") + + err := rc.rs.RemoveStudyMaterial(rname) + log.Println(rname) + if err != nil { + log.Println(color.RedString(err.Error())) + return middlewares.Responder(c, http.StatusConflict, "Error Occurred") + } + + return middlewares.Responder(c, http.StatusOK, "Success") +} + +// AddSubject godoc +// +// @Summary Add a subject +// @Description Creates a new subject and adds to Database +// @Tags StudyMaterial +// @Accept multipart/form-data +// @Produce json +// @Param subject formData string true "Enter subject name" +// @Param code formData string true "Enter subject code" +// @Param category formData models.SubjectCategory true "Enter subject category" +// @Success 200 {object} string +// @Failure 400 {object} models.Error +// +// @Security ApiKeyAuth +// @Router /v1/studymaterial/addSubject [post] +func (rc *studyMaterialController) AddSubject(c echo.Context) error { + response := new(models.StudyMaterialRequest) + if err := c.Bind(response); err != nil { + return err + } + err := rc.rs.AddSubject(response) + if err != nil { + log.Println(color.RedString(err.Error())) + return middlewares.Responder(c, http.StatusConflict, "Error Occurred") + } + + return middlewares.Responder(c, http.StatusOK, "Success") +} + +// GetAllStudyMaterials godoc +// +// @Summary Get all study materials from each category +// @Description Fetches all study materials belonging to every category from Database +// @Tags StudyMaterial +// @Accept json +// @Produce json +// @Success 200 {object} []models.CategoryMaterials +// @Failure 400 {object} models.Error +// +// @Security ApiKeyAuth +// @Router /v1/studymaterial/getall [get] +func (rc *studyMaterialController) GetAllMaterials(c echo.Context) error { + res, err := rc.rs.GetAllMaterials() + if err != nil { + log.Println(color.RedString(err.Error())) + return middlewares.Responder(c, http.StatusConflict, "Conflict") + } + return middlewares.Responder(c, http.StatusOK, res) +} diff --git a/controllers/team_controller.go b/controllers/team_controller.go index 6cbde60..bb98f9f 100644 --- a/controllers/team_controller.go +++ b/controllers/team_controller.go @@ -108,6 +108,8 @@ func (tc *teamController) AddMember(c echo.Context) error { log.Println(err) return middlewares.Responder(c, http.StatusBadRequest, "Bad Request") } + log.Println(request.Team) + log.Println(request.Role) file, err := c.FormFile("image") if err != nil { log.Println(err) From f4251f26ec5ed63914a5c962f7ad78f5e1317c15 Mon Sep 17 00:00:00 2001 From: RevanthSPK Date: Tue, 24 Jan 2023 22:28:03 +0530 Subject: [PATCH 10/21] feat(db): migrated database --- config/database.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/database.go b/config/database.go index bb5a8dd..ca7536b 100644 --- a/config/database.go +++ b/config/database.go @@ -47,6 +47,9 @@ func MigrateDB() { &schemas.Team{}, &schemas.Role{}, &schemas.Member{}, + &schemas.Subject{}, + &schemas.StudyMaterial{}, + &schemas.SubjectCategory{}, } { if err := db.AutoMigrate(&schema); err != nil { panic(err) From b485bb594b524eaa65a01e14998a95d4a420deae Mon Sep 17 00:00:00 2001 From: RevanthSPK Date: Tue, 24 Jan 2023 22:29:02 +0530 Subject: [PATCH 11/21] feat(swagger): updated swaggerui --- docs/docs.go | 387 ++++++++++++++++++++++++++++++++++++++++++++++ docs/swagger.json | 387 ++++++++++++++++++++++++++++++++++++++++++++++ docs/swagger.yaml | 253 ++++++++++++++++++++++++++++++ 3 files changed, 1027 insertions(+) diff --git a/docs/docs.go b/docs/docs.go index 2f0243d..4e8b565 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -24,6 +24,359 @@ const docTemplate = `{ "host": "{{.Host}}", "basePath": "{{.BasePath}}", "paths": { + "/v1/studymaterial/addMaterial": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Creates a new study material and adds to Database", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "StudyMaterial" + ], + "summary": "Add a study material", + "parameters": [ + { + "type": "string", + "description": "Enter material name", + "name": "name", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "Enter subject code", + "name": "code", + "in": "formData", + "required": true + }, + { + "type": "file", + "description": "Upload Document", + "name": "document", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, + "/v1/studymaterial/addSubject": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Creates a new subject and adds to Database", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "StudyMaterial" + ], + "summary": "Add a subject", + "parameters": [ + { + "type": "string", + "description": "Enter subject name", + "name": "subject", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "Enter subject code", + "name": "code", + "in": "formData", + "required": true + }, + { + "enum": [ + "DIGITAL ELECTRONICS", + "ANALOG ELECTRONICS", + "TELECOMMUNICATION", + "COMMUNICATION CHANNELING", + "SYSTEM DESIGN AND ARCHITECTURE", + "BASIC ENGINEERING", + "MATHEMATICS", + "OTHERS" + ], + "type": "string", + "description": "Enter subject category", + "name": "category", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, + "/v1/studymaterial/delete/{name}": { + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Deletes a study material along with its document and remove form Database", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "StudyMaterial" + ], + "summary": "Deletes a study material", + "parameters": [ + { + "type": "string", + "description": "Delete study material", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, + "/v1/studymaterial/edit/document": { + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Update a document and update it on Database", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "StudyMaterial" + ], + "summary": "Update a study material's document", + "parameters": [ + { + "type": "string", + "description": "Enter the name of material", + "name": "name", + "in": "formData", + "required": true + }, + { + "type": "file", + "description": "Edit Document", + "name": "document", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, + "/v1/studymaterial/get/{name}": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Fetches a study material and removes form database", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "StudyMaterial" + ], + "summary": "Get a study material", + "parameters": [ + { + "type": "string", + "description": "Get study material", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.StudyMaterials" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, + "/v1/studymaterial/getall": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Fetches all study materials belonging to every category from Database", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "StudyMaterial" + ], + "summary": "Get all study materials from each category", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/models.CategoryMaterials" + } + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, + "/v1/studymaterial/getcat/{category}": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Fetches all study materials belonging to a category from Database", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "StudyMaterial" + ], + "summary": "Get study materials from a category", + "parameters": [ + { + "enum": [ + "DIGITAL ELECTRONICS", + "ANALOG ELECTRONICS", + "TELECOMMUNICATION", + "COMMUNICATION CHANNELING", + "SYSTEM DESIGN AND ARCHITECTURE", + "BASIC ENGINEERING", + "MATHEMATICS", + "OTHERS" + ], + "type": "string", + "description": "Get study material from category", + "name": "category", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/models.StudyMaterials" + } + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, "/v1/team/add": { "post": { "security": [ @@ -516,6 +869,20 @@ const docTemplate = `{ } }, "definitions": { + "models.CategoryMaterials": { + "type": "object", + "properties": { + "category": { + "type": "string" + }, + "subjects": { + "type": "array", + "items": { + "$ref": "#/definitions/models.StudyMaterials" + } + } + } + }, "models.Error": { "type": "object", "properties": { @@ -604,6 +971,26 @@ const docTemplate = `{ "type": "string" } } + }, + "models.StudyMaterials": { + "type": "object", + "properties": { + "document_url": { + "type": "string" + }, + "name": { + "type": "string" + }, + "subject": { + "type": "string" + }, + "subjectCode": { + "type": "string" + }, + "subject_category": { + "type": "string" + } + } } }, "securityDefinitions": { diff --git a/docs/swagger.json b/docs/swagger.json index b74456a..1bd9975 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -15,6 +15,359 @@ "version": "1.0" }, "paths": { + "/v1/studymaterial/addMaterial": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Creates a new study material and adds to Database", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "StudyMaterial" + ], + "summary": "Add a study material", + "parameters": [ + { + "type": "string", + "description": "Enter material name", + "name": "name", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "Enter subject code", + "name": "code", + "in": "formData", + "required": true + }, + { + "type": "file", + "description": "Upload Document", + "name": "document", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, + "/v1/studymaterial/addSubject": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Creates a new subject and adds to Database", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "StudyMaterial" + ], + "summary": "Add a subject", + "parameters": [ + { + "type": "string", + "description": "Enter subject name", + "name": "subject", + "in": "formData", + "required": true + }, + { + "type": "string", + "description": "Enter subject code", + "name": "code", + "in": "formData", + "required": true + }, + { + "enum": [ + "DIGITAL ELECTRONICS", + "ANALOG ELECTRONICS", + "TELECOMMUNICATION", + "COMMUNICATION CHANNELING", + "SYSTEM DESIGN AND ARCHITECTURE", + "BASIC ENGINEERING", + "MATHEMATICS", + "OTHERS" + ], + "type": "string", + "description": "Enter subject category", + "name": "category", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, + "/v1/studymaterial/delete/{name}": { + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Deletes a study material along with its document and remove form Database", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "StudyMaterial" + ], + "summary": "Deletes a study material", + "parameters": [ + { + "type": "string", + "description": "Delete study material", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, + "/v1/studymaterial/edit/document": { + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Update a document and update it on Database", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "StudyMaterial" + ], + "summary": "Update a study material's document", + "parameters": [ + { + "type": "string", + "description": "Enter the name of material", + "name": "name", + "in": "formData", + "required": true + }, + { + "type": "file", + "description": "Edit Document", + "name": "document", + "in": "formData", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, + "/v1/studymaterial/get/{name}": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Fetches a study material and removes form database", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "StudyMaterial" + ], + "summary": "Get a study material", + "parameters": [ + { + "type": "string", + "description": "Get study material", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/models.StudyMaterials" + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, + "/v1/studymaterial/getall": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Fetches all study materials belonging to every category from Database", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "StudyMaterial" + ], + "summary": "Get all study materials from each category", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/models.CategoryMaterials" + } + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, + "/v1/studymaterial/getcat/{category}": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "description": "Fetches all study materials belonging to a category from Database", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "StudyMaterial" + ], + "summary": "Get study materials from a category", + "parameters": [ + { + "enum": [ + "DIGITAL ELECTRONICS", + "ANALOG ELECTRONICS", + "TELECOMMUNICATION", + "COMMUNICATION CHANNELING", + "SYSTEM DESIGN AND ARCHITECTURE", + "BASIC ENGINEERING", + "MATHEMATICS", + "OTHERS" + ], + "type": "string", + "description": "Get study material from category", + "name": "category", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/models.StudyMaterials" + } + } + }, + "400": { + "description": "Bad Request", + "schema": { + "$ref": "#/definitions/models.Error" + } + } + } + } + }, "/v1/team/add": { "post": { "security": [ @@ -507,6 +860,20 @@ } }, "definitions": { + "models.CategoryMaterials": { + "type": "object", + "properties": { + "category": { + "type": "string" + }, + "subjects": { + "type": "array", + "items": { + "$ref": "#/definitions/models.StudyMaterials" + } + } + } + }, "models.Error": { "type": "object", "properties": { @@ -595,6 +962,26 @@ "type": "string" } } + }, + "models.StudyMaterials": { + "type": "object", + "properties": { + "document_url": { + "type": "string" + }, + "name": { + "type": "string" + }, + "subject": { + "type": "string" + }, + "subjectCode": { + "type": "string" + }, + "subject_category": { + "type": "string" + } + } } }, "securityDefinitions": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 4f5429a..46accad 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -1,4 +1,13 @@ definitions: + models.CategoryMaterials: + properties: + category: + type: string + subjects: + items: + $ref: '#/definitions/models.StudyMaterials' + type: array + type: object models.Error: properties: code: @@ -63,6 +72,19 @@ definitions: message: type: string type: object + models.StudyMaterials: + properties: + document_url: + type: string + name: + type: string + subject: + type: string + subject_category: + type: string + subjectCode: + type: string + type: object info: contact: email: probe.eceanitt@gmail.com @@ -75,6 +97,237 @@ info: title: Probe Admin version: "1.0" paths: + /v1/studymaterial/addMaterial: + post: + consumes: + - multipart/form-data + description: Creates a new study material and adds to Database + parameters: + - description: Enter material name + in: formData + name: name + required: true + type: string + - description: Enter subject code + in: formData + name: code + required: true + type: string + - description: Upload Document + in: formData + name: document + required: true + type: file + produces: + - application/json + responses: + "200": + description: OK + schema: + type: string + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.Error' + security: + - ApiKeyAuth: [] + summary: Add a study material + tags: + - StudyMaterial + /v1/studymaterial/addSubject: + post: + consumes: + - multipart/form-data + description: Creates a new subject and adds to Database + parameters: + - description: Enter subject name + in: formData + name: subject + required: true + type: string + - description: Enter subject code + in: formData + name: code + required: true + type: string + - description: Enter subject category + enum: + - DIGITAL ELECTRONICS + - ANALOG ELECTRONICS + - TELECOMMUNICATION + - COMMUNICATION CHANNELING + - SYSTEM DESIGN AND ARCHITECTURE + - BASIC ENGINEERING + - MATHEMATICS + - OTHERS + in: formData + name: category + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + type: string + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.Error' + security: + - ApiKeyAuth: [] + summary: Add a subject + tags: + - StudyMaterial + /v1/studymaterial/delete/{name}: + delete: + consumes: + - application/json + description: Deletes a study material along with its document and remove form + Database + parameters: + - description: Delete study material + in: path + name: name + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + type: string + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.Error' + security: + - ApiKeyAuth: [] + summary: Deletes a study material + tags: + - StudyMaterial + /v1/studymaterial/edit/document: + put: + consumes: + - multipart/form-data + description: Update a document and update it on Database + parameters: + - description: Enter the name of material + in: formData + name: name + required: true + type: string + - description: Edit Document + in: formData + name: document + required: true + type: file + produces: + - application/json + responses: + "200": + description: OK + schema: + type: string + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.Error' + security: + - ApiKeyAuth: [] + summary: Update a study material's document + tags: + - StudyMaterial + /v1/studymaterial/get/{name}: + get: + consumes: + - application/json + description: Fetches a study material and removes form database + parameters: + - description: Get study material + in: path + name: name + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.StudyMaterials' + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.Error' + security: + - ApiKeyAuth: [] + summary: Get a study material + tags: + - StudyMaterial + /v1/studymaterial/getall: + get: + consumes: + - application/json + description: Fetches all study materials belonging to every category from Database + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/models.CategoryMaterials' + type: array + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.Error' + security: + - ApiKeyAuth: [] + summary: Get all study materials from each category + tags: + - StudyMaterial + /v1/studymaterial/getcat/{category}: + get: + consumes: + - application/json + description: Fetches all study materials belonging to a category from Database + parameters: + - description: Get study material from category + enum: + - DIGITAL ELECTRONICS + - ANALOG ELECTRONICS + - TELECOMMUNICATION + - COMMUNICATION CHANNELING + - SYSTEM DESIGN AND ARCHITECTURE + - BASIC ENGINEERING + - MATHEMATICS + - OTHERS + in: path + name: category + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/models.StudyMaterials' + type: array + "400": + description: Bad Request + schema: + $ref: '#/definitions/models.Error' + security: + - ApiKeyAuth: [] + summary: Get study materials from a category + tags: + - StudyMaterial /v1/team/add: post: consumes: From 1edc467250edf620e46a93b11ea8b090d2d01aad Mon Sep 17 00:00:00 2001 From: RevanthSPK Date: Tue, 24 Jan 2023 22:31:21 +0530 Subject: [PATCH 12/21] feat(helpers): added resource helper --- helpers/resource.go | 75 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 helpers/resource.go diff --git a/helpers/resource.go b/helpers/resource.go new file mode 100644 index 0000000..9a6eebf --- /dev/null +++ b/helpers/resource.go @@ -0,0 +1,75 @@ +package helpers + +import ( + "log" + "mime/multipart" + + "github.com/ecea-nitt/ecea-server/repositories" + "github.com/ecea-nitt/ecea-server/utils" +) + +func FetchSubjectID(channel chan int, code string, repo repositories.StudyMaterialRepository) { + subID, err := repo.GetSubjectID(code) + if err != nil { + return + } + channel <- int(subID) + +} + +func FetchSubjectCategoryID(channel chan int, subjectCode string, repo repositories.StudyMaterialRepository) { + id, err := repo.GetSubjectCategoryIDByCode(subjectCode) + if err != nil { + log.Println("hehehaha") + channel <- -1 + return + } + channel <- int(id) + +} + +func UploadFileAndFetchAssetID(channel chan int, file *multipart.FileHeader, repo repositories.StudyMaterialRepository) { + + fileName, err := utils.UploadDocument(file) + if err != nil { + log.Println(err) + channel <- -1 + return + } + id, err := repo.InsertAsset(fileName) + if err != nil { + log.Println(err) + channel <- -1 + return + } + channel <- int(id) +} + +func UpdateFileAndFetchAssetID(dbID uint, dbName string, document *multipart.FileHeader, repo repositories.StudyMaterialRepository) int { + + if dbName == document.Filename { + return int(dbID) + } + + err := utils.DeleteDocument(dbName) + + if err != nil { + log.Println(err) + return -1 + } + + fileName, err := utils.UploadDocument(document) + if err != nil { + log.Println(err) + return -1 + } + + err = repo.UpdateAsset(dbID, fileName) + + if err != nil { + log.Println(err) + return -1 + } + + return int(dbID) +} From 62fc183e55fa247808656979953aa12d59636f5f Mon Sep 17 00:00:00 2001 From: RevanthSPK Date: Tue, 24 Jan 2023 22:33:03 +0530 Subject: [PATCH 13/21] feat(models): added study material and subject models --- models/resource.go | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 models/resource.go diff --git a/models/resource.go b/models/resource.go new file mode 100644 index 0000000..efbe419 --- /dev/null +++ b/models/resource.go @@ -0,0 +1,33 @@ +package models + +type StudyMaterialRequest struct { + Name string `json:"name" form:"name"` + Subject string `json:"subject" form:"subject"` + SubjectCategory string `json:"subject_category" form:"category"` + SubjectCode string `json:"subject_code" form:"code"` +} +type StudyMaterials struct { + Name string `json:"name"` + Subject string `json:"subject"` + SubjectCategory string `json:"subject_category"` + SubjectCode string `hson:"subject_code"` + DocumentURL string `json:"document_url"` +} + +type CategoryMaterials struct { + Category string `json:"category"` + Material []StudyMaterials `json:"subjects"` +} + +type SubjectCategory string + +const ( + DigitalElectronics SubjectCategory = "DIGITAL ELECTRONICS" + AnalogElectronics SubjectCategory = "ANALOG ELECTRONICS" + Telecommunication SubjectCategory = "TELECOMMUNICATION" + CommunicationChanneling SubjectCategory = "COMMUNICATION CHANNELING" + SystemDesignAndArchitechture SubjectCategory = "SYSTEM DESIGN AND ARCHITECTURE" + BasicEngineering SubjectCategory = "BASIC ENGINEERING" + Mathematics SubjectCategory = "MATHEMATICS" + Others SubjectCategory = "OTHERS" +) From d001e09a5c331b6f4e6d25a4dd83f386c5258807 Mon Sep 17 00:00:00 2001 From: RevanthSPK Date: Tue, 24 Jan 2023 22:35:36 +0530 Subject: [PATCH 14/21] feat(registry): added resource registry --- registry/registry.go | 7 ++++--- registry/resource_registry.go | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 registry/resource_registry.go diff --git a/registry/registry.go b/registry/registry.go index 1142ec8..32c4dc7 100644 --- a/registry/registry.go +++ b/registry/registry.go @@ -19,8 +19,9 @@ func NewRegistry(db *gorm.DB) Registry { func (r *registry) NewAppController() controllers.AppController { return controllers.AppController{ - User: r.NewUserController(), - Team: r.NewTeamController(), - Seed: r.NewSeedController(), + User: r.NewUserController(), + Team: r.NewTeamController(), + Seed: r.NewSeedController(), + StudyMaterial: r.NewStudyMaterialController(), } } diff --git a/registry/resource_registry.go b/registry/resource_registry.go new file mode 100644 index 0000000..3dc3b73 --- /dev/null +++ b/registry/resource_registry.go @@ -0,0 +1,19 @@ +package registry + +import ( + "github.com/ecea-nitt/ecea-server/controllers" + "github.com/ecea-nitt/ecea-server/repositories" + "github.com/ecea-nitt/ecea-server/services" +) + +func (r *registry) NewStudyMaterialController() controllers.StudyMaterialController { + return controllers.NewStudyMaterialController(r.NewStudyMaterialService()) +} + +func (r *registry) NewStudyMaterialService() services.StudyMaterialService { + return services.NewStudyMaterialService(r.NewStudyMaterialRepository()) +} + +func (r *registry) NewStudyMaterialRepository() repositories.StudyMaterialRepository { + return repositories.NewStudyMaterialRepository(r.db) +} From de3deb01401d450aba239f0665622df8840c4ea5 Mon Sep 17 00:00:00 2001 From: RevanthSPK Date: Tue, 24 Jan 2023 22:36:23 +0530 Subject: [PATCH 15/21] feat(repositories): added resource repository --- repositories/resource_repository.go | 214 ++++++++++++++++++++++++++++ repositories/seeder_repository.go | 5 + 2 files changed, 219 insertions(+) create mode 100644 repositories/resource_repository.go diff --git a/repositories/resource_repository.go b/repositories/resource_repository.go new file mode 100644 index 0000000..c7085e2 --- /dev/null +++ b/repositories/resource_repository.go @@ -0,0 +1,214 @@ +package repositories + +import ( + "github.com/ecea-nitt/ecea-server/config" + "github.com/ecea-nitt/ecea-server/models" + "github.com/ecea-nitt/ecea-server/schemas" + "gorm.io/gorm" + "gorm.io/gorm/clause" +) + +type studyMaterialRepository struct { + db *gorm.DB +} + +type StudyMaterialRepository interface { + GetCategoryStudyMaterials(name string) ([]models.StudyMaterials, error) + GetAllCategories() ([]string, error) + FindStudyMaterialByName(name string) (models.StudyMaterials, error) + FindStudyMaterialByNameReturnSchema(name string) (schemas.StudyMaterial, error) + GetSubjectID(code string) (uint, error) + GetSubjectCategoryID(name string) (uint, error) + GetSubjectCategory(subject string) (string, error) + GetSubjectCategoryIDByCode(code string) (uint, error) + GetSubjectIDByName(name string) (uint, error) + GetAssetIDByName(name string) (uint, error) + InsertAsset(name string) (uint, error) + UpdateAsset(id uint, name string) error + CreateSubject(name string, code string, id uint) error + CreateStudyMaterial(studyMaterial *schemas.StudyMaterial) error + UpdateStudyMaterialSubject(editrequest *schemas.Subject, name string, code string) error + UpdateStudyMaterial(studyMaterial *schemas.StudyMaterial) error + DeleteStudyMaterial(name string, subjectID uint, assetID uint) error +} + +func NewStudyMaterialRepository(db *gorm.DB) StudyMaterialRepository { + return &studyMaterialRepository{db} +} + +func (rr *studyMaterialRepository) UpdateStudyMaterialSubject(editrequest *schemas.Subject, name string, code string) error { + /* + return rr.db.Table("subjects").Where("subjects.subject_code = ?", code).Update("subjects.name", name).Error + return rr.db.Model(&schemas.Subject{}).Where("subjects.subject_code = ?", code).Update("name", name).Error + */ + return rr.db.Model(&editrequest).Where("subject_code = ?", code).Updates(&editrequest).Error +} + +func (rr *studyMaterialRepository) CreateStudyMaterial(studyMaterial *schemas.StudyMaterial) error { + return rr.db.Create(&studyMaterial).Error +} + +func (rr *studyMaterialRepository) GetSubjectIDByName(name string) (uint, error) { + var studyMaterial schemas.StudyMaterial + res := rr.db.Where("name = ?", name).First(&studyMaterial) + if res.Error != nil { + return 0, res.Error + } + return studyMaterial.SubjectID, nil +} +func (rr *studyMaterialRepository) DeleteStudyMaterial(name string, subjectID uint, assetID uint) error { + err := rr.db.Unscoped().Where("id = ?", subjectID).Delete(&schemas.Subject{}).Error + if err != nil { + return err + } + err = rr.db.Unscoped().Where("id = ?", assetID).Delete(&schemas.Asset{}).Error + if err != nil { + return err + } + return rr.db.Unscoped().Where("name = ?", name).Delete(&schemas.StudyMaterial{}).Error +} + +func (rr *studyMaterialRepository) GetSubjectID(code string) (uint, error) { + var subject schemas.Subject + res := rr.db.Where("subject_code = ?", code).First(&subject) + if res.Error != nil { + return 0, res.Error + } + return subject.ID, nil +} + +func (rr *studyMaterialRepository) GetSubjectCategoryID(name string) (uint, error) { + var subjectCategory schemas.SubjectCategory + res := rr.db.Where("name = ?", name).First(&subjectCategory) + if res.Error != nil { + return 0, res.Error + } + return subjectCategory.ID, nil +} + +func (rr *studyMaterialRepository) GetAssetIDByName(name string) (uint, error) { + var studyMaterial schemas.StudyMaterial + res := rr.db.Where("name = ?", name).First(&studyMaterial) + if res.Error != nil { + return 0, res.Error + } + return studyMaterial.AssetID, nil +} + +func (rr *studyMaterialRepository) InsertAsset(name string) (uint, error) { + var assetType schemas.AssetType + if err := rr.db.Where("name = ?", schemas.Document).First(&assetType).Error; err != nil { + return 0, err + } + asset := schemas.Asset{ + Name: name, + AssetTypeID: assetType.ID, + } + if err := rr.db.Create(&asset).Error; err != nil { + return 0, err + } + return asset.ID, nil +} + +func (rr *studyMaterialRepository) FindStudyMaterialByName(name string) (models.StudyMaterials, error) { + /* + var studyMaterial schemas.StudyMaterial + + err := rr.db.Preload(clause.Associations).Where("name = ?", name).First(&studyMaterial).Error + return studyMaterial, err + */ + var studyMaterials models.StudyMaterials + err := rr.db.Table("study_materials").Select( + `study_materials.name as name,subjects.name as subject,subjects.subject_code as subject_code,CONCAT(?::text,'/static/documents','/',assets.name) as document_url`, config.Origin, + ).Joins( + "JOIN assets on assets.id = study_materials.asset_id").Joins( + "JOIN subjects on subjects.id = study_materials.subject_id").Where( + "study_materials.name = ?", name).First( + &studyMaterials).Error + if err != nil { + return models.StudyMaterials{}, err + } + return studyMaterials, nil +} + +func (rr *studyMaterialRepository) UpdateStudyMaterial(studyMaterial *schemas.StudyMaterial) error { + return rr.db.Model(&studyMaterial).Where("id = ?", studyMaterial.ID).Updates(&studyMaterial).Error +} + +func (rr *studyMaterialRepository) GetCategoryStudyMaterials(name string) ([]models.StudyMaterials, error) { + var studyMaterials []models.StudyMaterials + if err := rr.db.Table("study_materials").Select( + `study_materials.name as name,subjects.name as subject,subject_categories.name as subject_category,subjects.subject_code as subject_code, CONCAT(?::text,'/static/documents','/',assets.name) as document_url`, config.Origin, + ).Joins( + "JOIN assets on assets.id = study_materials.asset_id").Joins( + "JOIN subjects on subjects.id = study_materials.subject_id").Joins("JOIN subject_categories on subject_categories.id = subjects.subject_category_id").Where("subject_categories.name = ?", name).Scan( + &studyMaterials).Error; err != nil { + return nil, err + } + + return studyMaterials, nil +} + +func (rr *studyMaterialRepository) UpdateAsset(id uint, name string) error { + return rr.db.Model(&schemas.Asset{}).Where("id = ?", id).Update("name", name).Error +} + +func (rr *studyMaterialRepository) CreateSubject(name string, code string, id uint) error { + subject := schemas.Subject{ + Name: name, + SubjectCategoryID: id, + SubjectCode: code, + } + res := rr.db.Create(&subject) + if res.Error != nil { + return res.Error + } + return nil +} + +func (rr *studyMaterialRepository) GetSubjectCategory(subject string) (string, error) { + var category string + if err := rr.db.Table("subject_categories").Select( + `subject_categories.name`, + ).Joins( + "JOIN subjects on subjects.subject_category_id = subject_categories.id").Where("subjects.name = ?", subject).Scan( + &category).Error; err != nil { + return "", err + } + return category, nil +} + +func (rr *studyMaterialRepository) FindStudyMaterialByNameReturnSchema(name string) (schemas.StudyMaterial, error) { + var studyMaterial schemas.StudyMaterial + + err := rr.db.Preload(clause.Associations).Where("name = ?", name).First(&studyMaterial).Error + return studyMaterial, err +} + +func (rr *studyMaterialRepository) GetSubjectCategoryIDByCode(code string) (uint, error) { + var id uint + if err := rr.db.Table("subjects").Select(`subjects.subject_category_id`).Where("subjects.subject_code = ?", code).Scan( + &id).Error; err != nil { + return 0, err + } + return id, nil +} + +/* + func (rr *studyMaterialRepository) GetAllMaterials(categories []string) ([]models.AllMaterials,error) { + var allMaterials []models.AllMaterials + var categoryMaterials models.AllMaterials + for _,category := range categories { + categoryMaterials.Category = category + + } + } +*/ +func (rr *studyMaterialRepository) GetAllCategories() ([]string, error) { + var allCategories []string + if err := rr.db.Table("subject_categories").Select(`subject_categories.name`).Scan( + &allCategories).Error; err != nil { + return nil, err + } + return allCategories, nil +} diff --git a/repositories/seeder_repository.go b/repositories/seeder_repository.go index f71db45..71f79d5 100644 --- a/repositories/seeder_repository.go +++ b/repositories/seeder_repository.go @@ -13,6 +13,7 @@ type SeedRepository interface { InsertTeams(teams []schemas.Team) error InsertRoles(roles []schemas.Role) error InsertAssetTypes(types []schemas.AssetType) error + InsertSubjectCategory(sc []schemas.SubjectCategory) error } func NewSeedRepository(db *gorm.DB) SeedRepository { @@ -31,3 +32,7 @@ func (sr *seedRepository) InsertRoles(roles []schemas.Role) error { func (sr *seedRepository) InsertAssetTypes(types []schemas.AssetType) error { return sr.db.Create(&types).Error } + +func (sr *seedRepository) InsertSubjectCategory(sc []schemas.SubjectCategory) error { + return sr.db.Create(&sc).Error +} From b67a998726d54c59ce2375c481684d421a89605b Mon Sep 17 00:00:00 2001 From: RevanthSPK Date: Tue, 24 Jan 2023 22:37:10 +0530 Subject: [PATCH 16/21] feat(router): added resource routes --- router/resource.go | 22 ++++++++++++++++++++++ router/router.go | 1 + 2 files changed, 23 insertions(+) create mode 100644 router/resource.go diff --git a/router/resource.go b/router/resource.go new file mode 100644 index 0000000..c46d16f --- /dev/null +++ b/router/resource.go @@ -0,0 +1,22 @@ +package router + +import ( + "github.com/ecea-nitt/ecea-server/controllers" + "github.com/ecea-nitt/ecea-server/middlewares" + "github.com/labstack/echo/v4" +) + +func StudyMaterialRoutes(e *echo.Group, c controllers.StudyMaterialController) { + studyMaterial := e.Group("/studymaterial") + + studyMaterial.POST("/addMaterial", middlewares.Authorizer(c.AddStudyMaterial)) + studyMaterial.PUT("/edit/document", middlewares.Authorizer(c.UpdateStudyMaterialURL)) + // studyMaterial.PUT("/edit/name", middlewares.Authorizer(c.EditRessourceName)) + // studyMaterial.PUT("/edit/bookid", middlewares.Authorizer(c.EditMemberRole)) + studyMaterial.POST("/addSubject", middlewares.Authorizer(c.AddSubject)) + studyMaterial.GET("/getcat/:category", c.GetCategoryStudyMaterials) + studyMaterial.GET("/get/:name", c.GetStudyMaterial) + studyMaterial.GET("/getall", c.GetAllMaterials) + studyMaterial.DELETE("/delete/:name", middlewares.Authorizer(c.DeleteStudyMaterial)) + +} diff --git a/router/router.go b/router/router.go index 20a3ac4..48d3897 100644 --- a/router/router.go +++ b/router/router.go @@ -16,5 +16,6 @@ func NewRouter(e *echo.Echo, c controllers.AppController) { UserRoutes(api, c.User) TeamRoutes(api, c.Team) + StudyMaterialRoutes(api, c.StudyMaterial) SwaggerRoutes(api) } From 069cf2c34373d89e8fbfc2fa7f2a0f3438babb91 Mon Sep 17 00:00:00 2001 From: RevanthSPK Date: Tue, 24 Jan 2023 22:37:45 +0530 Subject: [PATCH 17/21] feat(schemas): added resource and subject schemas --- schemas/asset.go | 2 +- schemas/resource.go | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 schemas/resource.go diff --git a/schemas/asset.go b/schemas/asset.go index 7ab5f23..c63c7e4 100644 --- a/schemas/asset.go +++ b/schemas/asset.go @@ -11,7 +11,7 @@ type Asset struct { type AssetType struct { gorm.Model - Name string `gorm:"not null;unique"` + Name string `gorm:"not null;"` } type AssetTypes string diff --git a/schemas/resource.go b/schemas/resource.go new file mode 100644 index 0000000..aef7d2a --- /dev/null +++ b/schemas/resource.go @@ -0,0 +1,25 @@ +package schemas + +import "gorm.io/gorm" + +type StudyMaterial struct { + gorm.Model + Name string `gorm:"not null; unique"` + AssetID uint `gorm:"default: null"` + Asset Asset `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` + SubjectID uint `gorm:"default: null"` + Subject Subject `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` +} + +type Subject struct { + gorm.Model + SubjectCode string `gorm:"not null; unique"` + Name string `gorm:"not null"` + SubjectCategoryID uint `gorm:"default: null"` + SubjectCategory SubjectCategory `gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"` +} + +type SubjectCategory struct { + gorm.Model + Name string `gorm:"not null; unique"` +} From ad49eea33956f295e07fcad7b04993b43a392ba0 Mon Sep 17 00:00:00 2001 From: RevanthSPK Date: Tue, 24 Jan 2023 22:38:59 +0530 Subject: [PATCH 18/21] feat(services): added resource services --- services/resource_service.go | 160 +++++++++++++++++++++++++++++++++++ services/seeder_service.go | 31 +++++++ 2 files changed, 191 insertions(+) create mode 100644 services/resource_service.go diff --git a/services/resource_service.go b/services/resource_service.go new file mode 100644 index 0000000..aa81ff3 --- /dev/null +++ b/services/resource_service.go @@ -0,0 +1,160 @@ +package services + +import ( + "errors" + "log" + "mime/multipart" + + "github.com/ecea-nitt/ecea-server/helpers" + "github.com/ecea-nitt/ecea-server/models" + "github.com/ecea-nitt/ecea-server/repositories" + "github.com/ecea-nitt/ecea-server/schemas" +) + +type studyMaterialService struct { + repo repositories.StudyMaterialRepository +} + +type StudyMaterialService interface { + CreateNewStudyMaterial(studyMaterialDetails models.StudyMaterialRequest, studyMaterialFile *multipart.FileHeader) error + // EditStudyMaterialSubject(subject string, code string) error + EditStudyMaterialURL(name string, file *multipart.FileHeader) error + GetStudyMaterial(name string) (models.StudyMaterials, error) + GetCategoryStudyMaterials(name string) ([]models.StudyMaterials, error) + RemoveStudyMaterial(name string) error + GetAllMaterials() ([]models.CategoryMaterials, error) + AddSubject(studyMaterialDetails *models.StudyMaterialRequest) error +} + +func NewStudyMaterialService(repo repositories.StudyMaterialRepository) StudyMaterialService { + return &studyMaterialService{repo} +} + +func (rs *studyMaterialService) CreateNewStudyMaterial(studyMaterialDetails models.StudyMaterialRequest, studyMaterialFile *multipart.FileHeader) error { + assetChannel := make(chan int) + subjectChannel := make(chan int) + subjectCategoryChannel := make(chan int) + /* + subjectCategoryID, err := rs.repo.GetSubjectCategoryID(studyMaterialDetails.SubjectCategory) + if err != nil { + return err + } + */ + go helpers.FetchSubjectCategoryID(subjectCategoryChannel, studyMaterialDetails.SubjectCode, rs.repo) + subjectCategoryID := <-subjectCategoryChannel + go helpers.FetchSubjectID(subjectChannel, studyMaterialDetails.SubjectCode, rs.repo) + go helpers.UploadFileAndFetchAssetID(assetChannel, studyMaterialFile, rs.repo) + subjectID := <-subjectChannel + assetID := <-assetChannel + if subjectID == -1 || assetID == -1 || subjectCategoryID == -1 { + return errors.New("could not fetch data") + } + studyMaterial := schemas.StudyMaterial{ + Name: studyMaterialDetails.Name, + SubjectID: uint(subjectID), + AssetID: uint(assetID), + } + log.Println(subjectCategoryID, studyMaterialDetails.SubjectCategory) + return rs.repo.CreateStudyMaterial(&studyMaterial) +} + +/* +func (rs *studyMaterialService) EditStudyMaterialSubject(subject string, code string) error { + editrequest := schemas.Subject{ + Name: subject, + SubjectCode: code, + } + subjectID, err := rs.repo.GetSubjectIDByCode(code) + if err != nil { + return err + } + return rs.repo.UpdateStudyMaterialSubject(&editrequest, subject, code) +} +*/ + +func (rs *studyMaterialService) EditStudyMaterialURL(name string, file *multipart.FileHeader) error { + dbStudyMaterial, err := rs.repo.FindStudyMaterialByNameReturnSchema(name) + if err != nil { + return err + } + + assetID := helpers.UpdateFileAndFetchAssetID(dbStudyMaterial.AssetID, dbStudyMaterial.Asset.Name, file, rs.repo) + + if assetID == -1 { + return errors.New(" Error Occurred") + } + + studyMaterial := schemas.StudyMaterial{ + AssetID: uint(assetID), + } + studyMaterial.ID = dbStudyMaterial.ID + + return rs.repo.UpdateStudyMaterial(&studyMaterial) +} + +func (rs *studyMaterialService) RemoveStudyMaterial(name string) error { + subjectID, err1 := rs.repo.GetSubjectIDByName(name) + if err1 != nil { + return err1 + } + assetID, err2 := rs.repo.GetAssetIDByName(name) + if err2 != nil { + return err2 + } + return rs.repo.DeleteStudyMaterial(name, subjectID, assetID) +} + +func (rs *studyMaterialService) GetStudyMaterial(name string) (models.StudyMaterials, error) { + studyMaterial, err := rs.repo.FindStudyMaterialByName(name) + if err != nil { + return models.StudyMaterials{}, err + } + subjectCategory, err1 := rs.repo.GetSubjectCategory(studyMaterial.Subject) + if err1 != nil { + return models.StudyMaterials{}, err1 + } + result := models.StudyMaterials{ + Name: studyMaterial.Name, + Subject: studyMaterial.Subject, + SubjectCategory: subjectCategory, + SubjectCode: studyMaterial.SubjectCode, + DocumentURL: studyMaterial.DocumentURL, + } + log.Println(studyMaterial) + log.Println(result) + return result, err +} + +func (rs *studyMaterialService) GetCategoryStudyMaterials(name string) ([]models.StudyMaterials, error) { + return rs.repo.GetCategoryStudyMaterials(name) +} + +func (rs *studyMaterialService) AddSubject(studyMaterialDetails *models.StudyMaterialRequest) error { + subjectName := studyMaterialDetails.Subject + subjectCode := studyMaterialDetails.SubjectCode + subjectCategory := studyMaterialDetails.SubjectCategory + id, err := rs.repo.GetSubjectCategoryID(subjectCategory) + if err != nil { + return err + } + return rs.repo.CreateSubject(subjectName, subjectCode, id) +} + +func (rs *studyMaterialService) GetAllMaterials() ([]models.CategoryMaterials, error) { + allCategories, err := rs.repo.GetAllCategories() + if err != nil { + return nil, err + } + var allMaterials []models.CategoryMaterials + var categoryMaterials models.CategoryMaterials + for _, category := range allCategories { + categoryMaterials.Category = category + temp, err := rs.repo.GetCategoryStudyMaterials(category) + if err != nil { + return nil, err + } + categoryMaterials.Material = temp + allMaterials = append(allMaterials, categoryMaterials) + } + return allMaterials, nil +} diff --git a/services/seeder_service.go b/services/seeder_service.go index 9837b41..125cea4 100644 --- a/services/seeder_service.go +++ b/services/seeder_service.go @@ -14,6 +14,7 @@ type SeederService interface { AssetTypesSeeder() error TeamsSeeder() error RolesSeeder() error + StudyMaterialSeeder() error } var teams = []schemas.Team{ @@ -60,6 +61,32 @@ var assetTypes = []schemas.AssetType{ Name: string(schemas.Document), }, } +var subjectCategory = []schemas.SubjectCategory{ + { + Name: string(models.AnalogElectronics), + }, + { + Name: string(models.CommunicationChanneling), + }, + { + Name: string(models.DigitalElectronics), + }, + { + Name: string(models.SystemDesignAndArchitechture), + }, + { + Name: string(models.BasicEngineering), + }, + { + Name: string(models.Mathematics), + }, + { + Name: string(models.Telecommunication), + }, + { + Name: string(models.Others), + }, +} func NewSeeder(repo repositories.SeedRepository) SeederService { return &seederService{repo} @@ -76,3 +103,7 @@ func (s *seederService) RolesSeeder() error { func (s *seederService) AssetTypesSeeder() error { return s.repo.InsertAssetTypes(assetTypes) } + +func (s *seederService) StudyMaterialSeeder() error { + return s.repo.InsertSubjectCategory(subjectCategory) +} From d6f69cbd76fd8b9a01d4b20c1f3dddc9c1774305 Mon Sep 17 00:00:00 2001 From: RevanthSPK Date: Tue, 24 Jan 2023 22:42:49 +0530 Subject: [PATCH 19/21] feat(utils): added utilities for operations on documents --- utils/document.go | 51 ++++++++++++++++++++++++++++++++++++++++++++++ utils/validator.go | 2 +- 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 utils/document.go diff --git a/utils/document.go b/utils/document.go new file mode 100644 index 0000000..cec54ba --- /dev/null +++ b/utils/document.go @@ -0,0 +1,51 @@ +package utils + +import ( + "io" + "log" + "mime/multipart" + "os" + "time" + + "github.com/fatih/color" +) + +var DocumentPath = "static/documents/" + +func UploadDocument(file *multipart.FileHeader) (string, error) { + + src, err := file.Open() + if err != nil { + return "", err + } + defer src.Close() + + // Destination + timeStamp := time.Now() + + if _, err := os.Stat(DocumentPath); os.IsNotExist(err) { + _ = os.Mkdir(DocumentPath, 0777) + } + fileName := timeStamp.Format(time.RFC3339) + ".pdf" + path := DocumentPath + fileName + dst, err := os.Create(path) + if err != nil { + return "", err + } + defer dst.Close() + // Copy + if _, err = io.Copy(dst, src); err != nil { + return "", err + } + return fileName, nil +} + +func DeleteDocument(fileName string) error { + path := DocumentPath + fileName + log.Println(color.MagentaString("Deleting: " + path)) + e := os.Remove(path) + if e != nil { + return e + } + return nil +} diff --git a/utils/validator.go b/utils/validator.go index f033495..5941c78 100644 --- a/utils/validator.go +++ b/utils/validator.go @@ -37,7 +37,7 @@ func NumericValidator(s string) (string, error) { func EmailValidator(s string) (string, error) { var IsValid = regexp.MustCompile(`^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$`).MatchString if !IsValid(s) { - return s, errors.New("Invalid Email format") + return s, errors.New(" Invalid Email format") } return s, nil } From 6a298e33cd5a866eed8132b74f2ccb590a2b4c37 Mon Sep 17 00:00:00 2001 From: RevanthSPK Date: Tue, 24 Jan 2023 22:59:04 +0530 Subject: [PATCH 20/21] feat(docker-compose): updated docker-compose.yml --- docker-compose.yml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 1c09ed0..7cf7937 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -30,9 +30,11 @@ services: - ${POSTGRES_PORT}:${POSTGRES_PORT} command: -p ${POSTGRES_PORT} volumes: - - ./database:/data/postgres + - database:/data/postgres +volumes: + database: -networks: - default: - external: - name: thirumathikart_network +# networks: +# default: +# external: +# name: thirumathikart_network \ No newline at end of file From 5872be35561ca709504bdec490c25bdd59468598 Mon Sep 17 00:00:00 2001 From: RevanthSPK Date: Sat, 28 Jan 2023 14:30:41 +0530 Subject: [PATCH 21/21] feat(changes): altered get all resources functionality --- docker-compose.yml | 8 +++--- docs/docs.go | 30 +++++++++++++++++++- docs/swagger.json | 30 +++++++++++++++++++- docs/swagger.yaml | 20 +++++++++++++- models/resource.go | 14 ++++++++-- repositories/resource_repository.go | 43 +++++++++++++++++++++++++++++ services/resource_service.go | 25 +++++++++++++++-- 7 files changed, 158 insertions(+), 12 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 7cf7937..a43e35b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -29,10 +29,10 @@ services: ports: - ${POSTGRES_PORT}:${POSTGRES_PORT} command: -p ${POSTGRES_PORT} - volumes: - - database:/data/postgres -volumes: - database: +# volumes: +# - database:/data/postgres +#volumes: +# database: # networks: # default: diff --git a/docs/docs.go b/docs/docs.go index 4e8b565..1e28705 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -878,7 +878,7 @@ const docTemplate = `{ "subjects": { "type": "array", "items": { - "$ref": "#/definitions/models.StudyMaterials" + "$ref": "#/definitions/models.SubjectMaterial" } } } @@ -896,6 +896,17 @@ const docTemplate = `{ } } }, + "models.Links": { + "type": "object", + "properties": { + "document_url": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, "models.MemberRoles": { "type": "string", "enum": [ @@ -991,6 +1002,23 @@ const docTemplate = `{ "type": "string" } } + }, + "models.SubjectMaterial": { + "type": "object", + "properties": { + "materials": { + "type": "array", + "items": { + "$ref": "#/definitions/models.Links" + } + }, + "name": { + "type": "string" + }, + "subject_code": { + "type": "string" + } + } } }, "securityDefinitions": { diff --git a/docs/swagger.json b/docs/swagger.json index 1bd9975..aa81155 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -869,7 +869,7 @@ "subjects": { "type": "array", "items": { - "$ref": "#/definitions/models.StudyMaterials" + "$ref": "#/definitions/models.SubjectMaterial" } } } @@ -887,6 +887,17 @@ } } }, + "models.Links": { + "type": "object", + "properties": { + "document_url": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, "models.MemberRoles": { "type": "string", "enum": [ @@ -982,6 +993,23 @@ "type": "string" } } + }, + "models.SubjectMaterial": { + "type": "object", + "properties": { + "materials": { + "type": "array", + "items": { + "$ref": "#/definitions/models.Links" + } + }, + "name": { + "type": "string" + }, + "subject_code": { + "type": "string" + } + } } }, "securityDefinitions": { diff --git a/docs/swagger.yaml b/docs/swagger.yaml index 46accad..21e97ff 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -5,7 +5,7 @@ definitions: type: string subjects: items: - $ref: '#/definitions/models.StudyMaterials' + $ref: '#/definitions/models.SubjectMaterial' type: array type: object models.Error: @@ -17,6 +17,13 @@ definitions: example: status type: string type: object + models.Links: + properties: + document_url: + type: string + name: + type: string + type: object models.MemberRoles: enum: - Chairperson @@ -85,6 +92,17 @@ definitions: subjectCode: type: string type: object + models.SubjectMaterial: + properties: + materials: + items: + $ref: '#/definitions/models.Links' + type: array + name: + type: string + subject_code: + type: string + type: object info: contact: email: probe.eceanitt@gmail.com diff --git a/models/resource.go b/models/resource.go index efbe419..58631a3 100644 --- a/models/resource.go +++ b/models/resource.go @@ -15,8 +15,18 @@ type StudyMaterials struct { } type CategoryMaterials struct { - Category string `json:"category"` - Material []StudyMaterials `json:"subjects"` + Category string `json:"category"` + SubjectMaterial []SubjectMaterial `json:"subjects"` +} +type SubjectMaterial struct { + Name string `json:"name"` + SubjectCode string `json:"subject_code"` + Links []Links `json:"materials"` +} + +type Links struct { + Name string `json:"name"` + DocumentURL string `json:"document_url"` } type SubjectCategory string diff --git a/repositories/resource_repository.go b/repositories/resource_repository.go index c7085e2..6245eb0 100644 --- a/repositories/resource_repository.go +++ b/repositories/resource_repository.go @@ -13,6 +13,9 @@ type studyMaterialRepository struct { } type StudyMaterialRepository interface { + GetDocumentLinks(subID uint) ([]models.Links, error) + GetSubjectsByCategory(category string) ([]string, error) + GetSubjectStudyMaterial(subject string) (models.SubjectMaterial, error) GetCategoryStudyMaterials(name string) ([]models.StudyMaterials, error) GetAllCategories() ([]string, error) FindStudyMaterialByName(name string) (models.StudyMaterials, error) @@ -212,3 +215,43 @@ func (rr *studyMaterialRepository) GetAllCategories() ([]string, error) { } return allCategories, nil } + +func (rr *studyMaterialRepository) GetSubjectsByCategory(category string) ([]string, error) { + var categorySubjects []string + id, err := rr.GetSubjectCategoryID(category) + if err != nil { + return nil, err + } + if err := rr.db.Table("subjects").Select("subjects.name").Joins("JOIN subject_categories on subject_categories.name = ?", category).Where("subjects.subject_category_id = ?", id).Scan(&categorySubjects).Error; err != nil { + return nil, err + } + return categorySubjects, nil +} + +func (rr *studyMaterialRepository) GetSubjectStudyMaterial(subject string) (models.SubjectMaterial, error) { + var subMaterial models.SubjectMaterial + var subjectCode string + if err := rr.db.Table("subjects").Select("subjects.subject_code").Where("subjects.name = ?", subject).Scan(&subjectCode).Error; err != nil { + return subMaterial, err + } + subMaterial.Name = subject + subMaterial.SubjectCode = subjectCode + subID, err := rr.GetSubjectID(subjectCode) + if err != nil { + return subMaterial, err + } + links, err1 := rr.GetDocumentLinks(subID) + if err1 != nil { + return subMaterial, err + } + subMaterial.Links = links + return subMaterial, nil +} + +func (rr *studyMaterialRepository) GetDocumentLinks(subID uint) ([]models.Links, error) { + var links []models.Links + if err := rr.db.Table("study_materials").Select(`study_materials.name as name,CONCAT(?::text,'/static/documents','/',assets.name) as document_url`, config.Origin).Joins("JOIN assets on assets.id = study_materials.asset_id").Where("study_materials.subject_id = ?", subID).Scan(&links).Error; err != nil { + return nil, err + } + return links, nil +} diff --git a/services/resource_service.go b/services/resource_service.go index aa81ff3..b74528c 100644 --- a/services/resource_service.go +++ b/services/resource_service.go @@ -147,13 +147,32 @@ func (rs *studyMaterialService) GetAllMaterials() ([]models.CategoryMaterials, e } var allMaterials []models.CategoryMaterials var categoryMaterials models.CategoryMaterials + /* + for _, category := range allCategories { + categoryMaterials.Category = category + temp, err := rs.repo.GetCategoryStudyMaterials(category) + if err != nil { + return nil, err + } + categoryMaterials.Material = temp + allMaterials = append(allMaterials, categoryMaterials) + } + */ for _, category := range allCategories { - categoryMaterials.Category = category - temp, err := rs.repo.GetCategoryStudyMaterials(category) + subjects, err := rs.repo.GetSubjectsByCategory(category) if err != nil { return nil, err } - categoryMaterials.Material = temp + var subjectMaterialList []models.SubjectMaterial + for _, subject := range subjects { + materials, err := rs.repo.GetSubjectStudyMaterial(subject) + if err != nil { + return nil, err + } + subjectMaterialList = append(subjectMaterialList, materials) + } + categoryMaterials.Category = category + categoryMaterials.SubjectMaterial = subjectMaterialList allMaterials = append(allMaterials, categoryMaterials) } return allMaterials, nil