Spaces:
Paused
Paused
| 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() | |
| } | |