From df08ec63ec0ad1e95f289c239f9d27378d911623 Mon Sep 17 00:00:00 2001 From: divyam234 Date: Thu, 17 Aug 2023 17:02:27 +0530 Subject: [PATCH] added user service --- routes/main.go | 1 + routes/user.go | 19 +++++++++ services/user.service.go | 90 ++++++++++++++++++++++++++++++++++++++++ utils/tgclient.go | 4 +- 4 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 routes/user.go create mode 100644 services/user.service.go diff --git a/routes/main.go b/routes/main.go index a11e345..8e27b8c 100644 --- a/routes/main.go +++ b/routes/main.go @@ -7,4 +7,5 @@ func GetRoutes(router *gin.Engine) { addAuthRoutes(api) addFileRoutes(api) addUploadRoutes(api) + addUserRoutes(api) } diff --git a/routes/user.go b/routes/user.go new file mode 100644 index 0000000..96b9508 --- /dev/null +++ b/routes/user.go @@ -0,0 +1,19 @@ +package routes + +import ( + "github.com/divyam234/teldrive/services" + + "github.com/gin-gonic/gin" +) + +func addUserRoutes(rg *gin.RouterGroup) { + r := rg.Group("/users") + r.Use(Authmiddleware) + userService := services.UserService{} + + r.GET("/profile", func(c *gin.Context) { + if c.Query("photo") != "" { + userService.GetProfilePhoto(c) + } + }) +} diff --git a/services/user.service.go b/services/user.service.go new file mode 100644 index 0000000..e5fe91e --- /dev/null +++ b/services/user.service.go @@ -0,0 +1,90 @@ +package services + +import ( + "bytes" + "context" + "fmt" + "net/http" + "strconv" + + "github.com/divyam234/teldrive/utils" + "github.com/gotd/td/telegram" + "github.com/gotd/td/tg" + + "github.com/divyam234/teldrive/types" + + "github.com/gin-gonic/gin" +) + +type UserService struct { +} + +func getChunk(ctx context.Context, tgClient *telegram.Client, location tg.InputFileLocationClass, offset int64, limit int) ([]byte, error) { + + req := &tg.UploadGetFileRequest{ + Offset: offset, + Limit: int(limit), + Location: location, + } + + r, err := tgClient.API().UploadGetFile(ctx, req) + + if err != nil { + return nil, err + } + + switch result := r.(type) { + case *tg.UploadFile: + return result.Bytes, nil + default: + return nil, fmt.Errorf("unexpected type %T", r) + } +} + +func iterContent(ctx context.Context, tgClient *telegram.Client, location tg.InputFileLocationClass) (*bytes.Buffer, error) { + offset := int64(0) + limit := 1024 * 1024 + buff := &bytes.Buffer{} + for { + r, err := getChunk(ctx, tgClient, location, offset, limit) + if err != nil { + return buff, err + } + if len(r) == 0 { + break + } + buff.Write(r) + offset += int64(limit) + } + return buff, nil +} + +func (us *UserService) GetProfilePhoto(c *gin.Context) { + val, _ := c.Get("jwtUser") + jwtUser := val.(*types.JWTClaims) + userId, _ := strconv.Atoi(jwtUser.Subject) + tgClient, _, err := utils.GetAuthClient(jwtUser.TgSession, userId) + if err != nil { + http.Error(c.Writer, err.Error(), http.StatusBadRequest) + return + } + self, err := tgClient.Tg.Self(c) + if err != nil { + http.Error(c.Writer, err.Error(), http.StatusBadRequest) + return + } + peer := self.AsInputPeer() + photo, _ := self.Photo.AsNotEmpty() + location := &tg.InputPeerPhotoFileLocation{Big: false, Peer: peer, PhotoID: photo.PhotoID} + buff, err := iterContent(c, tgClient.Tg, location) + if err != nil { + http.Error(c.Writer, err.Error(), http.StatusBadRequest) + return + } + content := buff.Bytes() + c.Writer.Header().Set("Content-Type", "image/jpeg") + c.Writer.Header().Set("Cache-Control", "public, max-age=86400") + c.Writer.Header().Set("Content-Length", strconv.Itoa(len(content))) + c.Writer.Header().Set("Content-Disposition", fmt.Sprintf("inline; filename=\"%s\"", "profile.jpeg")) + c.Writer.Write(content) +} diff --git a/utils/tgclient.go b/utils/tgclient.go index d12ae6f..8b6c955 100644 --- a/utils/tgclient.go +++ b/utils/tgclient.go @@ -200,6 +200,8 @@ func GetNonAuthClient(handler telegram.UpdateHandler, storage telegram.SessionSt } func StopClient(stop bg.StopFunc, key int) { - stop() + if stop != nil { + stop() + } delete(clients, key) }