mirror of
https://github.com/cloudreve/Cloudreve.git
synced 2025-12-25 15:42:47 +00:00
151 lines
4.4 KiB
Go
151 lines
4.4 KiB
Go
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
|
|
}
|