2022-06-15 12:41:17 +00:00
|
|
|
package model
|
|
|
|
|
|
|
|
import (
|
|
|
|
"io"
|
2022-06-27 11:10:02 +00:00
|
|
|
"sort"
|
2022-12-18 11:51:20 +00:00
|
|
|
"strings"
|
2022-06-15 12:41:17 +00:00
|
|
|
"time"
|
2022-12-06 09:28:18 +00:00
|
|
|
|
2023-10-10 10:08:27 +00:00
|
|
|
"github.com/alist-org/alist/v3/pkg/http_range"
|
|
|
|
"github.com/alist-org/alist/v3/pkg/utils"
|
2023-12-31 07:03:25 +00:00
|
|
|
"github.com/dlclark/regexp2"
|
2023-10-10 10:08:27 +00:00
|
|
|
|
2022-12-18 11:51:20 +00:00
|
|
|
mapset "github.com/deckarep/golang-set/v2"
|
|
|
|
|
2022-12-06 09:28:18 +00:00
|
|
|
"github.com/maruel/natural"
|
2022-06-15 12:41:17 +00:00
|
|
|
)
|
|
|
|
|
2023-01-16 09:33:24 +00:00
|
|
|
type ObjUnwrap interface {
|
2022-12-17 11:49:05 +00:00
|
|
|
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
|
2023-08-27 13:14:23 +00:00
|
|
|
CreateTime() time.Time
|
2022-06-15 12:41:17 +00:00
|
|
|
IsDir() bool
|
2023-08-27 13:14:23 +00:00
|
|
|
GetHash() utils.HashInfo
|
2022-12-17 11:49:05 +00:00
|
|
|
|
|
|
|
// 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
|
|
|
}
|
|
|
|
|
2023-08-27 13:14:23 +00:00
|
|
|
// FileStreamer ->check FileStream for more comments
|
2022-06-15 12:41:17 +00:00
|
|
|
type FileStreamer interface {
|
2023-08-27 13:14:23 +00:00
|
|
|
io.Reader
|
|
|
|
io.Closer
|
2022-06-15 12:41:17 +00:00
|
|
|
Obj
|
|
|
|
GetMimetype() string
|
2023-08-27 13:14:23 +00:00
|
|
|
//SetReader(io.Reader)
|
2022-07-01 07:04:02 +00:00
|
|
|
NeedStore() bool
|
2023-08-27 13:14:23 +00:00
|
|
|
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":
|
|
|
|
{
|
2022-12-06 09:28:18 +00:00
|
|
|
c := natural.Less(objs[i].GetName(), objs[j].GetName())
|
2022-07-27 07:49:18 +00:00
|
|
|
if orderDirection == "desc" {
|
2022-12-06 09:28:18 +00:00
|
|
|
return !c
|
2022-06-27 11:10:02 +00:00
|
|
|
}
|
2022-12-06 09:28:18 +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()
|
|
|
|
}
|
2022-09-23 04:30:32 +00:00
|
|
|
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
|
|
|
|
})
|
|
|
|
}
|
2022-12-17 11:49:05 +00:00
|
|
|
|
2022-12-20 07:02:40 +00:00
|
|
|
func WrapObjName(objs Obj) Obj {
|
|
|
|
return &ObjWrapName{Obj: objs}
|
|
|
|
}
|
|
|
|
|
2022-12-17 11:49:05 +00:00
|
|
|
func WrapObjsName(objs []Obj) {
|
|
|
|
for i := 0; i < len(objs); i++ {
|
|
|
|
objs[i] = &ObjWrapName{Obj: objs[i]}
|
|
|
|
}
|
|
|
|
}
|
2022-12-18 11:51:20 +00:00
|
|
|
|
2023-01-16 09:33:24 +00:00
|
|
|
func UnwrapObj(obj Obj) Obj {
|
|
|
|
if unwrap, ok := obj.(ObjUnwrap); ok {
|
2022-12-20 07:02:40 +00:00
|
|
|
obj = unwrap.Unwrap()
|
|
|
|
}
|
|
|
|
return obj
|
|
|
|
}
|
|
|
|
|
|
|
|
func GetThumb(obj Obj) (thumb string, ok bool) {
|
|
|
|
if obj, ok := obj.(Thumb); ok {
|
|
|
|
return obj.Thumb(), true
|
|
|
|
}
|
2023-01-16 09:33:24 +00:00
|
|
|
if unwrap, ok := obj.(ObjUnwrap); ok {
|
2022-12-20 07:02:40 +00:00
|
|
|
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
|
|
|
|
}
|
2023-01-16 09:33:24 +00:00
|
|
|
if unwrap, ok := obj.(ObjUnwrap); ok {
|
2022-12-20 07:02:40 +00:00
|
|
|
return GetUrl(unwrap.Unwrap())
|
|
|
|
}
|
|
|
|
return url, false
|
|
|
|
}
|
|
|
|
|
2023-10-10 10:08:27 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2022-12-20 07:02:40 +00:00
|
|
|
// Merge
|
2022-12-18 11:51:20 +00:00
|
|
|
func NewObjMerge() *ObjMerge {
|
|
|
|
return &ObjMerge{
|
|
|
|
set: mapset.NewSet[string](),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type ObjMerge struct {
|
2023-12-31 07:03:25 +00:00
|
|
|
regs []*regexp2.Regexp
|
2022-12-18 11:51:20 +00:00
|
|
|
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 {
|
2023-12-31 07:03:25 +00:00
|
|
|
if isMatch, _ := reg.MatchString(obj.GetName()); isMatch {
|
2022-12-18 11:51:20 +00:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return om.set.Add(obj.GetName())
|
|
|
|
}
|
|
|
|
|
|
|
|
func (om *ObjMerge) InitHideReg(hides string) {
|
|
|
|
rs := strings.Split(hides, "\n")
|
2023-12-31 07:03:25 +00:00
|
|
|
om.regs = make([]*regexp2.Regexp, 0, len(rs))
|
2022-12-18 11:51:20 +00:00
|
|
|
for _, r := range rs {
|
2023-12-31 07:03:25 +00:00
|
|
|
om.regs = append(om.regs, regexp2.MustCompile(r, regexp2.None))
|
2022-12-18 11:51:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (om *ObjMerge) Reset() {
|
|
|
|
om.set.Clear()
|
|
|
|
}
|