From 0d3542e8bc5a48773b0fa7a351cf7b837446e877 Mon Sep 17 00:00:00 2001 From: seven <2260006962@qq.com> Date: Mon, 15 Dec 2025 16:34:45 +0800 Subject: [PATCH 1/5] feat(strm): add KeepSameNameOnly logic --- drivers/strm/hook.go | 15 ++++++++++----- drivers/strm/meta.go | 1 + 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/strm/hook.go b/drivers/strm/hook.go index 392bb014d..b88510756 100644 --- a/drivers/strm/hook.go +++ b/drivers/strm/hook.go @@ -146,12 +146,17 @@ func deleteExtraFiles(driver *Strm, localPath string, objs []model.Obj) { for _, localFile := range localFiles { if _, exists := objsSet[localFile]; !exists { ext := utils.Ext(localFile) - localFileName := stdpath.Base(localFile) - localFileBaseName := strings.TrimSuffix(localFile, utils.SourceExt(localFileName)) - _, nameExists := objsBaseNameSet[localFileBaseName[:len(localFileBaseName)-1]] _, downloadFile := driver.downloadSuffix[ext] - if driver.KeepLocalDownloadFile && nameExists && downloadFile { - continue + if driver.KeepLocalDownloadFile && downloadFile { + if !driver.KeepSameNameOnly { + continue + } + localFileName := stdpath.Base(localFile) + localFileBaseName := strings.TrimSuffix(localFile, utils.SourceExt(localFileName)) + _, nameExists := objsBaseNameSet[localFileBaseName[:len(localFileBaseName)-1]] + if nameExists { + continue + } } err := os.Remove(localFile) diff --git a/drivers/strm/meta.go b/drivers/strm/meta.go index 3575bc102..3eadf6e66 100644 --- a/drivers/strm/meta.go +++ b/drivers/strm/meta.go @@ -16,6 +16,7 @@ type Addition struct { SaveStrmToLocal bool `json:"SaveStrmToLocal" default:"false" help:"save strm file locally"` SaveStrmLocalPath string `json:"SaveStrmLocalPath" type:"text" help:"save strm file local path"` KeepLocalDownloadFile bool `json:"KeepLocalDownloadFile" default:"false" help:"keep local download files"` + KeepSameNameOnly bool `json:"KeepSameNameOnly" default:"false" help:"Keep only same name files"` Version int } From 10a746bd97ace52a91ff4b2095691cb057ce77c7 Mon Sep 17 00:00:00 2001 From: seven <2260006962@qq.com> Date: Tue, 16 Dec 2025 13:40:01 +0800 Subject: [PATCH 2/5] chore(strm): skip update strm file when keepLocalDownloadFile --- drivers/strm/hook.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/strm/hook.go b/drivers/strm/hook.go index b88510756..c736555dd 100644 --- a/drivers/strm/hook.go +++ b/drivers/strm/hook.go @@ -89,7 +89,7 @@ func RemoveStrm(dstPath string, d *Strm) { } func generateStrm(ctx context.Context, driver *Strm, obj model.Obj, localPath string) { - if !obj.IsDir() { + if !obj.IsDir() && !driver.KeepLocalDownloadFile && !utils.Exists(localPath) { link, err := driver.Link(ctx, obj, model.LinkArgs{}) if err != nil { log.Warnf("failed to generate strm of obj %s: failed to link: %v", localPath, err) From e9a054aa1bba859f7f3ed09150d5f28d1d8b5e43 Mon Sep 17 00:00:00 2001 From: seven <2260006962@qq.com> Date: Tue, 16 Dec 2025 15:44:14 +0800 Subject: [PATCH 3/5] feat(strm): add save local mode --- drivers/strm/driver.go | 3 ++ drivers/strm/hook.go | 67 ++++++++++++++++++++++++++++++++---------- drivers/strm/meta.go | 29 ++++++++++-------- 3 files changed, 72 insertions(+), 27 deletions(-) diff --git a/drivers/strm/driver.go b/drivers/strm/driver.go index da1e90cc0..422f0e1b1 100644 --- a/drivers/strm/driver.go +++ b/drivers/strm/driver.go @@ -117,6 +117,9 @@ func (d *Strm) Init(ctx context.Context) error { d.PathPrefix = "/d" d.Version = 5 } + if len(d.SaveLocalMode) == 0 { + d.SaveLocalMode = SaveLocalInsertMode + } return nil } diff --git a/drivers/strm/hook.go b/drivers/strm/hook.go index c736555dd..44a921d3d 100644 --- a/drivers/strm/hook.go +++ b/drivers/strm/hook.go @@ -1,8 +1,11 @@ package strm import ( + "bytes" "context" + "crypto/sha256" "errors" + "io" "os" stdpath "path" "strings" @@ -89,7 +92,10 @@ func RemoveStrm(dstPath string, d *Strm) { } func generateStrm(ctx context.Context, driver *Strm, obj model.Obj, localPath string) { - if !obj.IsDir() && !driver.KeepLocalDownloadFile && !utils.Exists(localPath) { + if !obj.IsDir() { + if utils.Exists(localPath) && driver.SaveLocalMode == SaveLocalInsertMode { + return + } link, err := driver.Link(ctx, obj, model.LinkArgs{}) if err != nil { log.Warnf("failed to generate strm of obj %s: failed to link: %v", localPath, err) @@ -111,6 +117,20 @@ func generateStrm(ctx context.Context, driver *Strm, obj model.Obj, localPath st return } defer rc.Close() + same, err := SameContent(localPath, size, rc) + if err != nil { + log.Warnf("failed to compare content of obj %s: %v", localPath, err) + return + } + if same { + return + } + rc, err = rrf.RangeRead(ctx, http_range.Range{Length: -1}) + if err != nil { + log.Warnf("failed to generate strm of obj %s: failed to reread range: %v", localPath, err) + return + } + defer rc.Close() file, err := utils.CreateNestedFile(localPath) if err != nil { log.Warnf("failed to generate strm of obj %s: failed to create local file: %v", localPath, err) @@ -123,7 +143,38 @@ func generateStrm(ctx context.Context, driver *Strm, obj model.Obj, localPath st } } +func SameContent(localPath string, size int64, rc io.Reader) (bool, error) { + info, err := os.Stat(localPath) + if err != nil { + if os.IsNotExist(err) { + return false, nil + } + return false, err + } + + if info.Size() != size { + return false, nil + } + localFile, err := os.Open(localPath) + if err != nil { + return false, err + } + defer localFile.Close() + h1 := sha256.New() + h2 := sha256.New() + if _, err := io.Copy(h1, localFile); err != nil { + return false, err + } + if _, err := io.Copy(h2, rc); err != nil { + return false, err + } + return bytes.Equal(h1.Sum(nil), h2.Sum(nil)), nil +} + func deleteExtraFiles(driver *Strm, localPath string, objs []model.Obj) { + if driver.SaveLocalMode != SaveLocalSyncMode { + return + } localFiles, err := getLocalFiles(localPath) if err != nil { log.Errorf("Failed to read local files from %s: %v", localPath, err) @@ -145,20 +196,6 @@ func deleteExtraFiles(driver *Strm, localPath string, objs []model.Obj) { for _, localFile := range localFiles { if _, exists := objsSet[localFile]; !exists { - ext := utils.Ext(localFile) - _, downloadFile := driver.downloadSuffix[ext] - if driver.KeepLocalDownloadFile && downloadFile { - if !driver.KeepSameNameOnly { - continue - } - localFileName := stdpath.Base(localFile) - localFileBaseName := strings.TrimSuffix(localFile, utils.SourceExt(localFileName)) - _, nameExists := objsBaseNameSet[localFileBaseName[:len(localFileBaseName)-1]] - if nameExists { - continue - } - } - err := os.Remove(localFile) if err != nil { log.Errorf("Failed to delete file: %s, error: %v\n", localFile, err) diff --git a/drivers/strm/meta.go b/drivers/strm/meta.go index 3eadf6e66..4ec8600d9 100644 --- a/drivers/strm/meta.go +++ b/drivers/strm/meta.go @@ -5,19 +5,24 @@ import ( "github.com/OpenListTeam/OpenList/v4/internal/op" ) +const ( + SaveLocalInsertMode = "insert" + SaveLocalUpdateMode = "update" + SaveLocalSyncMode = "sync" +) + type Addition struct { - Paths string `json:"paths" required:"true" type:"text"` - SiteUrl string `json:"siteUrl" type:"text" required:"false" help:"The prefix URL of the strm file"` - PathPrefix string `json:"PathPrefix" type:"text" required:"false" default:"/d" help:"Path prefix"` - DownloadFileTypes string `json:"downloadFileTypes" type:"text" default:"ass,srt,vtt,sub,strm" required:"false" help:"Files need to download with strm (usally subtitles)"` - FilterFileTypes string `json:"filterFileTypes" type:"text" default:"mp4,mkv,flv,avi,wmv,ts,rmvb,webm,mp3,flac,aac,wav,ogg,m4a,wma,alac" required:"false" help:"Supports suffix name of strm file"` - EncodePath bool `json:"encodePath" default:"true" required:"true" help:"encode the path in the strm file"` - WithoutUrl bool `json:"withoutUrl" default:"false" help:"strm file content without URL prefix"` - SaveStrmToLocal bool `json:"SaveStrmToLocal" default:"false" help:"save strm file locally"` - SaveStrmLocalPath string `json:"SaveStrmLocalPath" type:"text" help:"save strm file local path"` - KeepLocalDownloadFile bool `json:"KeepLocalDownloadFile" default:"false" help:"keep local download files"` - KeepSameNameOnly bool `json:"KeepSameNameOnly" default:"false" help:"Keep only same name files"` - Version int + Paths string `json:"paths" required:"true" type:"text"` + SiteUrl string `json:"siteUrl" type:"text" required:"false" help:"The prefix URL of the strm file"` + PathPrefix string `json:"PathPrefix" type:"text" required:"false" default:"/d" help:"Path prefix"` + DownloadFileTypes string `json:"downloadFileTypes" type:"text" default:"ass,srt,vtt,sub,strm" required:"false" help:"Files need to download with strm (usally subtitles)"` + FilterFileTypes string `json:"filterFileTypes" type:"text" default:"mp4,mkv,flv,avi,wmv,ts,rmvb,webm,mp3,flac,aac,wav,ogg,m4a,wma,alac" required:"false" help:"Supports suffix name of strm file"` + EncodePath bool `json:"encodePath" default:"true" required:"true" help:"encode the path in the strm file"` + WithoutUrl bool `json:"withoutUrl" default:"false" help:"strm file content without URL prefix"` + SaveStrmToLocal bool `json:"SaveStrmToLocal" default:"false" help:"save strm file locally"` + SaveStrmLocalPath string `json:"SaveStrmLocalPath" type:"text" help:"save strm file local path"` + SaveLocalMode string `json:"SaveLocalMode" type:"select" help:"save strm file locally mode" options:"insert,update,sync" default:"insert"` + Version int } var config = driver.Config{ From a6b98a264cc64404836be402df15deb4225f11d6 Mon Sep 17 00:00:00 2001 From: seven <2260006962@qq.com> Date: Sat, 20 Dec 2025 14:12:39 +0800 Subject: [PATCH 4/5] chore --- drivers/strm/hook.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/strm/hook.go b/drivers/strm/hook.go index 44a921d3d..8c69a35b0 100644 --- a/drivers/strm/hook.go +++ b/drivers/strm/hook.go @@ -117,7 +117,7 @@ func generateStrm(ctx context.Context, driver *Strm, obj model.Obj, localPath st return } defer rc.Close() - same, err := SameContent(localPath, size, rc) + same, err := isSameContent(localPath, size, rc) if err != nil { log.Warnf("failed to compare content of obj %s: %v", localPath, err) return @@ -143,7 +143,7 @@ func generateStrm(ctx context.Context, driver *Strm, obj model.Obj, localPath st } } -func SameContent(localPath string, size int64, rc io.Reader) (bool, error) { +func isSameContent(localPath string, size int64, rc io.Reader) (bool, error) { info, err := os.Stat(localPath) if err != nil { if os.IsNotExist(err) { From 6cc0141383f871aa3f4ef8a01866d0e7dc1ef396 Mon Sep 17 00:00:00 2001 From: seven <2260006962@qq.com> Date: Mon, 22 Dec 2025 00:17:28 +0800 Subject: [PATCH 5/5] chore --- drivers/strm/meta.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/strm/meta.go b/drivers/strm/meta.go index 5939b6301..efb9defa6 100644 --- a/drivers/strm/meta.go +++ b/drivers/strm/meta.go @@ -23,8 +23,8 @@ type Addition struct { SaveStrmToLocal bool `json:"SaveStrmToLocal" default:"false" help:"save strm file locally"` SaveStrmLocalPath string `json:"SaveStrmLocalPath" type:"text" help:"save strm file local path"` KeepLocalDownloadFile bool `json:"KeepLocalDownloadFile" default:"false" help:"keep local download files"` - SaveLocalMode string `json:"SaveLocalMode" type:"select" help:"save strm file locally mode" options:"insert,update,sync" default:"insert"` - Version int + SaveLocalMode string `json:"SaveLocalMode" type:"select" help:"save strm file locally mode" options:"insert,update,sync" default:"insert"` + Version int } var config = driver.Config{