diff --git a/config.ini b/config.ini index db3fe35..b2084f4 100644 --- a/config.ini +++ b/config.ini @@ -8,7 +8,9 @@ secret = "e93865c991358ff7a14f9781fa33ba4f28c33bb8d1cf3490ce6fd68521513536" [collabora] url = "https://loolwsd.deblan.org" -budget_file = "_data/test.ods" + +[file] +path = "./_data/" [log] ; level = "debug" diff --git a/config/config.go b/config/config.go index 28c3a38..44c7a18 100644 --- a/config/config.go +++ b/config/config.go @@ -30,6 +30,10 @@ type collabora struct { BudgetFile string } +type file struct { + Path string +} + func (c *collabora) HostingDiscoveryUrl() string { return fmt.Sprintf("%s/hosting/discovery", c.Url) } @@ -40,6 +44,7 @@ type Config struct { Security security Server server Collabora collabora + File file } var config *Config @@ -66,5 +71,5 @@ func (c *Config) Load(file string) { config.Server.Port, _ = cfg.Section("server").Key("port").Int() config.Server.BaseUrl = cfg.Section("server").Key("base_url").String() config.Collabora.Url = cfg.Section("collabora").Key("url").String() - config.Collabora.BudgetFile = cfg.Section("collabora").Key("budget_file").String() + config.File.Path = cfg.Section("file").Key("path").String() } diff --git a/file/manager.go b/file/manager.go new file mode 100644 index 0000000..c83927b --- /dev/null +++ b/file/manager.go @@ -0,0 +1,103 @@ +package file + +import ( + "crypto/sha256" + "fmt" + "math" + "math/big" + "os" + + "github.com/gabriel-vasile/mimetype" +) + +type File struct { + Id string `json:"id"` + Name string `json:"name"` + Path string `json:"path"` + Size int64 `json:"size"` + Type string `json:"type"` + Extension string `json:"extension"` +} + +type Tree struct { + Name string `json:"name"` + Directories []Tree `json:"directories"` + Path string `json:"path"` + Files []File `json:"files"` + IsRoot bool `json:"is_root"` +} + +func getFileId(path string) string { + hash := sha256.New() + hash.Write([]byte(path)) + hashBytes := hash.Sum(nil) + bInt := new(big.Int).SetBytes(hashBytes) + + return fmt.Sprintf("%d", int(math.Abs(float64(bInt.Int64())))) +} + +func GetTree(name, path string) Tree { + tree := Tree{ + Name: name, + Directories: []Tree{}, + Path: path, + Files: []File{}, + IsRoot: name == "", + } + entries, err := os.ReadDir(path) + + if err != nil { + return tree + } + + for _, e := range entries { + if e.IsDir() { + tree.Directories = append(tree.Directories, GetTree(e.Name(), path+"/"+e.Name())) + } else { + p := path + "/" + e.Name() + fi, _ := os.Stat(p) + mtype, _ := mimetype.DetectFile(p) + + tree.Files = append(tree.Files, File{ + Id: getFileId(p), + Name: e.Name(), + Path: p, + Size: fi.Size(), + Type: mtype.Extension(), + Extension: mtype.Extension(), + }) + } + } + + return tree +} + +func GetFiles(files *[]File, path string) *[]File { + entries, err := os.ReadDir(path) + + if err != nil { + return files + } + + for _, e := range entries { + p := path + "/" + e.Name() + + if e.IsDir() { + GetFiles(files, p) + } else { + fi, _ := os.Stat(p) + mtype, _ := mimetype.DetectFile(p) + + *files = append(*files, File{ + Id: getFileId(p), + Name: e.Name(), + Path: p, + Size: fi.Size(), + Type: mtype.Extension(), + Extension: mtype.Extension(), + }) + } + } + + return files +} diff --git a/frontend/js/views/CalcView.vue b/frontend/js/views/CalcView.vue index a372a25..4004647 100644 --- a/frontend/js/views/CalcView.vue +++ b/frontend/js/views/CalcView.vue @@ -1,9 +1,67 @@ diff --git a/frontend/scss/main.scss b/frontend/scss/main.scss index 9c8620d..1aa888a 100644 --- a/frontend/scss/main.scss +++ b/frontend/scss/main.scss @@ -71,7 +71,7 @@ $nav-size-sm: 50px; @media screen and (max-width: 980px) { #collabora { - height: calc(100vh - 70px); + height: calc(100vh - 100px); } #app-name { diff --git a/go.mod b/go.mod index fb0523a..e24a22a 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect github.com/daaku/go.zipexe v1.0.2 // indirect - github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/gabriel-vasile/mimetype v1.4.5 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator v9.31.0+incompatible // indirect diff --git a/go.sum b/go.sum index a7acb2a..bab4ae2 100644 --- a/go.sum +++ b/go.sum @@ -21,6 +21,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4= +github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= diff --git a/web/controller/collabora/controller.go b/web/controller/collabora/controller.go index 2edf181..945dafe 100644 --- a/web/controller/collabora/controller.go +++ b/web/controller/collabora/controller.go @@ -14,6 +14,7 @@ import ( "github.com/labstack/echo/v4" "gitnet.fr/deblan/budget/config" "gitnet.fr/deblan/budget/database/model" + f "gitnet.fr/deblan/budget/file" "gitnet.fr/deblan/budget/web/view" tpl "gitnet.fr/deblan/budget/web/view/template/collabora" ) @@ -45,7 +46,7 @@ func New(e *echo.Echo) *Controller { Token: getToken(), } - e.GET("/collabora", c.Iframe) + e.GET("/collabora/:id", c.Iframe) e.GET("/wopi/:id", c.Info) e.GET("/wopi/:id/contents", c.WopiContentGet) e.POST("/wopi/:id/contents", c.WopiContentPost) @@ -77,7 +78,7 @@ func (ctrl *Controller) Iframe(c echo.Context) error { wopiSrc := fmt.Sprintf( "%s%s", config.Get().Server.BaseUrl, - "/wopi/1", + "/wopi/"+c.Param("id"), ) url := items[1] + "WOPISrc=" + wopiSrc @@ -90,7 +91,21 @@ func (ctrl *Controller) Info(c echo.Context) error { return c.JSON(403, nil) } - fi, _ := os.Stat(config.Get().Collabora.BudgetFile) + var file string + files := []f.File{} + f.GetFiles(&files, config.Get().File.Path) + + for _, f := range files { + if f.Id == c.Param("id") { + file = f.Path + } + } + + if file == "" { + return c.JSON(404, "File not found") + } + + fi, _ := os.Stat(file) type res struct { BaseFileName string @@ -112,7 +127,21 @@ func (ctrl *Controller) WopiContentGet(c echo.Context) error { return c.JSON(403, nil) } - content, _ := os.ReadFile(config.Get().Collabora.BudgetFile) + var file string + files := []f.File{} + f.GetFiles(&files, config.Get().File.Path) + + for _, f := range files { + if f.Id == c.Param("id") { + file = f.Path + } + } + + if file == "" { + return c.JSON(404, "File not found") + } + + content, _ := os.ReadFile(file) return c.Blob(200, "application/vnd.oasis.opendocument.spreadsheet", content) } @@ -122,9 +151,23 @@ func (ctrl *Controller) WopiContentPost(c echo.Context) error { return c.JSON(403, nil) } + var file string + files := []f.File{} + f.GetFiles(&files, config.Get().File.Path) + + for _, f := range files { + if f.Id == c.Param("id") { + file = f.Path + } + } + + if file == "" { + return c.JSON(404, "File not found") + } + data, _ := ioutil.ReadAll(c.Request().Body) - err := os.WriteFile(config.Get().Collabora.BudgetFile, data, 0600) + err := os.WriteFile(file, data, 0600) if err != nil { return err diff --git a/web/controller/file/controller.go b/web/controller/file/controller.go new file mode 100644 index 0000000..647bd24 --- /dev/null +++ b/web/controller/file/controller.go @@ -0,0 +1,29 @@ +package file + +import ( + "github.com/labstack/echo/v4" + "gitnet.fr/deblan/budget/config" + "gitnet.fr/deblan/budget/database/model" + f "gitnet.fr/deblan/budget/file" +) + +type Controller struct { +} + +func New(e *echo.Echo) *Controller { + c := Controller{} + + e.GET("/api/files", c.Files) + + return &c +} + +func (ctrl *Controller) Files(c echo.Context) error { + if nil == model.LoadSessionUser(c) { + return c.Redirect(302, "/login") + } + + tree := f.GetTree("", config.Get().File.Path) + + return c.JSON(200, tree) +} diff --git a/web/router/router.go b/web/router/router.go index 7ed7db0..a5180ef 100644 --- a/web/router/router.go +++ b/web/router/router.go @@ -7,6 +7,7 @@ import ( "gitnet.fr/deblan/budget/web/controller/bank_account" "gitnet.fr/deblan/budget/web/controller/category" "gitnet.fr/deblan/budget/web/controller/collabora" + "gitnet.fr/deblan/budget/web/controller/file" "gitnet.fr/deblan/budget/web/controller/saving_account" "gitnet.fr/deblan/budget/web/controller/transaction" "gitnet.fr/deblan/budget/web/controller/user" @@ -21,4 +22,5 @@ func RegisterControllers(e *echo.Echo) { category.New(e) transaction.New(e) collabora.New(e) + file.New(e) }