| package model |
|
|
| import ( |
| "io" |
| "sort" |
| "strings" |
| "time" |
|
|
| "github.com/OpenListTeam/OpenList/v4/pkg/http_range" |
| "github.com/OpenListTeam/OpenList/v4/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 |
|
|
| |
| |
| GetID() string |
| GetPath() string |
| } |
|
|
| |
| type FileStreamer interface { |
| io.Reader |
| utils.ClosersIF |
| Obj |
| GetMimetype() string |
| NeedStore() bool |
| IsForceStreamUpload() bool |
| GetExist() Obj |
| SetExist(Obj) |
| |
| RangeRead(http_range.Range) (io.Reader, error) |
| |
| |
| CacheFullAndWriter(up *UpdateProgress, writer io.Writer) (File, error) |
| |
| GetFile() File |
| } |
|
|
| type UpdateProgress func(percentage float64) |
|
|
| func UpdateProgressWithRange(inner UpdateProgress, start, end float64) UpdateProgress { |
| return func(p float64) { |
| if p < 0 { |
| p = 0 |
| } |
| if p > 100 { |
| p = 100 |
| } |
| scaled := start + (end-start)*(p/100.0) |
| inner(scaled) |
| } |
| } |
|
|
| type URL interface { |
| URL() string |
| } |
|
|
| type Thumb interface { |
| Thumb() string |
| } |
|
|
| type SetPath interface { |
| SetPath(path string) |
| } |
|
|
| type ObjWithProvider interface { |
| GetProvider() 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{Name: utils.MappingName(objs.GetName()), Obj: objs} |
| } |
|
|
| func WrapObjsName(objs []Obj) { |
| for i := range objs { |
| objs[i] = &ObjWrapName{Name: utils.MappingName(objs[i].GetName()), Obj: objs[i]} |
| } |
| } |
|
|
| func UnwrapObjName(obj Obj) Obj { |
| if n, ok := obj.(*ObjWrapName); ok { |
| return n.Obj |
| } |
| return obj |
| } |
|
|
| func GetThumb(obj Obj) (thumb string, ok bool) { |
| for { |
| switch o := obj.(type) { |
| case Thumb: |
| return o.Thumb(), true |
| case ObjUnwrap: |
| obj = o.Unwrap() |
| default: |
| return |
| } |
| } |
| } |
|
|
| func GetUrl(obj Obj) (url string, ok bool) { |
| for { |
| switch o := obj.(type) { |
| case URL: |
| return o.URL(), true |
| case ObjUnwrap: |
| obj = o.Unwrap() |
| default: |
| return |
| } |
| } |
| } |
|
|
| func GetProvider(obj Obj) (string, bool) { |
| for { |
| switch o := obj.(type) { |
| case ObjWithProvider: |
| return o.GetProvider(), true |
| case ObjUnwrap: |
| obj = o.Unwrap() |
| default: |
| return "unknown", false |
| } |
| } |
| } |
|
|
| |
| 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() |
| } |
|
|
| type ObjMask uint8 |
|
|
| func (m ObjMask) GetObjMask() ObjMask { |
| return m |
| } |
|
|
| const ( |
| Virtual ObjMask = 1 << iota |
| NoRename |
| NoRemove |
| NoMove |
| NoCopy |
| NoWrite |
| Temp |
| ) |
| const ( |
| Locked = NoRename | NoRemove | NoMove |
| ReadOnly = Locked | NoWrite |
| ) |
|
|
| type ObjWrapMask struct { |
| Obj |
| Mask ObjMask |
| } |
|
|
| func (m *ObjWrapMask) Unwrap() Obj { |
| return m.Obj |
| } |
| func (m *ObjWrapMask) GetObjMask() ObjMask { |
| return m.Mask |
| } |
|
|
| func GetObjMask(obj Obj) ObjMask { |
| for { |
| switch o := obj.(type) { |
| case interface{ GetObjMask() ObjMask }: |
| return o.GetObjMask() |
| case ObjUnwrap: |
| obj = o.Unwrap() |
| default: |
| return 0 |
| } |
| } |
| } |
|
|
| func ObjHasMask(obj Obj, mask ObjMask) bool { |
| return GetObjMask(obj)&mask != 0 |
| } |
|
|