move gotd fork into repo. (#111)
- update to latest telegram layer - remove some references to fields in tg.Entities that don't exist in the schema - originally added here: https://github.com/beeper/td/commit/820929062a2ba0104397bc01235ab58a9cff780e - referenced here - https://github.com/mautrix/telegramgo/commit/124f0967ed195b5a380c9bd02e170ada9710dde3 - https://github.com/mautrix/telegramgo/commit/4205047aab2e0639217148b5d125bfaab668bd8e
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
package message
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"io/fs"
|
||||
|
||||
"go.uber.org/atomic"
|
||||
|
||||
"go.mau.fi/mautrix-telegram/pkg/gotd/telegram/uploader"
|
||||
"go.mau.fi/mautrix-telegram/pkg/gotd/telegram/uploader/source"
|
||||
"go.mau.fi/mautrix-telegram/pkg/gotd/tg"
|
||||
)
|
||||
|
||||
// Uploader is an abstraction for Telegram file uploader.
|
||||
type Uploader interface {
|
||||
FromFile(ctx context.Context, f uploader.File, name string) (tg.InputFileClass, error)
|
||||
FromPath(ctx context.Context, path, name string) (tg.InputFileClass, error)
|
||||
FromFS(ctx context.Context, filesystem fs.FS, path, name string) (tg.InputFileClass, error)
|
||||
FromReader(ctx context.Context, name string, f io.Reader) (tg.InputFileClass, error)
|
||||
FromBytes(ctx context.Context, name string, b []byte) (tg.InputFileClass, error)
|
||||
FromURL(ctx context.Context, rawURL string) (tg.InputFileClass, error)
|
||||
FromSource(ctx context.Context, src source.Source, rawURL string) (tg.InputFileClass, error)
|
||||
}
|
||||
|
||||
type uploadBuilder struct {
|
||||
upload Uploader
|
||||
}
|
||||
|
||||
// UploadOption is a UploadBuilder creation option.
|
||||
type UploadOption interface {
|
||||
apply(ctx context.Context, b uploadBuilder) (tg.InputFileClass, error)
|
||||
}
|
||||
|
||||
// uploadOptionFunc is a functional adapter for UploadOption.
|
||||
type uploadOptionFunc func(ctx context.Context, b uploadBuilder) (tg.InputFileClass, error)
|
||||
|
||||
func (f uploadOptionFunc) apply(ctx context.Context, b uploadBuilder) (tg.InputFileClass, error) {
|
||||
return f(ctx, b)
|
||||
}
|
||||
|
||||
type fileCache atomic.Value
|
||||
|
||||
func (r *fileCache) Store(result tg.InputFileClass) {
|
||||
r.Value.Store(result)
|
||||
}
|
||||
|
||||
func (r *fileCache) Load() (result tg.InputFileClass, ok bool) {
|
||||
result, ok = r.Value.Load().(tg.InputFileClass)
|
||||
return
|
||||
}
|
||||
|
||||
// FilePromise is a upload file promise.
|
||||
type FilePromise = func(ctx context.Context, b Uploader) (tg.InputFileClass, error)
|
||||
|
||||
// Upload creates new upload options using given promise.
|
||||
func Upload(promise FilePromise) UploadOption {
|
||||
once := &fileCache{}
|
||||
return uploadOptionFunc(func(ctx context.Context, b uploadBuilder) (r tg.InputFileClass, err error) {
|
||||
if v, ok := once.Load(); ok {
|
||||
return v, nil
|
||||
}
|
||||
defer func() {
|
||||
if err == nil && r != nil {
|
||||
once.Store(r)
|
||||
}
|
||||
}()
|
||||
|
||||
return promise(ctx, b.upload)
|
||||
})
|
||||
}
|
||||
|
||||
// FromFile uploads given File.
|
||||
// NB: FromFile does not close given file.
|
||||
func FromFile(f uploader.File) UploadOption {
|
||||
return Upload(func(ctx context.Context, b Uploader) (tg.InputFileClass, error) {
|
||||
return b.FromFile(ctx, f, "")
|
||||
})
|
||||
}
|
||||
|
||||
// FromPath uploads file from given path.
|
||||
func FromPath(path, name string) UploadOption {
|
||||
return Upload(func(ctx context.Context, b Uploader) (tg.InputFileClass, error) {
|
||||
return b.FromPath(ctx, path, name)
|
||||
})
|
||||
}
|
||||
|
||||
// FromFS uploads file from given path using given fs.FS.
|
||||
func FromFS(filesystem fs.FS, path, name string) UploadOption {
|
||||
return Upload(func(ctx context.Context, b Uploader) (tg.InputFileClass, error) {
|
||||
return b.FromFS(ctx, filesystem, path, name)
|
||||
})
|
||||
}
|
||||
|
||||
// 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).
|
||||
func FromReader(name string, r io.Reader) UploadOption {
|
||||
return Upload(func(ctx context.Context, b Uploader) (tg.InputFileClass, error) {
|
||||
return b.FromReader(ctx, name, r)
|
||||
})
|
||||
}
|
||||
|
||||
// FromBytes uploads file from given byte slice.
|
||||
func FromBytes(name string, data []byte) UploadOption {
|
||||
return Upload(func(ctx context.Context, b Uploader) (tg.InputFileClass, error) {
|
||||
return b.FromBytes(ctx, name, data)
|
||||
})
|
||||
}
|
||||
|
||||
// FromURL uploads file from given URL.
|
||||
func FromURL(rawURL string) UploadOption {
|
||||
return Upload(func(ctx context.Context, b Uploader) (tg.InputFileClass, error) {
|
||||
return b.FromURL(ctx, rawURL)
|
||||
})
|
||||
}
|
||||
|
||||
// FromSource uploads file from given URL using given Source.
|
||||
func FromSource(src source.Source, rawURL string) UploadOption {
|
||||
return Upload(func(ctx context.Context, b Uploader) (tg.InputFileClass, error) {
|
||||
return b.FromSource(ctx, src, rawURL)
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user