zip.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. package bundle_packager
  2. import (
  3. "archive/zip"
  4. "bytes"
  5. "io"
  6. "os"
  7. "strings"
  8. "github.com/langgenius/dify-plugin-daemon/internal/types/entities/bundle_entities"
  9. "github.com/langgenius/dify-plugin-daemon/internal/utils/parser"
  10. )
  11. type ZipBundlePackager struct {
  12. GenericBundlePackager
  13. zipReader *zip.Reader
  14. path string
  15. }
  16. func NewZipBundlePackager(path string) (BundlePackager, error) {
  17. zipFile, err := os.Open(path)
  18. if err != nil {
  19. return nil, err
  20. }
  21. defer zipFile.Close()
  22. zipFileInfo, err := zipFile.Stat()
  23. if err != nil {
  24. return nil, err
  25. }
  26. zipReader, err := zip.NewReader(zipFile, zipFileInfo.Size())
  27. if err != nil {
  28. return nil, err
  29. }
  30. // try read manifest file
  31. manifestFile, err := zipReader.Open("manifest.yaml")
  32. if err != nil {
  33. return nil, err
  34. }
  35. defer manifestFile.Close()
  36. manifestBytes, err := io.ReadAll(manifestFile)
  37. if err != nil {
  38. return nil, err
  39. }
  40. bundle, err := parser.UnmarshalYamlBytes[bundle_entities.Bundle](manifestBytes)
  41. if err != nil {
  42. return nil, err
  43. }
  44. packager := &ZipBundlePackager{
  45. GenericBundlePackager: *NewGenericBundlePackager(&bundle),
  46. zipReader: zipReader,
  47. path: path,
  48. }
  49. // walk through the zip file and load the assets
  50. for _, file := range zipReader.File {
  51. // if file starts with "assets/"
  52. if strings.HasPrefix(file.Name, "assets/") {
  53. // load the asset
  54. asset, err := file.Open()
  55. if err != nil {
  56. return nil, err
  57. }
  58. defer asset.Close()
  59. assetBytes, err := io.ReadAll(asset)
  60. if err != nil {
  61. return nil, err
  62. }
  63. // trim the prefix "assets/"
  64. assetName := strings.TrimPrefix(file.Name, "assets/")
  65. packager.assets[assetName] = bytes.NewBuffer(assetBytes)
  66. }
  67. }
  68. return packager, nil
  69. }
  70. func (p *ZipBundlePackager) Save() error {
  71. // export the bundle to a zip file
  72. zipBytes, err := p.Export()
  73. if err != nil {
  74. return err
  75. }
  76. // save the zip file
  77. err = os.WriteFile(p.path, zipBytes, 0644)
  78. if err != nil {
  79. return err
  80. }
  81. // reload zip reader
  82. zipFile, err := os.Open(p.path)
  83. if err != nil {
  84. return err
  85. }
  86. defer zipFile.Close()
  87. zipFileInfo, err := zipFile.Stat()
  88. if err != nil {
  89. return err
  90. }
  91. p.zipReader, err = zip.NewReader(zipFile, zipFileInfo.Size())
  92. if err != nil {
  93. return err
  94. }
  95. return nil
  96. }