personal-website/webfilesystem/directory.go

269 lines
6.0 KiB
Go

package webfilesystem
import (
"context"
"errors"
"strconv"
"github.com/mitchellh/mapstructure"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
)
type DirectoryData struct {
Parent primitive.ObjectID `bson:"parent"`
Children []primitive.ObjectID `bson:"children"`
}
//Deprecated
func (fs *WebFileSystem) List(dirPath string) ([]*OnlyHeaderFile, error) {
fileId, err := fs.FindFile(dirPath)
if err != nil {
return nil, err
}
read := ReadStruct2{
File: &DirectoryFile{},
Id: fileId,
}
fileRaw, err := fs.Read(read)
if err != nil {
return nil, err
}
var dirPtr interface{} = *fileRaw
dir := dirPtr.(*DirectoryFile)
children := []*OnlyHeaderFile{}
for _, childID := range dir.Data.Children {
read := ReadStruct2{
File: &OnlyHeaderFile{},
Id: childID,
}
childFile, err := fs.Read(read)
if err != nil {
// println(err.Error())
continue
}
var dirPtr interface{} = *childFile
children = append(children, dirPtr.(*OnlyHeaderFile))
}
return children, nil
}
//Deprecated
func (fs *WebFileSystem) FindFile(filePath string) (primitive.ObjectID, error) {
splittedPath := fs.SplitPath(filePath)
_, rootDirID, err := fs.GetRootDir()
if err != nil {
return primitive.NilObjectID, err
}
// println(rootDir.Name)
lastFileID := rootDirID
for _, pathPart := range splittedPath[1:] {
// println(pathPart)
id, err := fs.findInChildren(pathPart, lastFileID)
if err != nil {
return primitive.NilObjectID, err
}
lastFileID = id
}
return lastFileID, nil
}
//Deprecated
func (fs *WebFileSystem) findInChildren(fileName string, parentDirId primitive.ObjectID) (primitive.ObjectID, error) {
read := ReadStruct2{
File: &DirectoryFile{
FileHeader: FileHeader{},
Data: DirectoryData{},
},
Id: parentDirId,
}
parentDirRaw, err := fs.Read(read)
if err != nil {
return primitive.NilObjectID, err
}
var dirPtr interface{} = *parentDirRaw
dir := dirPtr.(*DirectoryFile)
for _, childId := range dir.Data.Children {
read := ReadStruct2{
File: OnlyHeaderFile{},
Id: childId,
}
childRaw, err := fs.Read(read)
if err != nil {
return primitive.NilObjectID, err
}
var dirPtr interface{} = *childRaw
childFileHeader := dirPtr.(*OnlyHeaderFile)
if childFileHeader.Name == fileName {
return childId, nil
}
}
return primitive.NilObjectID, errors.New("file not found")
}
//Deprecated
func (fs *WebFileSystem) IsChild(childID primitive.ObjectID, parent primitive.ObjectID) (bool, error) {
read := ReadStruct{
File: DirectoryFile{}, //TODO May be a possible problem, if parent file would be not a directory type
}
dirRaw, err := fs.ReadMongo(read)
if err != nil {
return false, err
}
var dirPtr interface{} = *dirRaw
dir := dirPtr.(*DirectoryFile)
for _, cID := range dir.Data.Children {
if cID == childID {
return true, nil
}
}
return false, nil
}
//Deprecated
func (fs *WebFileSystem) GetRootDir() (*DirectoryFile, primitive.ObjectID, error) {
filter := primitive.M{
"header.name": "/",
}
res := fs.webfsCollection.FindOne(fs.ctx, filter)
if res == nil {
return nil, primitive.NilObjectID, errors.New("TODO") //TODO
}
rootDirID := FileId{}
rootDir := DirectoryFile{}
err := res.Decode(&rootDir)
if res == nil {
return nil, primitive.NilObjectID, err
}
err = res.Decode(&rootDirID)
if res == nil {
return nil, primitive.NilObjectID, err
}
return &rootDir, rootDirID.Id, err
}
//Deprecated
func (fs *WebFileSystem) NewCreateDirectory(dirPath string) (primitive.ObjectID, error) {
splittedPath := fs.SplitPath(dirPath)
parentPath := fs.GetParentPath(dirPath)
parentDirRaw, err := fs.NewReadDeprecated(parentPath)
if err != nil {
return primitive.NilObjectID, err
}
newDir := WebFSFile{
MongoId: primitive.NewObjectID(),
Name: splittedPath[len(splittedPath)-1],
Type: "directory",
Data: DirectoryData{
Parent: parentDirRaw.MongoId,
Children: []primitive.ObjectID{},
},
Icon: "",
}
objectId, err := fs.writeMongo(newDir, parentPath)
if err != nil {
return primitive.NilObjectID, err
}
return objectId, nil
}
func (fs *WebFileSystem) CreateDirectory(dirPath string) (primitive.ObjectID, error) {
splittedPath := fs.SplitPath(dirPath)
parentPath := fs.GetParentPath(dirPath)
parentDirID, err := fs.FindFile(parentPath)
if err != nil {
return primitive.NilObjectID, err
}
read := ReadStruct2{
File: nil,
Id: parentDirID,
}
parentDirRaw, err := fs.Read(read)
if err != nil {
return primitive.NilObjectID, err
}
var dirPtr interface{} = *parentDirRaw
parentDir := dirPtr.(*OnlyHeaderFile)
if parentDir.Type != "directory" {
return primitive.NilObjectID, errors.New("path is bad")
}
newDir := DirectoryFile{
FileHeader: FileHeader{
Name: splittedPath[len(splittedPath)-1],
Type: "",
Icon: "",
},
Data: DirectoryData{
Parent: parentDirID,
Children: []primitive.ObjectID{},
},
}
resID, err := fs.Write(newDir, dirPath, false)
if err != nil {
return primitive.NilObjectID, err
}
fs.insertFileToDirectory(resID, parentDirID)
return resID, nil
}
func (fs *WebFileSystem) validateDir(dir *WebFSFile) error {
kek := dir.Data.(primitive.D).Map()["children"].(primitive.A)
_ = kek
children := []primitive.ObjectID{}
counter := 0
for _, v := range kek {
_, err := fs.ReadByObjectID(v.(primitive.ObjectID))
if err != nil {
counter++
} else {
children = append(children, v.(primitive.ObjectID))
}
}
if counter > 0 {
println(dir.Name + " broken iDs: " + strconv.Itoa(counter))
_, err := fs.webfsCollection.UpdateByID(context.Background(), dir.MongoId, bson.M{"$set": bson.M{"data.children": children}})
if err != nil {
println(err.Error())
return err
}
}
return nil
}
func castToFile(raw *interface{}) *WebFSFile {
var dirPtr interface{} = *raw
return dirPtr.(*WebFSFile)
}
func castToDirectoryData(data interface{}) (*DirectoryData, error) {
dirData := DirectoryData{}
err := mapstructure.Decode(data.(primitive.D).Map(), &dirData)
if err != nil {
return nil, err
}
return &dirData, nil
}
// func List()