Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

return org spaces' running status #174

Merged
merged 1 commit into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
271 changes: 271 additions & 0 deletions api/handler/organization.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,271 @@
package handler

import (
"log/slog"
"net/http"

"github.com/gin-gonic/gin"
"opencsg.com/csghub-server/api/httpbase"
"opencsg.com/csghub-server/common/config"
"opencsg.com/csghub-server/common/types"
"opencsg.com/csghub-server/common/utils/common"
"opencsg.com/csghub-server/component"
)

func NewOrganizationHandler(config *config.Config) (*OrganizationHandler, error) {
sc, err := component.NewSpaceComponent(config)
if err != nil {
return nil, err
}
cc, err := component.NewCodeComponent(config)
if err != nil {
return nil, err
}
mc, err := component.NewModelComponent(config)
if err != nil {
return nil, err
}
dsc, err := component.NewDatasetComponent(config)
if err != nil {
return nil, err
}
colc, err := component.NewCollectionComponent(config)
if err != nil {
return nil, err
}
return &OrganizationHandler{
sc: sc,
cc: cc,
mc: mc,
dsc: dsc,
colc: colc,
}, nil
}

type OrganizationHandler struct {
sc *component.SpaceComponent
cc *component.CodeComponent
mc *component.ModelComponent
dsc *component.DatasetComponent
colc *component.CollectionComponent
}

// GetOrganizationModels godoc
// @Security ApiKey
// @Summary Get organization models
// @Description get organization models
// @Tags Organization
// @Accept json
// @Produce json
// @Param namespace path string true "org name"
// @Param current_user query string true "current user name"
// @Param per query int false "page size"
// @Param page query int false "current page number"
// @Success 200 {object} types.ResponseWithTotal{data=[]types.Model,total=int} "OK"
// @Failure 400 {object} types.APIBadRequest "Bad request"
// @Failure 500 {object} types.APIInternalServerError "Internal server error"
// @Router /organization/{namespace}/models [get]
func (h *OrganizationHandler) Models(ctx *gin.Context) {
var req types.OrgModelsReq
req.Namespace = ctx.Param("namespace")
req.CurrentUser = httpbase.GetCurrentUser(ctx)

per, page, err := common.GetPerAndPageFromContext(ctx)
if err != nil {
slog.Error("Bad request format", "error", err)
httpbase.BadRequest(ctx, err.Error())
return
}
req.Page = page
req.PageSize = per
models, total, err := h.mc.OrgModels(ctx, &req)
if err != nil {
slog.Error("Failed to get org models", slog.Any("error", err))
httpbase.ServerError(ctx, err)
return
}

slog.Info("Get org models succeed", slog.String("org", req.Namespace))

respData := gin.H{
"message": "OK",
"data": models,
"total": total,
}
ctx.JSON(http.StatusOK, respData)
}

// GetOrganizationDatasets godoc
// @Security ApiKey
// @Summary Get organization datasets
// @Description get organization datasets
// @Tags Organization
// @Accept json
// @Produce json
// @Param namespace path string true "org name"
// @Param current_user query string true "current user name"
// @Param per query int false "page size"
// @Param page query int false "current page number"
// @Success 200 {object} types.ResponseWithTotal{data=[]types.Dataset,total=int} "OK"
// @Failure 400 {object} types.APIBadRequest "Bad request"
// @Failure 500 {object} types.APIInternalServerError "Internal server error"
// @Router /organization/{namespace}/datasets [get]
func (h *OrganizationHandler) Datasets(ctx *gin.Context) {
var req types.OrgDatasetsReq
req.Namespace = ctx.Param("namespace")
req.CurrentUser = httpbase.GetCurrentUser(ctx)

per, page, err := common.GetPerAndPageFromContext(ctx)
if err != nil {
slog.Error("Bad request format", "error", err)
httpbase.BadRequest(ctx, err.Error())
return
}
req.Page = page
req.PageSize = per
datasets, total, err := h.dsc.OrgDatasets(ctx, &req)
if err != nil {
slog.Error("Failed to get org datasets", slog.Any("error", err))
httpbase.ServerError(ctx, err)
return
}

slog.Info("Get org datasets succeed", slog.String("org", req.Namespace))

respData := gin.H{
"message": "OK",
"data": datasets,
"total": total,
}
ctx.JSON(http.StatusOK, respData)
}

// GetOrganizationCodes godoc
// @Security ApiKey
// @Summary Get organization codes
// @Tags Organization
// @Accept json
// @Produce json
// @Param namespace path string true "org name"
// @Param current_user query string true "current user name"
// @Param per query int false "page size"
// @Param page query int false "current page number"
// @Success 200 {object} types.ResponseWithTotal{data=[]types.Code,total=int} "OK"
// @Failure 400 {object} types.APIBadRequest "Bad request"
// @Failure 500 {object} types.APIInternalServerError "Internal server error"
// @Router /organization/{namespace}/codes [get]
func (h *OrganizationHandler) Codes(ctx *gin.Context) {
var req types.OrgCodesReq
req.Namespace = ctx.Param("namespace")
req.CurrentUser = httpbase.GetCurrentUser(ctx)

per, page, err := common.GetPerAndPageFromContext(ctx)
if err != nil {
slog.Error("Bad request format", "error", err)
httpbase.BadRequest(ctx, err.Error())
return
}
req.Page = page
req.PageSize = per
datasets, total, err := h.cc.OrgCodes(ctx, &req)
if err != nil {
slog.Error("Failed to get org codes", slog.Any("error", err))
httpbase.ServerError(ctx, err)
return
}

slog.Info("Get org codes succeed", slog.String("org", req.Namespace))

respData := gin.H{
"message": "OK",
"data": datasets,
"total": total,
}
ctx.JSON(http.StatusOK, respData)
}

// GetOrganizationSpaces godoc
// @Security ApiKey
// @Summary Get organization Spaces
// @Tags Organization
// @Accept json
// @Produce json
// @Param namespace path string true "org name"
// @Param current_user query string true "current user name"
// @Param per query int false "page size"
// @Param page query int false "current page number"
// @Success 200 {object} types.ResponseWithTotal{data=[]types.Space,total=int} "OK"
// @Failure 400 {object} types.APIBadRequest "Bad request"
// @Failure 500 {object} types.APIInternalServerError "Internal server error"
// @Router /organization/{namespace}/spaces [get]
func (h *OrganizationHandler) Spaces(ctx *gin.Context) {
var req types.OrgSpacesReq
req.Namespace = ctx.Param("namespace")
req.CurrentUser = httpbase.GetCurrentUser(ctx)

per, page, err := common.GetPerAndPageFromContext(ctx)
if err != nil {
slog.Error("Bad request format", "error", err)
httpbase.BadRequest(ctx, err.Error())
return
}
req.Page = page
req.PageSize = per
datasets, total, err := h.sc.OrgSpaces(ctx, &req)
if err != nil {
slog.Error("Failed to get org spaces", slog.Any("error", err))
httpbase.ServerError(ctx, err)
return
}

slog.Info("Get org spaces succeed", slog.String("org", req.Namespace))

respData := gin.H{
"message": "OK",
"data": datasets,
"total": total,
}
ctx.JSON(http.StatusOK, respData)
}

// GetOrganizationCollections godoc
// @Security ApiKey
// @Summary Get organization Collections
// @Tags Organization
// @Accept json
// @Produce json
// @Param namespace path string true "org name"
// @Param current_user query string true "current user name"
// @Param per query int false "page size"
// @Param page query int false "current page number"
// @Success 200 {object} types.ResponseWithTotal{data=[]types.Collection,total=int} "OK"
// @Failure 400 {object} types.APIBadRequest "Bad request"
// @Failure 500 {object} types.APIInternalServerError "Internal server error"
// @Router /organization/{namespace}/collections [get]
func (h *OrganizationHandler) Collections(ctx *gin.Context) {
var req types.OrgCollectionsReq
req.Namespace = ctx.Param("namespace")
req.CurrentUser = httpbase.GetCurrentUser(ctx)

per, page, err := common.GetPerAndPageFromContext(ctx)
if err != nil {
slog.Error("Bad request format", "error", err)
httpbase.BadRequest(ctx, err.Error())
return
}
req.Page = page
req.PageSize = per
datasets, total, err := h.colc.OrgCollections(ctx, &req)
if err != nil {
slog.Error("Failed to get org collections", slog.Any("error", err))
httpbase.ServerError(ctx, err)
return
}

respData := gin.H{
"message": "OK",
"data": datasets,
"total": total,
}
ctx.JSON(http.StatusOK, respData)
}
17 changes: 10 additions & 7 deletions api/router/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ func NewRouter(config *config.Config, enableSwagger bool) (*gin.Engine, error) {
if err != nil {
return nil, fmt.Errorf("error creating user controller:%w", err)
}
orgHandler, err := handler.NewOrganizationHandler(config)
if err != nil {
return nil, fmt.Errorf("error creating organization controller:%w", err)
}

repoCommonHandler, err := handler.NewRepoHandler(config)
if err != nil {
Expand Down Expand Up @@ -200,13 +204,12 @@ func NewRouter(config *config.Config, enableSwagger bool) (*gin.Engine, error) {
apiGroup.GET("/organization/:namespace", userProxyHandler.ProxyToApi("/api/v1/organization/%s", "namespace"))
apiGroup.PUT("/organization/:namespace", userProxyHandler.ProxyToApi("/api/v1/organization/%s", "namespace"))
apiGroup.DELETE("/organization/:namespace", userProxyHandler.ProxyToApi("/api/v1/organization/%s", "namespace"))
// Organization models
apiGroup.GET("/organization/:namespace/models", userProxyHandler.ProxyToApi("/api/v1/organization/%s/models", "namespace"))
// Organization datasets
apiGroup.GET("/organization/:namespace/datasets", userProxyHandler.ProxyToApi("/api/v1/organization/%s/datasets", "namespace"))
apiGroup.GET("/organization/:namespace/codes", userProxyHandler.ProxyToApi("/api/v1/organization/%s/codes", "namespace"))
apiGroup.GET("/organization/:namespace/spaces", userProxyHandler.ProxyToApi("/api/v1/organization/%s/spaces", "namespace"))
apiGroup.GET("/organization/:namespace/collections", userProxyHandler.ProxyToApi("/api/v1/organization/%s/collections", "namespace"))
// Organization assets
apiGroup.GET("/organization/:namespace/models", orgHandler.Models)
Rader marked this conversation as resolved.
Show resolved Hide resolved
apiGroup.GET("/organization/:namespace/datasets", orgHandler.Datasets)
apiGroup.GET("/organization/:namespace/codes", orgHandler.Codes)
apiGroup.GET("/organization/:namespace/spaces", orgHandler.Spaces)
apiGroup.GET("/organization/:namespace/collections", orgHandler.Collections)
}

{
Expand Down
42 changes: 42 additions & 0 deletions component/code.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package component
import (
"context"
"fmt"
"log/slog"

"opencsg.com/csghub-server/builder/git/membership"
"opencsg.com/csghub-server/builder/store/database"
"opencsg.com/csghub-server/common/config"
"opencsg.com/csghub-server/common/types"
Expand Down Expand Up @@ -360,3 +362,43 @@ func (c *CodeComponent) getRelations(ctx context.Context, repoID int64, currentU

return rels, nil
}

func (c *CodeComponent) OrgCodes(ctx context.Context, req *types.OrgCodesReq) ([]types.Code, int, error) {
var resCodes []types.Code
var err error
r := membership.RoleUnkown
Rader marked this conversation as resolved.
Show resolved Hide resolved
if req.CurrentUser != "" {
r, err = c.userSvcClient.GetMemberRole(ctx, req.Namespace, req.CurrentUser)
// log error, and treat user as unkown role in org
if err != nil {
slog.Error("faild to get member role",
Rader marked this conversation as resolved.
Show resolved Hide resolved
slog.String("org", req.Namespace), slog.String("user", req.CurrentUser),
slog.String("error", err.Error()))
}
}
onlyPublic := !r.CanRead()
codes, total, err := c.cs.ByOrgPath(ctx, req.Namespace, req.PageSize, req.Page, onlyPublic)
if err != nil {
newError := fmt.Errorf("failed to get org codes,error:%w", err)
slog.Error(newError.Error())
return nil, 0, newError
}

for _, data := range codes {
resCodes = append(resCodes, types.Code{
ID: data.ID,
Name: data.Repository.Name,
Nickname: data.Repository.Nickname,
Description: data.Repository.Description,
Likes: data.Repository.Likes,
Downloads: data.Repository.DownloadCount,
Path: data.Repository.Path,
RepositoryID: data.RepositoryID,
Private: data.Repository.Private,
CreatedAt: data.CreatedAt,
UpdatedAt: data.Repository.UpdatedAt,
})
}

return resCodes, total, nil
}
Loading