Skip to content

Commit

Permalink
fix update metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
ybizeul committed Aug 4, 2024
1 parent 271c76d commit ab0ac50
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 32 deletions.
2 changes: 1 addition & 1 deletion html/src/Components/ShareComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export function ShareComponent(props: {share: Share}) {
const name = share.name
const count = share.count
const size = share.size
const countString = count?(count + ' items' + (count > 1 ? 's' : '')):"empty"
const countString = count?(count + ' item' + (count > 1 ? 's' : '')):"empty"

// Function
const deleteShare = () => {
Expand Down
17 changes: 13 additions & 4 deletions hupload/pkg/apiws/storageservice/storageservice.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,20 @@ import (
)

type Share struct {
Name string `json:"name"`
Created time.Time `json:"created"`
Owner string `json:"owner"`
Name string `json:"name"`
DateCreated time.Time `json:"created"`
Owner string `json:"owner"`
Size int64 `json:"size"`
Count int64 `json:"count"`
}

type Item struct {
Path string
ItemInfo ItemInfo
}
type ItemInfo struct {
Size int64
Size int64
DateModified time.Time
}

// BackendInterface must be implemented by any backend
Expand All @@ -27,6 +30,9 @@ type StorageServiceInterface interface {
// CreateItem creates a new item in a share
CreateItem(string, string, *bufio.Reader) (*Item, error)

// GetShare returns the share identified by share
GetShare(string) (*Share, error)

// ListShares returns the list of shares available
ListShares() ([]Share, error)

Expand All @@ -41,4 +47,7 @@ type StorageServiceInterface interface {

// GetItem returns the item identified by share and item
GetItemData(string, string) (*bufio.Reader, error)

// UpdateMetadata updates the metadata of share
UpdateMetadata(string) error
}
160 changes: 133 additions & 27 deletions hupload/pkg/apiws/storageservice/storageservicefile.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"
"errors"
"io"
"log/slog"
"os"
"path"
"sort"
Expand Down Expand Up @@ -32,7 +33,7 @@ func NewFileBackend(m map[string]any) *FileBackend {

// initialize creates the root directory for the backend
func (b *FileBackend) initialize() {
path := b.Options["path"].(string)
path := b.stringOption("path")
if path == "" {
panic("path is required")
}
Expand All @@ -42,23 +43,39 @@ func (b *FileBackend) initialize() {
}
}

func (b *FileBackend) stringOption(o string) string {
v, ok := b.Options[o].(string)
if !ok {
return ""
}
return v
}

func (b *FileBackend) int64Option(o string) int64 {
v, ok := b.Options[o].(int)
if !ok {
return 0
}
return int64(v)
}

func (b *FileBackend) CreateShare(s string, o string) error {
_, err := os.Stat(path.Join(b.Options["path"].(string), s))
_, err := os.Stat(path.Join(b.stringOption("path"), s))
if err == nil {
return errors.New("share already exists")
}

err = os.Mkdir(path.Join(b.Options["path"].(string), s), 0755)
err = os.Mkdir(path.Join(b.stringOption("path"), s), 0755)
if err != nil {
return errors.New("cannot create share")
}

m := Share{
Name: s,
Owner: o,
Created: time.Now(),
Name: s,
Owner: o,
DateCreated: time.Now(),
}
f, err := os.Create(path.Join(b.Options["path"].(string), s, ".metadata"))
f, err := os.Create(path.Join(b.stringOption("path"), s, ".metadata"))
if err != nil {
return err
}
Expand All @@ -71,17 +88,42 @@ func (b *FileBackend) CreateShare(s string, o string) error {
}

func (b *FileBackend) CreateItem(s string, i string, r *bufio.Reader) (*Item, error) {
p := path.Join(b.Options["path"].(string), s, i)
p := path.Join(b.stringOption("path"), s, i)
f, err := os.Create(p + suffix)
if err != nil {
return nil, errors.New("cannot create item")
}
defer f.Close()

_, err = io.Copy(f, r)
if err != nil {
os.Remove(p + suffix)
return nil, errors.New("cannot copy item content")
max := b.int64Option("max_bytes")
if max > 0 {
// Check if there is a max bytes associated to share
share, err := b.GetShare(s)
if err != nil {
return nil, errors.New("cannot get share")
}
maxWrite := max - share.Size
if maxWrite <= 0 {
return nil, errors.New("Max share capacity already reached")
}
reader := io.LimitReader(r, maxWrite)
written, err := io.Copy(f, reader)
if err != nil {
os.Remove(p + suffix)
return nil, errors.New("cannot copy item content")
}

if written == 0 || written == maxWrite {
os.Remove(p + suffix)
return nil, errors.New("Max share capacity reached")
}

} else {
_, err := io.Copy(f, r)
if err != nil {
os.Remove(p + suffix)
return nil, errors.New("cannot copy item content")
}
}
err = os.Rename(p+suffix, p)
if err != nil {
Expand All @@ -95,36 +137,47 @@ func (b *FileBackend) CreateItem(s string, i string, r *bufio.Reader) (*Item, er
return item, nil
}

func (b *FileBackend) GetShare(s string) (*Share, error) {
fm, err := os.Open(path.Join(b.stringOption("path"), s, ".metadata"))
if err != nil {
return nil, err
}
defer fm.Close()

m := Share{}
err = json.NewDecoder(fm).Decode(&m)
if err != nil {
return nil, err
}
return &m, nil
}

func (b *FileBackend) ListShares() ([]Share, error) {
d, err := os.ReadDir(b.Options["path"].(string))
d, err := os.ReadDir(b.stringOption("path"))
if err != nil {
return nil, err
}
r := []Share{}

// Shares loop
for _, f := range d {
if f.IsDir() {
fm, err := os.Open(path.Join(b.Options["path"].(string), f.Name(), ".metadata"))
m, err := b.GetShare(f.Name())
if err != nil {
continue
}
defer fm.Close()
m := Share{}
err = json.NewDecoder(fm).Decode(&m)
if err != nil {
return nil, err
}
r = append(r, m)
r = append(r, *m)
}
}
sort.Slice(r, func(i, j int) bool {
return r[i].Created.After(r[j].Created)
return r[i].DateCreated.After(r[j].DateCreated)
})

return r, nil
}

func (b *FileBackend) DeleteShare(s string) error {
sharePath := path.Join(b.Options["path"].(string), s)
sharePath := path.Join(b.stringOption("path"), s)
err := os.RemoveAll(sharePath)
if err != nil {
return err
Expand All @@ -133,7 +186,7 @@ func (b *FileBackend) DeleteShare(s string) error {
}

func (b *FileBackend) ListShare(s string) ([]Item, error) {
d, err := os.ReadDir(path.Join(b.Options["path"].(string), s))
d, err := os.ReadDir(path.Join(b.stringOption("path"), s))
if err != nil {
return nil, err
}
Expand All @@ -148,26 +201,79 @@ func (b *FileBackend) ListShare(s string) ([]Item, error) {
}
r = append(r, *i)
}

sort.Slice(r, func(i, j int) bool {
return r[i].ItemInfo.DateModified.After(r[j].ItemInfo.DateModified)
})

return r, nil
}

func (b *FileBackend) GetItem(s string, i string) (*Item, error) {
p := path.Join(b.Options["path"].(string), s, i)
p := path.Join(b.stringOption("path"), s, i)
stat, err := os.Stat(p)
if err != nil {
return nil, err
}
return &Item{
Path: path.Join(s, i),
ItemInfo: ItemInfo{Size: stat.Size()},
ItemInfo: ItemInfo{Size: stat.Size(), DateModified: stat.ModTime()},
}, nil
}

func (b *FileBackend) GetItemData(s string, i string) (*bufio.Reader, error) {
p := path.Join(b.Options["path"].(string), s, i)
p := path.Join(b.stringOption("path"), s, i)
f, err := os.Open(p)
if err != nil {
return nil, err
}
return bufio.NewReader(f), nil
}

func (b *FileBackend) UpdateMetadata(s string) error {
sd, err := os.ReadDir(path.Join(b.stringOption("path"), s))
if err != nil {
return err
}

fm, err := os.OpenFile(path.Join(b.stringOption("path"), s, ".metadata"), os.O_RDWR, 0644)
if err != nil {
return err
}
defer fm.Close()

m := Share{}
err = json.NewDecoder(fm).Decode(&m)
if err != nil {
return err
}

m.Size = 0
m.Count = 0

// Share content loop
for _, i := range sd {
if strings.HasPrefix(i.Name(), ".") {
continue
}
info, err := i.Info()
if err != nil {
slog.Error("cannot get file info", slog.String("error", err.Error()))
continue
}
m.Size += info.Size()
m.Count += 1
}

_, err = fm.Seek(0, 0)
if err != nil {
return err
}

err = json.NewEncoder(fm).Encode(m)
if err != nil {
return err
}

return nil
}
7 changes: 7 additions & 0 deletions hupload/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ func postItem(w http.ResponseWriter, r *http.Request) {
b := bufio.NewReader(np)
item, err := api.StorageService.CreateItem(r.PathValue("share"), np.FileName(), b)
if err != nil {
w.WriteHeader(http.StatusNotAcceptable)
_, _ = w.Write([]byte(err.Error()))
return
}
Expand All @@ -68,6 +69,12 @@ func postItem(w http.ResponseWriter, r *http.Request) {
return
}

err = api.StorageService.UpdateMetadata(r.PathValue("share"))
if err != nil {
_, _ = w.Write([]byte(err.Error()))
return
}

_, _ = w.Write(c)
}

Expand Down

0 comments on commit ab0ac50

Please sign in to comment.