Last active
April 8, 2024 11:31
-
-
Save ernado/3784de00cf781f6f00025742a9b51e1b to your computer and use it in GitHub Desktop.
gotd upload example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"context" | |
"os" | |
"path/filepath" | |
"time" | |
"github.com/dustin/go-humanize" | |
"github.com/go-faster/errors" | |
"github.com/gotd/td/telegram/message" | |
"github.com/gotd/td/telegram/uploader" | |
"github.com/gotd/td/tg" | |
"go.uber.org/zap" | |
) | |
type progressFunc func(ctx context.Context, state uploader.ProgressState) error | |
func (f progressFunc) Chunk(ctx context.Context, state uploader.ProgressState) error { | |
return f(ctx, state) | |
} | |
func Upload(ctx context.Context, lg *zap.Logger, target tg.InputPeerClass, api *tg.Client, file string) error { | |
lg = lg.With(zap.String("file", file)) | |
stat, err := os.Stat(file) | |
if err != nil { | |
return errors.Wrap(err, "stat") | |
} | |
const ( | |
kb int = 1024 | |
mb = kb * 1024 | |
gb = mb * 1024 | |
) | |
partSize := 128 * 1024 | |
size := int(stat.Size()) | |
if size > 100*mb { | |
partSize = uploader.MaximumPartSize | |
} | |
if size > 4*gb { | |
return errors.Wrapf(err, "%s: file too big", file) | |
} | |
var lastNotify time.Time | |
start := time.Now() | |
notifyRate := time.Second * 5 | |
onProgress := progressFunc(func(ctx context.Context, state uploader.ProgressState) error { | |
now := time.Now() | |
if now.Sub(lastNotify) < notifyRate { | |
return nil | |
} | |
lastNotify = now | |
progress := int(100 * (float64(state.Uploaded) / float64(state.Total))) | |
perSecond := float64(state.Uploaded) / now.Sub(start).Seconds() | |
lg.Info("Progress", | |
zap.Int64("total", state.Total), | |
zap.Int64("uploaded", state.Uploaded), | |
zap.Int("percent", progress), | |
zap.String("speed", humanize.Bytes(uint64(perSecond))+"/s"), | |
) | |
return nil | |
}) | |
inputFile, err := uploader.NewUploader(api). | |
WithProgress(onProgress). | |
WithPartSize(partSize). | |
WithThreads(1). | |
FromPath(ctx, file) | |
if err != nil { | |
return errors.Wrap(err, "upload") | |
} | |
lg.Info("Uploaded", | |
zap.String("file", filepath.Base(file)), | |
) | |
if _, err := message.NewSender(api). | |
To(target). | |
File(ctx, inputFile); err != nil { | |
return errors.Wrap(err, "send") | |
} | |
lg.Info("Done") | |
return nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment