memory_zip.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. package bundle_packager
  2. import (
  3. "archive/zip"
  4. "bytes"
  5. "io"
  6. "path/filepath"
  7. "strings"
  8. "github.com/langgenius/dify-plugin-daemon/internal/utils/parser"
  9. "github.com/langgenius/dify-plugin-daemon/pkg/entities/bundle_entities"
  10. )
  11. type MemoryZipBundlePackager struct {
  12. GenericBundlePackager
  13. zipReader *zip.Reader
  14. }
  15. func NewMemoryZipBundlePackager(zipFile []byte) (*MemoryZipBundlePackager, error) {
  16. // try read manifest file
  17. zipReader, err := zip.NewReader(bytes.NewReader(zipFile), int64(len(zipFile)))
  18. if err != nil {
  19. return nil, err
  20. }
  21. manifestFile, err := zipReader.Open("manifest.yaml")
  22. if err != nil {
  23. return nil, err
  24. }
  25. defer manifestFile.Close()
  26. manifestBytes, err := io.ReadAll(manifestFile)
  27. if err != nil {
  28. return nil, err
  29. }
  30. bundle, err := parser.UnmarshalYamlBytes[bundle_entities.Bundle](manifestBytes)
  31. if err != nil {
  32. return nil, err
  33. }
  34. // collect files starts with README
  35. extraFiles := make(map[string]*bytes.Buffer)
  36. for _, file := range zipReader.File {
  37. if strings.HasPrefix(file.Name, "README") {
  38. buffer := bytes.NewBuffer([]byte{})
  39. readFile, err := file.Open()
  40. if err != nil {
  41. return nil, err
  42. }
  43. defer readFile.Close()
  44. io.Copy(buffer, readFile)
  45. extraFiles[file.Name] = buffer
  46. }
  47. }
  48. packager := &MemoryZipBundlePackager{
  49. GenericBundlePackager: *NewGenericBundlePackager(&bundle, extraFiles),
  50. zipReader: zipReader,
  51. }
  52. // walk through the zip file and load the assets
  53. for _, file := range zipReader.File {
  54. // if file starts with "_assets/"
  55. if strings.HasPrefix(file.Name, "_assets"+string(filepath.Separator)) {
  56. // load the asset
  57. asset, err := file.Open()
  58. if err != nil {
  59. return nil, err
  60. }
  61. defer asset.Close()
  62. assetBytes, err := io.ReadAll(asset)
  63. if err != nil {
  64. return nil, err
  65. }
  66. // trim the prefix "_assets/"
  67. assetName := strings.TrimPrefix(file.Name, "_assets"+string(filepath.Separator))
  68. packager.assets[assetName] = bytes.NewBuffer(assetBytes)
  69. }
  70. }
  71. return packager, nil
  72. }
  73. func (p *MemoryZipBundlePackager) Save() error {
  74. return nil
  75. }
  76. func (p *MemoryZipBundlePackager) ReadFile(path string) ([]byte, error) {
  77. // read the file from the zip reader
  78. file, err := p.zipReader.Open(path)
  79. if err != nil {
  80. return nil, err
  81. }
  82. defer file.Close()
  83. return io.ReadAll(file)
  84. }