teldrive/services/upload.service.go

186 lines
4.2 KiB
Go
Raw Normal View History

2023-08-13 04:15:19 +08:00
package services
import (
2023-08-24 02:40:40 +08:00
"context"
2023-08-13 04:15:19 +08:00
"errors"
"net/http"
2023-09-20 03:20:44 +08:00
"strconv"
"strings"
2023-08-13 04:15:19 +08:00
2023-09-20 03:20:44 +08:00
"github.com/divyam234/teldrive/mapper"
2023-08-16 05:53:02 +08:00
"github.com/divyam234/teldrive/schemas"
2023-09-20 03:20:44 +08:00
"github.com/divyam234/teldrive/utils/tgc"
2023-08-13 04:15:19 +08:00
2023-08-16 05:53:02 +08:00
"github.com/divyam234/teldrive/types"
2023-08-13 04:15:19 +08:00
2023-08-16 05:53:02 +08:00
"github.com/divyam234/teldrive/models"
2023-08-13 04:15:19 +08:00
"github.com/gin-gonic/gin"
2023-09-20 03:20:44 +08:00
"github.com/gotd/td/telegram"
2023-08-13 04:15:19 +08:00
"github.com/gotd/td/telegram/message"
"github.com/gotd/td/telegram/uploader"
"github.com/gotd/td/tg"
"gorm.io/gorm"
)
type UploadService struct {
2023-09-20 03:20:44 +08:00
Db *gorm.DB
2023-08-13 04:15:19 +08:00
}
func (us *UploadService) GetUploadFileById(c *gin.Context) (*schemas.UploadOut, *types.AppError) {
uploadId := c.Param("id")
parts := []schemas.UploadPartOut{}
if err := us.Db.Model(&models.Upload{}).Order("part_no").Where("upload_id = ?", uploadId).Find(&parts).Error; err != nil {
return nil, &types.AppError{Error: errors.New("failed to fetch from db"), Code: http.StatusInternalServerError}
}
return &schemas.UploadOut{Parts: parts}, nil
}
func (us *UploadService) DeleteUploadFile(c *gin.Context) *types.AppError {
uploadId := c.Param("id")
if err := us.Db.Where("upload_id = ?", uploadId).Delete(&models.Upload{}).Error; err != nil {
return &types.AppError{Error: errors.New("failed to delete upload"), Code: http.StatusInternalServerError}
}
return nil
}
func (us *UploadService) UploadFile(c *gin.Context) (*schemas.UploadPartOut, *types.AppError) {
var uploadQuery schemas.UploadQuery
uploadQuery.PartNo = 1
uploadQuery.TotalParts = 1
if err := c.ShouldBindQuery(&uploadQuery); err != nil {
return nil, &types.AppError{Error: err, Code: http.StatusBadRequest}
}
if uploadQuery.Filename == "" {
return nil, &types.AppError{Error: errors.New("filename missing"), Code: http.StatusBadRequest}
}
uploadId := c.Param("id")
2023-08-19 21:53:09 +08:00
var uploadPart []models.Upload
us.Db.Model(&models.Upload{}).Where("upload_id = ?", uploadId).Where("part_no = ?", uploadQuery.PartNo).Find(&uploadPart)
if len(uploadPart) == 1 {
2023-09-20 03:20:44 +08:00
out := mapper.MapUploadSchema(&uploadPart[0])
2023-08-19 21:53:09 +08:00
return out, nil
}
2023-08-13 04:15:19 +08:00
2023-08-24 02:40:40 +08:00
file := c.Request.Body
2023-08-13 04:15:19 +08:00
2023-08-24 02:40:40 +08:00
fileSize := c.Request.ContentLength
fileName := uploadQuery.Filename
var msgId int
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer func() {
cancel()
}()
2023-08-13 04:15:19 +08:00
2023-09-20 03:20:44 +08:00
userId, session := getUserAuth(c)
2023-08-13 04:15:19 +08:00
tokens, err := GetBotsToken(c, userId)
2023-09-20 03:20:44 +08:00
if err != nil {
return nil, &types.AppError{Error: errors.New("failed to fetch bots"), Code: http.StatusInternalServerError}
}
2023-08-13 04:15:19 +08:00
2023-09-20 03:20:44 +08:00
var client *telegram.Client
2023-08-13 04:15:19 +08:00
2023-09-20 03:20:44 +08:00
var token string
var channelUser string
if len(tokens) == 0 {
client, _ = tgc.UserLogin(session)
channelUser = strconv.FormatInt(userId, 10)
} else {
tgc.Workers.Set(tokens)
token = tgc.Workers.Next()
client, _ = tgc.BotLogin(token)
channelUser = strings.Split(token, ":")[0]
}
var out *schemas.UploadPartOut
err = tgc.RunWithAuth(ctx, client, token, func(ctx context.Context) error {
channelId, err := GetDefaultChannel(ctx, userId)
2023-08-13 04:15:19 +08:00
2023-08-24 02:40:40 +08:00
if err != nil {
return err
}
2023-08-13 04:15:19 +08:00
2023-09-20 03:20:44 +08:00
channel, err := GetChannelById(ctx, client, channelId, channelUser)
if err != nil {
return err
}
api := client.API()
2023-08-13 04:15:19 +08:00
2023-09-20 03:20:44 +08:00
u := uploader.NewUploader(api).WithThreads(16).WithPartSize(512 * 1024)
upload, err := u.Upload(c, uploader.NewUpload(fileName, file, fileSize))
2023-08-13 04:15:19 +08:00
2023-08-24 02:40:40 +08:00
if err != nil {
return err
}
2023-08-13 04:15:19 +08:00
2023-09-20 03:20:44 +08:00
document := message.UploadedDocument(upload).Filename(fileName).ForceFile(true)
2023-08-13 04:15:19 +08:00
2023-08-24 02:40:40 +08:00
sender := message.NewSender(client.API())
2023-08-13 04:15:19 +08:00
2023-09-20 03:20:44 +08:00
target := sender.To(&tg.InputPeerChannel{ChannelID: channel.ChannelID,
AccessHash: channel.AccessHash})
2023-08-24 02:40:40 +08:00
2023-09-20 03:20:44 +08:00
res, err := target.Media(c, document)
2023-08-13 04:15:19 +08:00
2023-08-24 02:40:40 +08:00
if err != nil {
return err
}
2023-08-13 04:15:19 +08:00
2023-08-24 02:40:40 +08:00
updates := res.(*tg.Updates)
2023-08-13 04:15:19 +08:00
2023-08-24 02:40:40 +08:00
msgId = updates.Updates[0].(*tg.UpdateMessageID).ID
2023-09-20 03:20:44 +08:00
if msgId == 0 {
return errors.New("failed to upload part")
}
partUpload := &models.Upload{
Name: fileName,
UploadId: uploadId,
PartId: msgId,
ChannelID: channelId,
Size: fileSize,
PartNo: uploadQuery.PartNo,
TotalParts: uploadQuery.TotalParts,
}
if err := us.Db.Create(partUpload).Error; err != nil {
return errors.New("failed to upload part")
}
out = mapper.MapUploadSchema(partUpload)
2023-08-24 02:40:40 +08:00
return nil
})
2023-08-13 04:15:19 +08:00
if err != nil {
return nil, &types.AppError{Error: err, Code: http.StatusInternalServerError}
}
return out, nil
}