From 5fa2a064fbd5b2671b19c54540e6a04e5393c039 Mon Sep 17 00:00:00 2001 From: divyam234 <47589864+divyam234@users.noreply.github.com> Date: Sun, 26 May 2024 01:56:05 +0530 Subject: [PATCH] refactor: add endpoint to delete file parts --- api/router.go | 1 + pkg/controller/file.go | 14 +++++++++- pkg/cron/cron.go | 30 ++------------------ pkg/schemas/file.go | 1 + pkg/services/common.go | 23 ++++++++++++++++ pkg/services/file.go | 58 +++++++++++++++++++++++++++++++++++++-- pkg/services/file_test.go | 2 +- 7 files changed, 97 insertions(+), 32 deletions(-) diff --git a/api/router.go b/api/router.go index e47aa4b..b048877 100644 --- a/api/router.go +++ b/api/router.go @@ -28,6 +28,7 @@ func InitRouter(r *gin.Engine, c *controller.Controller, cnf *config.Config) *gi files.PATCH(":fileID", authmiddleware, c.UpdateFile) files.HEAD(":fileID/stream/:fileName", c.GetFileStream) files.GET(":fileID/stream/:fileName", c.GetFileStream) + files.DELETE(":fileID/parts", authmiddleware, c.DeleteFileParts) files.GET("/category/stats", authmiddleware, c.GetCategoryStats) files.POST("/move", authmiddleware, c.MoveFiles) files.POST("/directories", authmiddleware, c.MakeDirectory) diff --git a/pkg/controller/file.go b/pkg/controller/file.go index ab28388..6d49de7 100644 --- a/pkg/controller/file.go +++ b/pkg/controller/file.go @@ -3,6 +3,7 @@ package controller import ( "net/http" + "github.com/divyam234/teldrive/internal/cache" "github.com/divyam234/teldrive/pkg/httputil" "github.com/divyam234/teldrive/pkg/logging" "github.com/divyam234/teldrive/pkg/schemas" @@ -43,7 +44,7 @@ func (fc *Controller) UpdateFile(c *gin.Context) { httputil.NewError(c, http.StatusBadRequest, err) return } - res, err := fc.FileService.UpdateFile(c.Param("fileID"), userId, &fileUpdate) + res, err := fc.FileService.UpdateFile(c.Param("fileID"), userId, &fileUpdate, cache.FromContext(c)) if err != nil { httputil.NewError(c, err.Code, err.Error) return @@ -151,6 +152,17 @@ func (fc *Controller) DeleteFiles(c *gin.Context) { c.JSON(http.StatusOK, res) } +func (fc *Controller) DeleteFileParts(c *gin.Context) { + + res, err := fc.FileService.DeleteFileParts(c, c.Param("fileID")) + if err != nil { + httputil.NewError(c, err.Code, err.Error) + return + } + + c.JSON(http.StatusOK, res) +} + func (fc *Controller) MoveDirectory(c *gin.Context) { userId, _ := services.GetUserAuth(c) diff --git a/pkg/cron/cron.go b/pkg/cron/cron.go index d3cd939..a96dd81 100644 --- a/pkg/cron/cron.go +++ b/pkg/cron/cron.go @@ -4,16 +4,13 @@ import ( "context" "database/sql/driver" "encoding/json" - "strconv" "time" "github.com/divyam234/teldrive/internal/config" - "github.com/divyam234/teldrive/internal/tgc" "github.com/divyam234/teldrive/pkg/logging" "github.com/divyam234/teldrive/pkg/models" "github.com/divyam234/teldrive/pkg/services" "github.com/go-co-op/gocron" - "github.com/gotd/td/tg" "go.uber.org/zap" "gorm.io/gorm" ) @@ -114,7 +111,7 @@ func (c *CronService) CleanFiles(ctx context.Context) { } } - err := deleteTGMessages(ctx, c.cnf, row.Session, row.ChannelId, row.UserId, ids) + err := services.DeleteTGMessages(ctx, &c.cnf.TG, row.Session, row.ChannelId, row.UserId, ids) if err != nil { c.logger.Errorw("failed to clean files", err) } @@ -142,7 +139,7 @@ func (c *CronService) CleanUploads(ctx context.Context) { if result.Session == "" { break } - err := deleteTGMessages(ctx, c.cnf, result.Session, result.ChannelId, result.UserId, result.Parts) + err := services.DeleteTGMessages(ctx, &c.cnf.TG, result.Session, result.ChannelId, result.UserId, result.Parts) c.logger.Errorw("failed to delete messages", err) parts := []int{} for _, id := range result.Parts { @@ -158,26 +155,3 @@ func (c *CronService) CleanUploads(ctx context.Context) { func (c *CronService) UpdateFolderSize() { c.db.Exec("call teldrive.update_size();") } - -func deleteTGMessages(ctx context.Context, cnf *config.Config, session string, channelId, userId int64, ids []int) error { - - client, _ := tgc.AuthClient(ctx, &cnf.TG, session) - - err := tgc.RunWithAuth(ctx, client, "", func(ctx context.Context) error { - - channel, err := services.GetChannelById(ctx, client, channelId, strconv.FormatInt(userId, 10)) - - if err != nil { - return err - } - - messageDeleteRequest := tg.ChannelsDeleteMessagesRequest{Channel: channel, ID: ids} - - _, err = client.API().ChannelsDeleteMessages(ctx, &messageDeleteRequest) - if err != nil { - return err - } - return nil - }) - return err -} diff --git a/pkg/schemas/file.go b/pkg/schemas/file.go index 1888320..8bce9c5 100644 --- a/pkg/schemas/file.go +++ b/pkg/schemas/file.go @@ -67,6 +67,7 @@ type FileUpdate struct { ParentID string `json:"parentId,omitempty"` UpdatedAt time.Time `json:"updatedAt,omitempty"` Parts []Part `json:"parts,omitempty"` + Size *int64 `json:"size,omitempty"` } type FileResponse struct { diff --git a/pkg/services/common.go b/pkg/services/common.go index e1c7b3b..e03ebc2 100644 --- a/pkg/services/common.go +++ b/pkg/services/common.go @@ -334,3 +334,26 @@ func getSessionByHash(db *gorm.DB, cache *cache.Cache, hash string) (*models.Ses return &session, nil } + +func DeleteTGMessages(ctx context.Context, cnf *config.TGConfig, session string, channelId, userId int64, ids []int) error { + + client, _ := tgc.AuthClient(ctx, cnf, session) + + err := tgc.RunWithAuth(ctx, client, "", func(ctx context.Context) error { + + channel, err := GetChannelById(ctx, client, channelId, strconv.FormatInt(userId, 10)) + + if err != nil { + return err + } + + messageDeleteRequest := tg.ChannelsDeleteMessagesRequest{Channel: channel, ID: ids} + + _, err = client.API().ChannelsDeleteMessages(ctx, &messageDeleteRequest) + if err != nil { + return err + } + return nil + }) + return err +} diff --git a/pkg/services/file.go b/pkg/services/file.go index 6f4487b..217c0b9 100644 --- a/pkg/services/file.go +++ b/pkg/services/file.go @@ -110,7 +110,7 @@ func (fs *FileService) CreateFile(c *gin.Context, userId int64, fileIn *schemas. return res, nil } -func (fs *FileService) UpdateFile(id string, userId int64, update *schemas.FileUpdate) (*schemas.FileOut, *types.AppError) { +func (fs *FileService) UpdateFile(id string, userId int64, update *schemas.FileUpdate, cache *cache.Cache) (*schemas.FileOut, *types.AppError) { var ( files []models.File chain *gorm.DB @@ -118,7 +118,35 @@ func (fs *FileService) UpdateFile(id string, userId int64, update *schemas.FileU if update.Type == "folder" && update.Name != "" { chain = fs.db.Raw("select * from teldrive.update_folder(?, ?, ?)", id, update.Name, userId).Scan(&files) } else { - chain = fs.db.Model(&files).Clauses(clause.Returning{}).Where("id = ?", id).Updates(update) + + updateDb := models.File{ + Name: update.Name, + ParentID: update.ParentID, + UpdatedAt: update.UpdatedAt, + Path: update.Path, + Size: update.Size, + } + + if update.Starred != nil { + updateDb.Starred = *update.Starred + } + + if len(update.Parts) > 0 { + parts := models.Parts{} + + for _, part := range update.Parts { + parts = append(parts, models.Part{ + ID: part.ID, + Salt: part.Salt, + }) + + } + + updateDb.Parts = &parts + } + chain = fs.db.Model(&files).Clauses(clause.Returning{}).Where("id = ?", id).Updates(updateDb) + + cache.Delete(fmt.Sprintf("files:%s", id)) } if chain.Error != nil { @@ -267,6 +295,32 @@ func (fs *FileService) DeleteFiles(userId int64, payload *schemas.FileOperation) return &schemas.Message{Message: "files deleted"}, nil } +func (fs *FileService) DeleteFileParts(c *gin.Context, id string) (*schemas.Message, *types.AppError) { + var file models.File + if err := fs.db.Where("id = ?", id).First(&file).Error; err != nil { + if database.IsRecordNotFoundErr(err) { + return nil, &types.AppError{Error: database.ErrNotFound, Code: http.StatusNotFound} + } + return nil, &types.AppError{Error: err} + } + + userId, session := GetUserAuth(c) + + ids := []int{} + + for _, part := range *file.Parts { + ids = append(ids, int(part.ID)) + } + + err := DeleteTGMessages(c, fs.cnf, session, *file.ChannelID, userId, ids) + + if err != nil { + return nil, &types.AppError{Error: err} + } + + return &schemas.Message{Message: "file parts deleted"}, nil +} + func (fs *FileService) MoveDirectory(userId int64, payload *schemas.DirMove) (*schemas.Message, *types.AppError) { if err := fs.db.Exec("select * from teldrive.move_directory(? , ? , ?)", payload.Source, diff --git a/pkg/services/file_test.go b/pkg/services/file_test.go index 8d00c8a..eaeae4a 100644 --- a/pkg/services/file_test.go +++ b/pkg/services/file_test.go @@ -83,7 +83,7 @@ func (s *FileServiceSuite) Test_Update() { Path: "/dwkd", Type: "file", } - r, err := s.srv.UpdateFile(res.ID, 123456, data) + r, err := s.srv.UpdateFile(res.ID, 123456, data, nil) s.NoError(err.Error) s.Equal(r.Name, data.Name) s.Equal(r.Path, data.Path)