chore: 初始化 Cloudreve 源码仓库
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
package dbfs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/auth/requestinfo"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/eventhub"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/fs"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/hashid"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
func (f *DBFS) emitFileCreated(ctx context.Context, file *File) {
|
||||
subscribers := f.getEligibleSubscriber(ctx, file, true)
|
||||
for _, subscriber := range subscribers {
|
||||
subscriber.Publish(eventhub.Event{
|
||||
Type: eventhub.EventTypeCreate,
|
||||
FileID: hashid.EncodeFileID(f.hasher, file.Model.ID),
|
||||
From: subscriber.relativePath(file),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (f *DBFS) emitFileModified(ctx context.Context, file *File) {
|
||||
subscribers := f.getEligibleSubscriber(ctx, file, true)
|
||||
for _, subscriber := range subscribers {
|
||||
subscriber.Publish(eventhub.Event{
|
||||
Type: eventhub.EventTypeModify,
|
||||
FileID: hashid.EncodeFileID(f.hasher, file.Model.ID),
|
||||
From: subscriber.relativePath(file),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (f *DBFS) emitFileRenamed(ctx context.Context, file *File, newName string) {
|
||||
subscribers := f.getEligibleSubscriber(ctx, file, true)
|
||||
for _, subscriber := range subscribers {
|
||||
from := subscriber.relativePath(file)
|
||||
to := strings.TrimSuffix(from, file.Name()) + newName
|
||||
subscriber.Publish(eventhub.Event{
|
||||
Type: eventhub.EventTypeRename,
|
||||
FileID: hashid.EncodeFileID(f.hasher, file.Model.ID),
|
||||
From: subscriber.relativePath(file),
|
||||
To: to,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (f *DBFS) emitFileDeleted(ctx context.Context, files ...*File) {
|
||||
for _, file := range files {
|
||||
subscribers := f.getEligibleSubscriber(ctx, file, true)
|
||||
for _, subscriber := range subscribers {
|
||||
subscriber.Publish(eventhub.Event{
|
||||
Type: eventhub.EventTypeDelete,
|
||||
FileID: hashid.EncodeFileID(f.hasher, file.Model.ID),
|
||||
From: subscriber.relativePath(file),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (f *DBFS) emitFileMoved(ctx context.Context, src, dst *File) {
|
||||
srcSubMap := lo.SliceToMap(f.getEligibleSubscriber(ctx, src, true), func(subscriber foundSubscriber) (string, *foundSubscriber) {
|
||||
return subscriber.ID(), &subscriber
|
||||
})
|
||||
dstSubMap := lo.SliceToMap(f.getEligibleSubscriber(ctx, dst, false), func(subscriber foundSubscriber) (string, *foundSubscriber) {
|
||||
return subscriber.ID(), &subscriber
|
||||
})
|
||||
|
||||
for _, subscriber := range srcSubMap {
|
||||
subId := subscriber.ID()
|
||||
if dstSub, ok := dstSubMap[subId]; ok {
|
||||
// Src and Dst subscribed by the same subscriber
|
||||
subscriber.Publish(eventhub.Event{
|
||||
Type: eventhub.EventTypeRename,
|
||||
FileID: hashid.EncodeFileID(f.hasher, src.Model.ID),
|
||||
From: subscriber.relativePath(src),
|
||||
To: path.Join(dstSub.relativePath(dst), src.Name()),
|
||||
})
|
||||
delete(dstSubMap, subId)
|
||||
} else {
|
||||
// Only Src is subscribed by the subscriber
|
||||
subscriber.Publish(eventhub.Event{
|
||||
Type: eventhub.EventTypeDelete,
|
||||
FileID: hashid.EncodeFileID(f.hasher, src.Model.ID),
|
||||
From: subscriber.relativePath(src),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
for _, subscriber := range dstSubMap {
|
||||
// Only Dst is subscribed by the subscriber
|
||||
subscriber.Publish(eventhub.Event{
|
||||
Type: eventhub.EventTypeCreate,
|
||||
FileID: hashid.EncodeFileID(f.hasher, src.Model.ID),
|
||||
From: path.Join(subscriber.relativePath(dst), src.Name()),
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (f *DBFS) getEligibleSubscriber(ctx context.Context, file *File, checkParentPerm bool) []foundSubscriber {
|
||||
roots := file.Ancestors()
|
||||
if !checkParentPerm {
|
||||
// Include file itself
|
||||
roots = file.AncestorsChain()
|
||||
}
|
||||
requestInfo := requestinfo.RequestInfoFromContext(ctx)
|
||||
eligibleSubscribers := make([]foundSubscriber, 0)
|
||||
|
||||
for _, root := range roots {
|
||||
subscribers := f.eventHub.GetSubscribers(ctx, root.Model.ID)
|
||||
subscribers = lo.Filter(subscribers, func(subscriber eventhub.Subscriber, index int) bool {
|
||||
// Exlucde self from subscribers
|
||||
if requestInfo != nil && subscriber.ID() == requestInfo.ClientID {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
eligibleSubscribers = append(eligibleSubscribers, lo.Map(subscribers, func(subscriber eventhub.Subscriber, index int) foundSubscriber {
|
||||
return foundSubscriber{
|
||||
Subscriber: subscriber,
|
||||
root: root,
|
||||
}
|
||||
})...)
|
||||
}
|
||||
|
||||
return eligibleSubscribers
|
||||
|
||||
}
|
||||
|
||||
type foundSubscriber struct {
|
||||
eventhub.Subscriber
|
||||
root *File
|
||||
}
|
||||
|
||||
func (s *foundSubscriber) relativePath(file *File) string {
|
||||
res := strings.TrimPrefix(file.Uri(true).Path(), s.root.Uri(true).Path())
|
||||
if res == "" {
|
||||
res = fs.Separator
|
||||
}
|
||||
|
||||
if res[0] != fs.Separator[0] {
|
||||
res = fs.Separator + res
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
Reference in New Issue
Block a user