Browse Source

feat: checking missing dependencies

Yeuoly 8 months ago
parent
commit
c57b554245

+ 18 - 0
internal/server/controllers/plugins.go

@@ -167,3 +167,21 @@ func ListPlugins(c *gin.Context) {
 		c.JSON(http.StatusOK, service.ListPlugins(request.TenantID, request.Page, request.PageSize))
 	})
 }
+
+func BatchFetchPluginInstallationByIDs(c *gin.Context) {
+	BindRequest(c, func(request struct {
+		TenantID  string   `uri:"tenant_id" validate:"required"`
+		PluginIDs []string `json:"plugin_ids" validate:"required,max=256"`
+	}) {
+		c.JSON(http.StatusOK, service.BatchFetchPluginInstallationByIDs(request.TenantID, request.PluginIDs))
+	})
+}
+
+func FetchMissingPluginInstallations(c *gin.Context) {
+	BindRequest(c, func(request struct {
+		TenantID                string                                   `uri:"tenant_id" validate:"required"`
+		PluginUniqueIdentifiers []plugin_entities.PluginUniqueIdentifier `json:"plugin_unique_identifiers" validate:"required,max=256,dive,plugin_unique_identifier"`
+	}) {
+		c.JSON(http.StatusOK, service.FetchMissingPluginInstallations(request.TenantID, request.PluginUniqueIdentifiers))
+	})
+}

+ 2 - 0
internal/server/http_server.go

@@ -124,6 +124,8 @@ func (app *App) pluginManagementGroup(group *gin.RouterGroup, config *app.Config
 	group.GET("/fetch/identifier", controllers.FetchPluginFromIdentifier)
 	group.POST("/uninstall", controllers.UninstallPlugin)
 	group.GET("/list", gzip.Gzip(gzip.DefaultCompression), controllers.ListPlugins)
+	group.POST("/installation/fetch/batch", controllers.BatchFetchPluginInstallationByIDs)
+	group.POST("/installation/missing", controllers.FetchMissingPluginInstallations)
 	group.GET("/models", gzip.Gzip(gzip.DefaultCompression), controllers.ListModels)
 	group.GET("/tools", gzip.Gzip(gzip.DefaultCompression), controllers.ListTools)
 	group.GET("/tool", gzip.Gzip(gzip.DefaultCompression), controllers.GetTool)

+ 63 - 0
internal/service/manage_plugin.go

@@ -8,6 +8,7 @@ import (
 	"github.com/langgenius/dify-plugin-daemon/internal/types/entities/plugin_entities"
 	"github.com/langgenius/dify-plugin-daemon/internal/types/models"
 	"github.com/langgenius/dify-plugin-daemon/internal/utils/cache/helper"
+	"github.com/langgenius/dify-plugin-daemon/internal/utils/strings"
 )
 
 func ListPlugins(tenant_id string, page int, page_size int) *entities.Response {
@@ -75,6 +76,68 @@ func ListPlugins(tenant_id string, page int, page_size int) *entities.Response {
 	return entities.NewSuccessResponse(data)
 }
 
+// Using plugin_ids to fetch plugin installations
+func BatchFetchPluginInstallationByIDs(tenant_id string, plugin_ids []string) *entities.Response {
+	if len(plugin_ids) == 0 {
+		return entities.NewSuccessResponse([]models.PluginInstallation{})
+	}
+
+	plugin_installations, err := db.GetAll[models.PluginInstallation](
+		db.Equal("tenant_id", tenant_id),
+		db.InArray("plugin_id", strings.Map(plugin_ids, func(id string) any { return id })),
+		db.Page(1, 256), // TODO: pagination
+	)
+
+	if err != nil {
+		return entities.NewErrorResponse(-500, err.Error())
+	}
+
+	return entities.NewSuccessResponse(plugin_installations)
+}
+
+// check which plugin is missing
+func FetchMissingPluginInstallations(tenant_id string, plugin_unique_identifiers []plugin_entities.PluginUniqueIdentifier) *entities.Response {
+	result := make([]plugin_entities.PluginUniqueIdentifier, 0, len(plugin_unique_identifiers))
+
+	if len(plugin_unique_identifiers) == 0 {
+		return entities.NewSuccessResponse(result)
+	}
+
+	installed, err := db.GetAll[models.PluginInstallation](
+		db.Equal("tenant_id", tenant_id),
+		db.InArray(
+			"plugin_unique_identifier",
+			strings.Map(
+				plugin_unique_identifiers,
+				func(id plugin_entities.PluginUniqueIdentifier) any {
+					return id.String()
+				},
+			),
+		),
+	)
+
+	if err != nil {
+		return entities.NewErrorResponse(-500, err.Error())
+	}
+
+	// check which plugin is missing
+	for _, plugin_unique_identifier := range plugin_unique_identifiers {
+		found := false
+		for _, installed_plugin := range installed {
+			if installed_plugin.PluginUniqueIdentifier == plugin_unique_identifier.String() {
+				found = true
+				break
+			}
+		}
+
+		if !found {
+			result = append(result, plugin_unique_identifier)
+		}
+	}
+
+	return entities.NewSuccessResponse(result)
+}
+
 func ListTools(tenant_id string, page int, page_size int) *entities.Response {
 	providers, err := db.GetAll[models.ToolInstallation](
 		db.Equal("tenant_id", tenant_id),

+ 9 - 0
internal/utils/strings/map.go

@@ -0,0 +1,9 @@
+package strings
+
+func Map[T any, R any](slice []T, fn func(T) R) []R {
+	result := make([]R, len(slice))
+	for i, v := range slice {
+		result[i] = fn(v)
+	}
+	return result
+}