From 67750c842310fda71b02509db16f100d5833b4ea Mon Sep 17 00:00:00 2001 From: okhex Date: Tue, 10 Sep 2024 01:18:07 +0530 Subject: [PATCH] feat(upload): add support for streamed uploads of Big File [Streamed uploads](https://core.telegram.org/api/files#streamed-uploads) - A total_stream_size variable must be used to keep track of the total number of bytes read from the stream. - upload.saveBigFilePart must always be used, even if the stream turns out to be smaller than 10MB. - The file_total_parts field must be set to -1 for all parts except for the last one, using the following logic: --- telegram/uploader/big.go | 8 ++++++++ telegram/uploader/helpers.go | 2 ++ telegram/uploader/uploader.go | 4 ++++ 3 files changed, 14 insertions(+) diff --git a/telegram/uploader/big.go b/telegram/uploader/big.go index 2261c3afe4..8eaa7fe058 100644 --- a/telegram/uploader/big.go +++ b/telegram/uploader/big.go @@ -53,14 +53,22 @@ func (u *Uploader) bigLoop(ctx context.Context, threads int, upload *Upload) err r := syncio.NewReader(upload.from) g.Go(func(ctx context.Context) error { last := false + totalStreamSize := 0 for { buf := u.pool.GetSize(u.partSize) n, err := io.ReadFull(r, buf.Buf) + if n > 0 { + totalStreamSize += n + } switch { case errors.Is(err, io.ErrUnexpectedEOF): last = true + if upload.totalParts == -1 { + totalParts := (totalStreamSize + u.partSize - 1) / u.partSize + upload.totalParts = int(totalParts) + } case errors.Is(err, io.EOF): u.pool.Put(buf) diff --git a/telegram/uploader/helpers.go b/telegram/uploader/helpers.go index a03c9aa10b..13eb5e67f7 100644 --- a/telegram/uploader/helpers.go +++ b/telegram/uploader/helpers.go @@ -60,6 +60,8 @@ func (u *Uploader) FromFS(ctx context.Context, filesystem fs.FS, path string) (_ // FromReader uploads file from given io.Reader. // NB: totally stream should not exceed the limit for // small files (10 MB as docs says, may be a bit bigger). +// Support For Big Files +// https://core.telegram.org/api/files#streamed-uploads func (u *Uploader) FromReader(ctx context.Context, name string, f io.Reader) (tg.InputFileClass, error) { return u.Upload(ctx, NewUpload(name, f, -1)) } diff --git a/telegram/uploader/uploader.go b/telegram/uploader/uploader.go index bdf6f87ebf..cf0a73e57d 100644 --- a/telegram/uploader/uploader.go +++ b/telegram/uploader/uploader.go @@ -82,6 +82,10 @@ func (u *Uploader) Upload(ctx context.Context, upload *Upload) (tg.InputFileClas if err := u.initUpload(upload); err != nil { return nil, err } + if upload.totalBytes == -1 { + upload.big = true + upload.totalParts = -1 + } if !upload.big { return u.uploadSmall(ctx, upload)