From e1e62a0373a5db8c988d092566d2363358330b99 Mon Sep 17 00:00:00 2001 From: cyber-dream Date: Sat, 29 Apr 2023 12:02:55 +0300 Subject: [PATCH] Add file data structure --- .env | 3 + go.mod | 1 + go.sum | 2 + main.go | 16 +++++ webfilesystem/webfilesystem.go | 117 ++++++++++++++++++++++++++++----- 5 files changed, 122 insertions(+), 17 deletions(-) create mode 100644 .env diff --git a/.env b/.env new file mode 100644 index 0000000..50a8248 --- /dev/null +++ b/.env @@ -0,0 +1,3 @@ +MONGO_CONNECT=mongodb://localhost:27017 +DATABASE=personal-website +COLLECTION_WEBFS=webfs \ No newline at end of file diff --git a/go.mod b/go.mod index d1ba5de..1b644b7 100644 --- a/go.mod +++ b/go.mod @@ -30,6 +30,7 @@ require ( github.com/klauspost/cpuid/v2 v2.0.9 // indirect github.com/leodido/go-urn v1.2.1 // indirect github.com/mattn/go-isatty v0.0.17 // indirect + github.com/mitchellh/mapstructure v1.5.0 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.0.6 // indirect diff --git a/go.sum b/go.sum index d79d9dd..1de6cb5 100644 --- a/go.sum +++ b/go.sum @@ -41,6 +41,8 @@ github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= diff --git a/main.go b/main.go index d25d344..4767ef2 100644 --- a/main.go +++ b/main.go @@ -107,6 +107,22 @@ func main() { fs := router.Group("fs") { + fs.GET("createDir", func(ctx *gin.Context) { + path := ctx.Query("path") + if path == "" { + ctx.JSON(http.StatusBadRequest, "TODO") //TODO json error struct + return + } + + err := webfs.CreateDirectory(path) + if err != nil { + ctx.JSON(http.StatusInternalServerError, "TODO") //TODO json error struct + return + } + + ctx.JSON(http.StatusOK, "OK") + }) + fs.GET("list", func(ctx *gin.Context) { path := ctx.Query("path") if path == "" { diff --git a/webfilesystem/webfilesystem.go b/webfilesystem/webfilesystem.go index 842c733..f66b837 100644 --- a/webfilesystem/webfilesystem.go +++ b/webfilesystem/webfilesystem.go @@ -2,8 +2,10 @@ package webfilesystem import ( "context" + "errors" "strings" + "github.com/mitchellh/mapstructure" "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo" ) @@ -19,35 +21,116 @@ func NewWebFileSystem(mongoClient *mongo.Client, dBName string, fsCollectionName } } -func (fs *WebFileSystem) List(path string) ([]*WebFSFile, error) { - return nil, nil -} - func (fs *WebFileSystem) Read(path string) (*WebFSFile, error) { - splittedPath := strings.Split(path, "/") + splittedPath := fs.SplitPath(path) filter := primitive.D{ { - Key: "filename", + Key: "name", Value: splittedPath[len(splittedPath)-1], }, } - if splittedPath == []string{"",""} - res := fs.webfsCollection.FindOne(context.TODO(), &filter) - findedFile := WebFSFile{} - err := res.Decode(&findedFile) - return &findedFile, err + file, err := fs.findFileInMongo(filter) + return file, err +} + +func (fs *WebFileSystem) ReadByObjectID(objectId primitive.ObjectID) (*WebFSFile, error) { + filter := primitive.D{ + { + Key: "_id", + Value: objectId, + }, + } + file, err := fs.findFileInMongo(filter) + return file, err +} + +func (fs *WebFileSystem) findFileInMongo(filter primitive.D) (*WebFSFile, error) { + res := fs.webfsCollection.FindOne(context.Background(), &filter) + file := WebFSFile{} + err := res.Decode(&file) + if err != nil { + return nil, err + } + return &file, nil +} + +func (fs *WebFileSystem) List(path string) ([]*WebFSFile, error) { + dirFile, err := fs.Read(fs.GetParentPath(path)) + if err != nil { + return nil, err + } + if dirFile.Type != "directory" { + return nil, errors.New("file is not a directory") + } + fileData := FolderData{} + err = mapstructure.Decode(dirFile.Data.(primitive.D).Map(), &fileData) + if err != nil { + return nil, err + } + + files := []*WebFSFile{} + for _, child := range fileData.Children { + file, err := fs.ReadByObjectID(child) + if err != nil { + println(err.Error()) + continue + } + files = append(files, file) + } + return files, nil +} + +func (fs *WebFileSystem) CreateDirectory(path string) error { + splittedpath := fs.SplitPath(path) + directory := WebFSFile{ + MongoId: primitive.NewObjectID(), + Name: splittedpath[len(splittedpath)-1], + Type: "directory", + Data: FolderData{ + // Parent: , + Children: []primitive.ObjectID{ + primitive.NewObjectID(), + primitive.NewObjectID(), + primitive.NewObjectID(), + }, + }, + } + _, err := fs.webfsCollection.InsertOne(context.Background(), &directory) + if err != nil { + return err + } + // res.InsertedID //TODO Insert to parent folder data + return nil +} + +func (fs *WebFileSystem) SplitPath(path string) []string { + resPath := []string{} + splittedPath := strings.Split(path, "/") + splittedPath[0] = "/" + for _, split := range splittedPath { + if split != "" { + resPath = append(resPath, split) + } + } + return resPath +} + +func (fs *WebFileSystem) GetParentPath(path string) string { + splittedPath := fs.SplitPath(path) + parentPath := strings.Join(splittedPath[:len(splittedPath)-1], "/") + return parentPath } type WebFSFile struct { - MongoId primitive.ObjectID `bson:"_id"` - Name string `bson:"name"` - Type string `bson:"type"` - data interface{} `bson:"data"` + MongoId primitive.ObjectID `bson:"_id" json:"-"` + Name string `bson:"name" json:"name"` + Type string `bson:"type" json:"type"` + Data interface{} `bson:"data" json:"-"` } type FolderData struct { - Parent primitive.ObjectID `bson:"parent"` - Childs []primitive.ObjectID `bson:"childs"` + Parent primitive.ObjectID `bson:"parent"` + Children []primitive.ObjectID `bson:"children"` } type File interface {