Skip to content
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
95 changes: 65 additions & 30 deletions drivers/strm/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@ package strm
import (
"context"
"errors"
"fmt"
stdpath "path"
"strings"

"github.com/OpenListTeam/OpenList/v4/internal/driver"
"github.com/OpenListTeam/OpenList/v4/internal/errs"
"github.com/OpenListTeam/OpenList/v4/internal/fs"
"github.com/OpenListTeam/OpenList/v4/internal/model"
"github.com/OpenListTeam/OpenList/v4/internal/sign"
"github.com/OpenListTeam/OpenList/v4/pkg/utils"
"github.com/OpenListTeam/OpenList/v4/server/common"
)

type Strm struct {
Expand All @@ -18,6 +22,9 @@ type Strm struct {
pathMap map[string][]string
autoFlatten bool
oneKey string

supportSuffix map[string]struct{}
downloadSuffix map[string]struct{}
}

func (d *Strm) Config() driver.Config {
Expand Down Expand Up @@ -51,12 +58,24 @@ func (d *Strm) Init(ctx context.Context) error {
d.autoFlatten = false
}

d.supportSuffix = supportSuffix()
if d.FilterFileTypes != "" {
types := strings.Split(d.FilterFileTypes, ",")
for _, ext := range types {
ext = strings.ToLower(strings.TrimSpace(ext))
if ext != "" {
supportSuffix[ext] = struct{}{}
d.supportSuffix[ext] = struct{}{}
}
}
}

d.downloadSuffix = downloadSuffix()
if d.DownloadFileTypes != "" {
downloadTypes := strings.Split(d.DownloadFileTypes, ",")
for _, ext := range downloadTypes {
ext = strings.ToLower(strings.TrimSpace(ext))
if ext != "" {
d.downloadSuffix[ext] = struct{}{}
}
}
}
Expand All @@ -65,6 +84,8 @@ func (d *Strm) Init(ctx context.Context) error {

func (d *Strm) Drop(ctx context.Context) error {
d.pathMap = nil
d.downloadSuffix = nil
d.supportSuffix = nil
return nil
}

Expand All @@ -82,10 +103,25 @@ func (d *Strm) Get(ctx context.Context, path string) (model.Obj, error) {
return nil, errs.ObjectNotFound
}
for _, dst := range dsts {
obj, err := d.get(ctx, path, dst, sub)
if err == nil {
return obj, nil
reqPath := stdpath.Join(dst, sub)
obj, err := fs.Get(ctx, reqPath, &fs.GetArgs{NoLog: true})
if err != nil {
continue
}
// fs.Get 没报错,说明不是strm生成的路径,需要直接返回
size := int64(0)
if !obj.IsDir() {
size = obj.GetSize()
path = reqPath //把路径设置为真实的,供Link直接读取
}
return &model.Object{
Path: path,
Name: obj.GetName(),
Size: size,
Modified: obj.ModTime(),
IsFolder: obj.IsDir(),
HashInfo: obj.GetHash(),
}, nil
}
return nil, errs.ObjectNotFound
}
Expand All @@ -112,34 +148,33 @@ func (d *Strm) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]
}

func (d *Strm) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
link := d.getLink(ctx, file.GetPath())
return &model.Link{
MFile: strings.NewReader(link),
}, nil
}

func (d *Strm) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
return errors.New("strm Driver cannot make dir")
}

func (d *Strm) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
return errors.New("strm Driver cannot move file")
}

func (d *Strm) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
return errors.New("strm Driver cannot rename file")
}

func (d *Strm) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
return errors.New("strm Driver cannot copy file")
}
if file.GetID() == "strm" {
link := d.getLink(ctx, file.GetPath())
return &model.Link{
MFile: strings.NewReader(link),
}, nil
}
// ftp,s3
if common.GetApiUrl(ctx) == "" {
args.Redirect = false
}
reqPath := file.GetPath()
link, _, err := d.link(ctx, reqPath, args)
if err != nil {
return nil, err
}

func (d *Strm) Remove(ctx context.Context, obj model.Obj) error {
return errors.New("strm Driver cannot remove file")
}
if link == nil {
return &model.Link{
URL: fmt.Sprintf("%s/p%s?sign=%s",
common.GetApiUrl(ctx),
utils.EncodePath(reqPath, true),
sign.Sign(reqPath)),
}, nil
}

func (d *Strm) Put(ctx context.Context, dstDir model.Obj, s model.FileStreamer, up driver.UpdateProgress) error {
return errors.New("strm Driver cannot put file")
// 没有修改link的字段,可直接返回
return link, nil
}

var _ driver.Driver = (*Strm)(nil)
11 changes: 6 additions & 5 deletions drivers/strm/meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import (
)

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"`
FilterFileTypes string `json:"filterFileTypes" type:"text" default:"strm" 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"`
LocalModel bool `json:"localModel" default:"false" help:"enable local mode"`
Paths string `json:"paths" required:"true" type:"text"`
SiteUrl string `json:"siteUrl" type:"text" required:"false" help:"The prefix URL of the strm file"`
FilterFileTypes string `json:"filterFileTypes" type:"text" default:"strm" required:"false" help:"Supports suffix name of strm file"`
DownloadFileTypes string `json:"downloadFileTypes" type:"text" default:"ass" required:"false" help:"Files need to download with strm (usally subtitles)"`
EncodePath bool `json:"encodePath" default:"true" required:"true" help:"encode the path in the strm file"`
LocalModel bool `json:"localModel" default:"false" help:"enable local mode"`
}

var config = driver.Config{
Expand Down
52 changes: 33 additions & 19 deletions drivers/strm/types.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,36 @@
package strm

var supportSuffix = map[string]struct{}{
// video
"mp4": {},
"mkv": {},
"flv": {},
"avi": {},
"wmv": {},
"ts": {},
"rmvb": {},
"webm": {},
// audio
"mp3": {},
"flac": {},
"aac": {},
"wav": {},
"ogg": {},
"m4a": {},
"wma": {},
"alac": {},
func supportSuffix() map[string]struct{} {
return map[string]struct{}{
// video
"mp4": {},
"mkv": {},
"flv": {},
"avi": {},
"wmv": {},
"ts": {},
"rmvb": {},
"webm": {},
// audio
"mp3": {},
"flac": {},
"aac": {},
"wav": {},
"ogg": {},
"m4a": {},
"wma": {},
"alac": {},
}
}

func downloadSuffix() map[string]struct{} {
return map[string]struct{}{
// strm
"strm": {},
// subtitles
"ass": {},
"srt": {},
"vtt": {},
"sub": {},
}
}
83 changes: 38 additions & 45 deletions drivers/strm/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/OpenListTeam/OpenList/v4/internal/fs"
"github.com/OpenListTeam/OpenList/v4/internal/model"
"github.com/OpenListTeam/OpenList/v4/internal/op"
"github.com/OpenListTeam/OpenList/v4/internal/sign"
"github.com/OpenListTeam/OpenList/v4/pkg/utils"
"github.com/OpenListTeam/OpenList/v4/server/common"
Expand Down Expand Up @@ -51,31 +52,6 @@ func (d *Strm) getRootAndPath(path string) (string, string) {
return parts[0], parts[1]
}

func (d *Strm) get(ctx context.Context, path string, dst, sub string) (model.Obj, error) {
reqPath := stdpath.Join(dst, sub)
obj, err := fs.Get(ctx, reqPath, &fs.GetArgs{NoLog: true})
if err != nil {
return nil, err
}
size := int64(0)
if !obj.IsDir() {
if utils.Ext(obj.GetName()) == "strm" {
size = obj.GetSize()
} else {
file := stdpath.Join(reqPath, obj.GetName())
size = int64(len(d.getLink(ctx, file)))
}
}
return &model.Object{
Path: path,
Name: obj.GetName(),
Size: size,
Modified: obj.ModTime(),
IsFolder: obj.IsDir(),
HashInfo: obj.GetHash(),
}, nil
}

func (d *Strm) list(ctx context.Context, dst, sub string, args *fs.ListArgs) ([]model.Obj, error) {
reqPath := stdpath.Join(dst, sub)
objs, err := fs.List(ctx, reqPath, args)
Expand All @@ -85,45 +61,44 @@ func (d *Strm) list(ctx context.Context, dst, sub string, args *fs.ListArgs) ([]

var validObjs []model.Obj
for _, obj := range objs {
if !obj.IsDir() {
ext := strings.ToLower(utils.Ext(obj.GetName()))
if _, ok := supportSuffix[ext]; !ok {
continue
}
}
validObjs = append(validObjs, obj)
}
return utils.SliceConvert(validObjs, func(obj model.Obj) (model.Obj, error) {
name := obj.GetName()
id, name, path := "", obj.GetName(), ""
size := int64(0)
if !obj.IsDir() {
ext := utils.Ext(name)
name = strings.TrimSuffix(name, ext) + "strm"
if ext == "strm" {
path = stdpath.Join(reqPath, obj.GetName())
ext := strings.ToLower(utils.Ext(name))
if _, ok := d.supportSuffix[ext]; ok {
id = "strm"
name = strings.TrimSuffix(name, ext) + "strm"
size = int64(len(d.getLink(ctx, path)))
} else if _, ok := d.downloadSuffix[ext]; ok {
size = obj.GetSize()
} else {
file := stdpath.Join(reqPath, obj.GetName())
size = int64(len(d.getLink(ctx, file)))
continue
}
}
objRes := model.Object{
ID: id,
Path: path,
Name: name,
Size: size,
Modified: obj.ModTime(),
IsFolder: obj.IsDir(),
Path: stdpath.Join(reqPath, obj.GetName()),
}

thumb, ok := model.GetThumb(obj)
if !ok {
return &objRes, nil
validObjs = append(validObjs, &objRes)
continue
}
return &model.ObjThumb{

validObjs = append(validObjs, &model.ObjThumb{
Object: objRes,
Thumbnail: model.Thumbnail{
Thumbnail: thumb,
},
}, nil
})
})
}
return validObjs, nil
}

func (d *Strm) getLink(ctx context.Context, path string) string {
Expand All @@ -149,3 +124,21 @@ func (d *Strm) getLink(ctx context.Context, path string) string {
apiUrl,
finalPath)
}

func (d *Strm) link(ctx context.Context, reqPath string, args model.LinkArgs) (*model.Link, model.Obj, error) {
storage, reqActualPath, err := op.GetStorageAndActualPath(reqPath)
if err != nil {
return nil, nil, err
}
if !args.Redirect {
return op.Link(ctx, storage, reqActualPath, args)
}
obj, err := fs.Get(ctx, reqPath, &fs.GetArgs{NoLog: true})
if err != nil {
return nil, nil, err
}
if common.ShouldProxy(storage, stdpath.Base(reqPath)) {
return nil, obj, nil
}
return op.Link(ctx, storage, reqActualPath, args)
}