You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
OneAuth/libs/fs/file.go

106 lines
2.6 KiB
Go

package fs
import (
"context"
"encoding/json"
"fmt"
"github.com/olivere/elastic/v7"
"github.com/veypi/OneAuth/cfg"
"github.com/veypi/OneAuth/libs/webdav"
"github.com/veypi/OneAuth/models"
"github.com/veypi/OneAuth/models/index"
"github.com/veypi/utils/log"
"gorm.io/gorm"
"net/http"
"strconv"
"time"
)
func updateUserSize(uid uint, delta int64) error {
if uid == 0 {
return nil
}
err := cfg.DB().Model(&models.User{}).Where("ID = ?", uid).
Update("Used", gorm.Expr("Used + ?", delta)).Error
return err
}
func removeFile(r *http.Request, prefix string, h *webdav.Handler) error {
f := &models.File{}
f.OwnerID = h.OwnerID
f.Path = prefix
res, err := index.File.Get().Id(f.ID()).Do(r.Context())
if err != nil {
if elastic.IsNotFound(err) {
return nil
}
return err
}
_, err = index.File.Delete().Id(f.ID()).Do(r.Context())
if err == nil {
err = json.Unmarshal(res.Source, f)
if err != nil {
return err
}
uid, _ := strconv.Atoi(h.OwnerID)
if f.Size > 0 && uid > 0 {
err = updateUserSize(uint(uid), -int64(f.Size))
}
_ = addHistory(r, h, models.ActDelete, res.Id, f.Path)
}
return err
}
func updateFile(ctx context.Context, fileID string, props interface{}) error {
_, err := index.File.Update().Id(fileID).Doc(props).Do(ctx)
return err
}
func getFile(ctx context.Context, path string, h *webdav.Handler) (*models.File, error) {
f := &models.File{}
f.OwnerID = h.OwnerID
f.Path = path
//body, err := cfg.ES().Update().Index(models.IndexFile).Id(f.ID()).Upsert(f).Do(ctx)
body, err := index.File.Get().Id(f.ID()).Do(ctx)
if elastic.IsNotFound(err) {
f.CreatedAt = time.Now()
_, err = index.File.Index().Id(f.ID()).BodyJson(f).Do(ctx)
return f, err
} else if err != nil {
return nil, err
}
err = json.Unmarshal(body.Source, f)
return f, err
}
func addHistory(r *http.Request, h *webdav.Handler, act models.Action, fileID string, tag string) error {
his := &models.History{
Action: act,
OwnerID: h.OwnerID,
ActorID: h.ActorID,
FileID: fileID,
Tag: tag,
IP: r.RemoteAddr,
}
his.CreatedAt = time.Now()
_, err := index.History.Index().BodyJson(his).Do(r.Context())
if err != nil {
return err
}
if act == models.ActGet && fileID != "" {
_, err = index.File.Update().Id(fileID).
Script(elastic.NewScript("ctx._source.Count ++")).Do(r.Context())
}
return err
}
func CleanHistory(days uint) error {
res, err := index.History.DeleteByQuery().
Query(elastic.NewRangeQuery("CreatedAt").Lt(fmt.Sprintf("now-%dd/d", days))).
Do(cfg.Ctx)
if err == nil && res.Deleted > 0 {
log.Info().Msgf("clean %d records of history.", res.Deleted)
}
return err
}