alist/internal/model/obj.go

212 lines
4.0 KiB
Go
Raw Normal View History

2022-06-15 12:41:17 +00:00
package model
import (
"io"
2022-06-27 11:10:02 +00:00
"sort"
"strings"
2022-06-15 12:41:17 +00:00
"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"
2022-06-15 12:41:17 +00:00
)
type ObjUnwrap interface {
Unwrap() Obj
}
2022-06-15 12:41:17 +00:00
type Obj interface {
2022-06-23 07:57:36 +00:00
GetSize() int64
2022-06-15 12:41:17 +00:00
GetName() string
ModTime() time.Time
CreateTime() time.Time
2022-06-15 12:41:17 +00:00
IsDir() bool
GetHash() utils.HashInfo
// The internal information of the driver.
// If you want to use it, please understand what it means
2022-06-15 12:41:17 +00:00
GetID() string
2022-09-02 14:46:31 +00:00
GetPath() string
2022-06-15 12:41:17 +00:00
}
// FileStreamer ->check FileStream for more comments
2022-06-15 12:41:17 +00:00
type FileStreamer interface {
io.Reader
io.Closer
2022-06-15 12:41:17 +00:00
Obj
GetMimetype() string
//SetReader(io.Reader)
2022-07-01 07:04:02 +00:00
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)
2022-06-15 12:41:17 +00:00
}
type URL interface {
URL() string
}
2022-08-11 12:32:17 +00:00
type Thumb interface {
Thumb() string
2022-06-15 12:41:17 +00:00
}
2022-06-16 12:25:33 +00:00
2022-09-02 14:46:31 +00:00
type SetPath interface {
SetPath(path string)
2022-06-16 12:25:33 +00:00
}
2022-06-27 11:10:02 +00:00
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())
2022-07-27 07:49:18 +00:00
if orderDirection == "desc" {
return !c
2022-06-27 11:10:02 +00:00
}
return c
2022-06-27 11:10:02 +00:00
}
case "size":
{
2022-07-27 07:49:18 +00:00
if orderDirection == "desc" {
2022-06-27 11:10:02 +00:00
return objs[i].GetSize() >= objs[j].GetSize()
}
return objs[i].GetSize() <= objs[j].GetSize()
}
case "modified":
2022-07-27 07:49:18 +00:00
if orderDirection == "desc" {
2022-06-27 11:10:02 +00:00
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()
}