mirror of https://github.com/Xhofe/alist
				
				
				
			
		
			
				
	
	
		
			212 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Go
		
	
	
			
		
		
	
	
			212 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			Go
		
	
	
| package model
 | |
| 
 | |
| import (
 | |
| 	"io"
 | |
| 	"sort"
 | |
| 	"strings"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/alist-org/alist/v3/pkg/http_range"
 | |
| 	"github.com/alist-org/alist/v3/pkg/utils"
 | |
| 	"github.com/dlclark/regexp2"
 | |
| 
 | |
| 	mapset "github.com/deckarep/golang-set/v2"
 | |
| 
 | |
| 	"github.com/maruel/natural"
 | |
| )
 | |
| 
 | |
| type ObjUnwrap interface {
 | |
| 	Unwrap() Obj
 | |
| }
 | |
| 
 | |
| type Obj interface {
 | |
| 	GetSize() int64
 | |
| 	GetName() string
 | |
| 	ModTime() time.Time
 | |
| 	CreateTime() time.Time
 | |
| 	IsDir() bool
 | |
| 	GetHash() utils.HashInfo
 | |
| 
 | |
| 	// The internal information of the driver.
 | |
| 	// If you want to use it, please understand what it means
 | |
| 	GetID() string
 | |
| 	GetPath() string
 | |
| }
 | |
| 
 | |
| // FileStreamer ->check FileStream for more comments
 | |
| type FileStreamer interface {
 | |
| 	io.Reader
 | |
| 	io.Closer
 | |
| 	Obj
 | |
| 	GetMimetype() string
 | |
| 	//SetReader(io.Reader)
 | |
| 	NeedStore() bool
 | |
| 	IsForceStreamUpload() bool
 | |
| 	GetExist() Obj
 | |
| 	SetExist(Obj)
 | |
| 	//for a non-seekable Stream, RangeRead supports peeking some data, and CacheFullInTempFile still works
 | |
| 	RangeRead(http_range.Range) (io.Reader, error)
 | |
| 	//for a non-seekable Stream, if Read is called, this function won't work
 | |
| 	CacheFullInTempFile() (File, error)
 | |
| }
 | |
| 
 | |
| type URL interface {
 | |
| 	URL() string
 | |
| }
 | |
| 
 | |
| type Thumb interface {
 | |
| 	Thumb() string
 | |
| }
 | |
| 
 | |
| type SetPath interface {
 | |
| 	SetPath(path string)
 | |
| }
 | |
| 
 | |
| func SortFiles(objs []Obj, orderBy, orderDirection string) {
 | |
| 	if orderBy == "" {
 | |
| 		return
 | |
| 	}
 | |
| 	sort.Slice(objs, func(i, j int) bool {
 | |
| 		switch orderBy {
 | |
| 		case "name":
 | |
| 			{
 | |
| 				c := natural.Less(objs[i].GetName(), objs[j].GetName())
 | |
| 				if orderDirection == "desc" {
 | |
| 					return !c
 | |
| 				}
 | |
| 				return c
 | |
| 			}
 | |
| 		case "size":
 | |
| 			{
 | |
| 				if orderDirection == "desc" {
 | |
| 					return objs[i].GetSize() >= objs[j].GetSize()
 | |
| 				}
 | |
| 				return objs[i].GetSize() <= objs[j].GetSize()
 | |
| 			}
 | |
| 		case "modified":
 | |
| 			if orderDirection == "desc" {
 | |
| 				return objs[i].ModTime().After(objs[j].ModTime())
 | |
| 			}
 | |
| 			return objs[i].ModTime().Before(objs[j].ModTime())
 | |
| 		}
 | |
| 		return false
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func ExtractFolder(objs []Obj, extractFolder string) {
 | |
| 	if extractFolder == "" {
 | |
| 		return
 | |
| 	}
 | |
| 	front := extractFolder == "front"
 | |
| 	sort.SliceStable(objs, func(i, j int) bool {
 | |
| 		if objs[i].IsDir() || objs[j].IsDir() {
 | |
| 			if !objs[i].IsDir() {
 | |
| 				return !front
 | |
| 			}
 | |
| 			if !objs[j].IsDir() {
 | |
| 				return front
 | |
| 			}
 | |
| 		}
 | |
| 		return false
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func WrapObjName(objs Obj) Obj {
 | |
| 	return &ObjWrapName{Obj: objs}
 | |
| }
 | |
| 
 | |
| func WrapObjsName(objs []Obj) {
 | |
| 	for i := 0; i < len(objs); i++ {
 | |
| 		objs[i] = &ObjWrapName{Obj: objs[i]}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func UnwrapObj(obj Obj) Obj {
 | |
| 	if unwrap, ok := obj.(ObjUnwrap); ok {
 | |
| 		obj = unwrap.Unwrap()
 | |
| 	}
 | |
| 	return obj
 | |
| }
 | |
| 
 | |
| func GetThumb(obj Obj) (thumb string, ok bool) {
 | |
| 	if obj, ok := obj.(Thumb); ok {
 | |
| 		return obj.Thumb(), true
 | |
| 	}
 | |
| 	if unwrap, ok := obj.(ObjUnwrap); ok {
 | |
| 		return GetThumb(unwrap.Unwrap())
 | |
| 	}
 | |
| 	return thumb, false
 | |
| }
 | |
| 
 | |
| func GetUrl(obj Obj) (url string, ok bool) {
 | |
| 	if obj, ok := obj.(URL); ok {
 | |
| 		return obj.URL(), true
 | |
| 	}
 | |
| 	if unwrap, ok := obj.(ObjUnwrap); ok {
 | |
| 		return GetUrl(unwrap.Unwrap())
 | |
| 	}
 | |
| 	return url, false
 | |
| }
 | |
| 
 | |
| func GetRawObject(obj Obj) *Object {
 | |
| 	switch v := obj.(type) {
 | |
| 	case *ObjThumbURL:
 | |
| 		return &v.Object
 | |
| 	case *ObjThumb:
 | |
| 		return &v.Object
 | |
| 	case *ObjectURL:
 | |
| 		return &v.Object
 | |
| 	case *Object:
 | |
| 		return v
 | |
| 	}
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // Merge
 | |
| func NewObjMerge() *ObjMerge {
 | |
| 	return &ObjMerge{
 | |
| 		set: mapset.NewSet[string](),
 | |
| 	}
 | |
| }
 | |
| 
 | |
| type ObjMerge struct {
 | |
| 	regs []*regexp2.Regexp
 | |
| 	set  mapset.Set[string]
 | |
| }
 | |
| 
 | |
| func (om *ObjMerge) Merge(objs []Obj, objs_ ...Obj) []Obj {
 | |
| 	newObjs := make([]Obj, 0, len(objs)+len(objs_))
 | |
| 	newObjs = om.insertObjs(om.insertObjs(newObjs, objs...), objs_...)
 | |
| 	return newObjs
 | |
| }
 | |
| 
 | |
| func (om *ObjMerge) insertObjs(objs []Obj, objs_ ...Obj) []Obj {
 | |
| 	for _, obj := range objs_ {
 | |
| 		if om.clickObj(obj) {
 | |
| 			objs = append(objs, obj)
 | |
| 		}
 | |
| 	}
 | |
| 	return objs
 | |
| }
 | |
| 
 | |
| func (om *ObjMerge) clickObj(obj Obj) bool {
 | |
| 	for _, reg := range om.regs {
 | |
| 		if isMatch, _ := reg.MatchString(obj.GetName()); isMatch {
 | |
| 			return false
 | |
| 		}
 | |
| 	}
 | |
| 	return om.set.Add(obj.GetName())
 | |
| }
 | |
| 
 | |
| func (om *ObjMerge) InitHideReg(hides string) {
 | |
| 	rs := strings.Split(hides, "\n")
 | |
| 	om.regs = make([]*regexp2.Regexp, 0, len(rs))
 | |
| 	for _, r := range rs {
 | |
| 		om.regs = append(om.regs, regexp2.MustCompile(r, regexp2.None))
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (om *ObjMerge) Reset() {
 | |
| 	om.set.Clear()
 | |
| }
 |