mirror of https://github.com/cloudreve/Cloudreve
feat(dashboard): traverse file URI from file ID (#2412)
parent
65095855c1
commit
51fa9f66a5
2
assets
2
assets
|
@ -1 +1 @@
|
||||||
Subproject commit 2440a06536dd2b8053359999bb61d495220cbf9c
|
Subproject commit d674a23b21bdeb0a415985d4d5dc2b2051bc80d1
|
|
@ -450,7 +450,7 @@ func (f *DBFS) Get(ctx context.Context, path *fs.URI, opts ...fs.Option) (fs.Fil
|
||||||
return nil, fmt.Errorf("failed to get target file: %w", err)
|
return nil, fmt.Errorf("failed to get target file: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if o.notRoot && target.IsRootFolder() {
|
if o.notRoot && (target == nil || target.IsRootFolder()) {
|
||||||
return nil, fs.ErrNotSupportedAction.WithError(fmt.Errorf("cannot operate root file"))
|
return nil, fs.ErrNotSupportedAction.WithError(fmt.Errorf("cannot operate root file"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -641,6 +641,40 @@ func (f *DBFS) GetFileFromDirectLink(ctx context.Context, dl *ent.DirectLink) (f
|
||||||
return file, nil
|
return file, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *DBFS) TraverseFile(ctx context.Context, fileID int) (fs.File, error) {
|
||||||
|
fileModel, err := f.fileClient.GetByID(ctx, fileID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if fileModel.OwnerID != f.user.ID && !f.user.Edges.Group.Permissions.Enabled(int(types.GroupPermissionIsAdmin)) {
|
||||||
|
return nil, fs.ErrOwnerOnly.WithError(fmt.Errorf("only file owner can traverse file's uri"))
|
||||||
|
}
|
||||||
|
|
||||||
|
file := newFile(nil, fileModel)
|
||||||
|
|
||||||
|
// Traverse to the root file
|
||||||
|
baseNavigator := newBaseNavigator(f.fileClient, defaultFilter, f.user, f.hasher, f.settingClient.DBFS(ctx))
|
||||||
|
root, err := baseNavigator.findRoot(ctx, file)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to find root file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
rootUri := newMyUri()
|
||||||
|
if fileModel.OwnerID != f.user.ID {
|
||||||
|
rootUri = newMyIDUri(hashid.EncodeUserID(f.hasher, fileModel.OwnerID))
|
||||||
|
}
|
||||||
|
|
||||||
|
if root.Name() != inventory.RootFolderName {
|
||||||
|
rootUri = newTrashUri(root.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
root.Path[pathIndexRoot] = rootUri
|
||||||
|
root.Path[pathIndexUser] = rootUri
|
||||||
|
|
||||||
|
return file, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (f *DBFS) deleteEntity(ctx context.Context, target *File, entityId int) (inventory.StorageDiff, error) {
|
func (f *DBFS) deleteEntity(ctx context.Context, target *File, entityId int) (inventory.StorageDiff, error) {
|
||||||
if target.PrimaryEntityID() == entityId {
|
if target.PrimaryEntityID() == entityId {
|
||||||
return nil, fs.ErrNotSupportedAction.WithError(fmt.Errorf("cannot delete current version"))
|
return nil, fs.ErrNotSupportedAction.WithError(fmt.Errorf("cannot delete current version"))
|
||||||
|
|
|
@ -95,6 +95,8 @@ type (
|
||||||
VersionControl(ctx context.Context, path *URI, versionId int, delete bool) error
|
VersionControl(ctx context.Context, path *URI, versionId int, delete bool) error
|
||||||
// GetFileFromDirectLink gets a file from a direct link.
|
// GetFileFromDirectLink gets a file from a direct link.
|
||||||
GetFileFromDirectLink(ctx context.Context, dl *ent.DirectLink) (File, error)
|
GetFileFromDirectLink(ctx context.Context, dl *ent.DirectLink) (File, error)
|
||||||
|
// TraverseFile traverses a file to its root file, return the file with linked root.
|
||||||
|
TraverseFile(ctx context.Context, fileID int) (File, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
UploadManager interface {
|
UploadManager interface {
|
||||||
|
|
|
@ -55,6 +55,8 @@ type (
|
||||||
PatchMedata(ctx context.Context, path []*fs.URI, data ...fs.MetadataPatch) error
|
PatchMedata(ctx context.Context, path []*fs.URI, data ...fs.MetadataPatch) error
|
||||||
// CreateViewerSession creates a viewer session for given file
|
// CreateViewerSession creates a viewer session for given file
|
||||||
CreateViewerSession(ctx context.Context, uri *fs.URI, version string, viewer *setting.Viewer) (*ViewerSession, error)
|
CreateViewerSession(ctx context.Context, uri *fs.URI, version string, viewer *setting.Viewer) (*ViewerSession, error)
|
||||||
|
// TraverseFile traverses a file to its root file, return the file with linked root.
|
||||||
|
TraverseFile(ctx context.Context, fileID int) (fs.File, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
FsManagement interface {
|
FsManagement interface {
|
||||||
|
|
|
@ -277,6 +277,10 @@ func (l *manager) CreateOrUpdateShare(ctx context.Context, path *fs.URI, args *C
|
||||||
return share, nil
|
return share, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *manager) TraverseFile(ctx context.Context, fileID int) (fs.File, error) {
|
||||||
|
return m.fs.TraverseFile(ctx, fileID)
|
||||||
|
}
|
||||||
|
|
||||||
func getEntityDisplayName(f fs.File, e fs.Entity) string {
|
func getEntityDisplayName(f fs.File, e fs.Entity) string {
|
||||||
switch e.Type() {
|
switch e.Type() {
|
||||||
case types.EntityTypeThumbnail:
|
case types.EntityTypeThumbnail:
|
||||||
|
|
|
@ -208,6 +208,7 @@ func (service *AdminListService) Files(c *gin.Context) (*ListFileResponse, error
|
||||||
return GetFileResponse{
|
return GetFileResponse{
|
||||||
File: file,
|
File: file,
|
||||||
UserHashID: hashid.EncodeUserID(hasher, file.OwnerID),
|
UserHashID: hashid.EncodeUserID(hasher, file.OwnerID),
|
||||||
|
FileHashID: hashid.EncodeFileID(hasher, file.ID),
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
}, nil
|
}, nil
|
||||||
|
@ -251,6 +252,7 @@ func (service *SingleFileService) Get(c *gin.Context) (*GetFileResponse, error)
|
||||||
return &GetFileResponse{
|
return &GetFileResponse{
|
||||||
File: file,
|
File: file,
|
||||||
UserHashID: hashid.EncodeUserID(hasher, file.OwnerID),
|
UserHashID: hashid.EncodeUserID(hasher, file.OwnerID),
|
||||||
|
FileHashID: hashid.EncodeFileID(hasher, file.ID),
|
||||||
DirectLinkMap: directLinkMap,
|
DirectLinkMap: directLinkMap,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ type ListFileResponse struct {
|
||||||
type GetFileResponse struct {
|
type GetFileResponse struct {
|
||||||
*ent.File
|
*ent.File
|
||||||
UserHashID string `json:"user_hash_id,omitempty"`
|
UserHashID string `json:"user_hash_id,omitempty"`
|
||||||
|
FileHashID string `json:"file_hash_id,omitempty"`
|
||||||
DirectLinkMap map[int]string `json:"direct_link_map,omitempty"`
|
DirectLinkMap map[int]string `json:"direct_link_map,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -584,7 +584,8 @@ func (s *UnlockFileService) Unlock(c *gin.Context) error {
|
||||||
type (
|
type (
|
||||||
GetFileInfoParameterCtx struct{}
|
GetFileInfoParameterCtx struct{}
|
||||||
GetFileInfoService struct {
|
GetFileInfoService struct {
|
||||||
Uri string `form:"uri" binding:"required"`
|
Uri string `form:"uri"`
|
||||||
|
ID string `form:"id"`
|
||||||
ExtendedInfo bool `form:"extended"`
|
ExtendedInfo bool `form:"extended"`
|
||||||
FolderSummary bool `form:"folder_summary"`
|
FolderSummary bool `form:"folder_summary"`
|
||||||
}
|
}
|
||||||
|
@ -596,6 +597,24 @@ func (s *GetFileInfoService) Get(c *gin.Context) (*FileResponse, error) {
|
||||||
m := manager.NewFileManager(dep, user)
|
m := manager.NewFileManager(dep, user)
|
||||||
defer m.Recycle()
|
defer m.Recycle()
|
||||||
|
|
||||||
|
if s.ID != "" && s.Uri == "" {
|
||||||
|
fileId, err := dep.HashIDEncoder().Decode(s.ID, hashid.FileID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, serializer.NewError(serializer.CodeParamErr, "unknown file id", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := m.TraverseFile(c, fileId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to traverse file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.Uri = file.Uri(true).String()
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.Uri == "" {
|
||||||
|
return nil, serializer.NewError(serializer.CodeParamErr, "uri is required", nil)
|
||||||
|
}
|
||||||
|
|
||||||
uri, err := fs.NewUriFromString(s.Uri)
|
uri, err := fs.NewUriFromString(s.Uri)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, serializer.NewError(serializer.CodeParamErr, "unknown uri", err)
|
return nil, serializer.NewError(serializer.CodeParamErr, "unknown uri", err)
|
||||||
|
|
Loading…
Reference in New Issue