mirror of
https://github.com/iyear/tdl
synced 2025-01-08 11:57:55 +08:00
refactor(prj): separate tclient core code to core module
This commit is contained in:
parent
75b86da710
commit
d06ca3a065
@ -17,12 +17,12 @@ import (
|
||||
"github.com/iyear/tdl/core/dcpool"
|
||||
"github.com/iyear/tdl/core/downloader"
|
||||
"github.com/iyear/tdl/core/logctx"
|
||||
"github.com/iyear/tdl/core/tclient"
|
||||
"github.com/iyear/tdl/pkg/consts"
|
||||
"github.com/iyear/tdl/pkg/key"
|
||||
"github.com/iyear/tdl/pkg/kv"
|
||||
"github.com/iyear/tdl/pkg/prog"
|
||||
"github.com/iyear/tdl/pkg/storage"
|
||||
"github.com/iyear/tdl/pkg/tclient"
|
||||
"github.com/iyear/tdl/pkg/tmessage"
|
||||
"github.com/iyear/tdl/pkg/utils"
|
||||
)
|
||||
|
@ -19,12 +19,12 @@ import (
|
||||
"github.com/iyear/tdl/app/internal/tctx"
|
||||
"github.com/iyear/tdl/core/dcpool"
|
||||
"github.com/iyear/tdl/core/forwarder"
|
||||
"github.com/iyear/tdl/core/tclient"
|
||||
"github.com/iyear/tdl/core/util/tutil"
|
||||
"github.com/iyear/tdl/pkg/consts"
|
||||
"github.com/iyear/tdl/pkg/kv"
|
||||
"github.com/iyear/tdl/pkg/prog"
|
||||
"github.com/iyear/tdl/pkg/storage"
|
||||
"github.com/iyear/tdl/pkg/tclient"
|
||||
"github.com/iyear/tdl/pkg/texpr"
|
||||
"github.com/iyear/tdl/pkg/tmessage"
|
||||
)
|
||||
|
@ -12,13 +12,13 @@ import (
|
||||
"go.uber.org/multierr"
|
||||
|
||||
"github.com/iyear/tdl/core/dcpool"
|
||||
"github.com/iyear/tdl/core/tclient"
|
||||
"github.com/iyear/tdl/core/uploader"
|
||||
"github.com/iyear/tdl/core/util/tutil"
|
||||
"github.com/iyear/tdl/pkg/consts"
|
||||
"github.com/iyear/tdl/pkg/kv"
|
||||
"github.com/iyear/tdl/pkg/prog"
|
||||
"github.com/iyear/tdl/pkg/storage"
|
||||
"github.com/iyear/tdl/pkg/tclient"
|
||||
"github.com/iyear/tdl/pkg/utils"
|
||||
)
|
||||
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/iyear/tdl/core/logctx"
|
||||
tclientcore "github.com/iyear/tdl/core/tclient"
|
||||
"github.com/iyear/tdl/core/util/fsutil"
|
||||
"github.com/iyear/tdl/core/util/logutil"
|
||||
"github.com/iyear/tdl/pkg/consts"
|
||||
@ -158,7 +159,7 @@ func tRun(ctx context.Context, f func(ctx context.Context, c *telegram.Client, k
|
||||
return errors.Wrap(err, "create client")
|
||||
}
|
||||
|
||||
return tclient.Run(ctx, client, func(ctx context.Context) error {
|
||||
return tclientcore.RunWithAuth(ctx, client, func(ctx context.Context) error {
|
||||
return f(ctx, client, kvd)
|
||||
})
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ require (
|
||||
github.com/cenkalti/backoff/v4 v4.3.0
|
||||
github.com/gabriel-vasile/mimetype v1.4.4
|
||||
github.com/go-faster/errors v0.7.1
|
||||
github.com/gotd/contrib v0.20.0
|
||||
github.com/gotd/td v0.102.0
|
||||
github.com/iyear/connectproxy v0.1.1
|
||||
github.com/yapingcat/gomedia v0.0.0-20240601043430-920523f8e5c7
|
||||
@ -14,10 +15,12 @@ require (
|
||||
go.uber.org/zap v1.27.0
|
||||
golang.org/x/net v0.25.0
|
||||
golang.org/x/sync v0.7.0
|
||||
golang.org/x/time v0.5.0
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/beevik/ntp v1.3.1 // indirect
|
||||
github.com/go-faster/jx v1.1.0 // indirect
|
||||
github.com/go-faster/xor v1.0.0 // indirect
|
||||
github.com/gotd/ige v0.2.2 // indirect
|
||||
|
10
core/go.sum
10
core/go.sum
@ -1,3 +1,5 @@
|
||||
github.com/beevik/ntp v1.3.1 h1:Y/srlT8L1yQr58kyPWFPZIxRL8ttx2SRIpVYJqZIlAM=
|
||||
github.com/beevik/ntp v1.3.1/go.mod h1:fT6PylBq86Tsq23ZMEe47b7QQrZfYBFPnpzt0a9kJxw=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
@ -13,6 +15,8 @@ github.com/go-faster/xor v1.0.0 h1:2o8vTOgErSGHP3/7XwA5ib1FTtUsNtwCoLLBjl31X38=
|
||||
github.com/go-faster/xor v1.0.0/go.mod h1:x5CaDY9UKErKzqfRfFZdfu+OSTfoZny3w5Ak7UxcipQ=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/gotd/contrib v0.20.0 h1:1Wc4+HMQiIKYQuGHVwVksIx152HFTP6B5n88dDe0ZYw=
|
||||
github.com/gotd/contrib v0.20.0/go.mod h1:P6o8W4niqhDPHLA0U+SA/L7l3BQHYLULpeHfRSePn9o=
|
||||
github.com/gotd/ige v0.2.2 h1:XQ9dJZwBfDnOGSTxKXBGP4gMud3Qku2ekScRjDWWfEk=
|
||||
github.com/gotd/ige v0.2.2/go.mod h1:tuCRb+Y5Y3eNTo3ypIfNpQ4MFjrnONiL2jN2AKZXmb0=
|
||||
github.com/gotd/neo v0.1.5 h1:oj0iQfMbGClP8xI59x7fE/uHoTJD7NZH9oV1WNuPukQ=
|
||||
@ -45,8 +49,8 @@ go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/exp v0.0.0-20230116083435-1de6713980de h1:DBWn//IJw30uYCgERoxCg84hWtA97F4wMiKOIh00Uf0=
|
||||
golang.org/x/exp v0.0.0-20230116083435-1de6713980de/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME=
|
||||
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
|
||||
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@ -54,6 +58,8 @@ golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
|
122
core/tclient/tclient.go
Normal file
122
core/tclient/tclient.go
Normal file
@ -0,0 +1,122 @@
|
||||
package tclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/cenkalti/backoff/v4"
|
||||
"github.com/go-faster/errors"
|
||||
"github.com/gotd/contrib/clock"
|
||||
"github.com/gotd/contrib/middleware/floodwait"
|
||||
"github.com/gotd/contrib/middleware/ratelimit"
|
||||
tdclock "github.com/gotd/td/clock"
|
||||
"github.com/gotd/td/telegram"
|
||||
"github.com/gotd/td/telegram/dcs"
|
||||
"golang.org/x/net/proxy"
|
||||
"golang.org/x/time/rate"
|
||||
|
||||
"github.com/iyear/tdl/core/logctx"
|
||||
"github.com/iyear/tdl/core/middlewares/recovery"
|
||||
"github.com/iyear/tdl/core/middlewares/retry"
|
||||
"github.com/iyear/tdl/core/util/netutil"
|
||||
"github.com/iyear/tdl/core/util/tutil"
|
||||
)
|
||||
|
||||
type Options struct {
|
||||
AppID int
|
||||
AppHash string
|
||||
Session telegram.SessionStorage
|
||||
Middlewares []telegram.Middleware
|
||||
Proxy string
|
||||
NTP string
|
||||
ReconnectTimeout time.Duration
|
||||
Test bool
|
||||
UpdateHandler telegram.UpdateHandler
|
||||
}
|
||||
|
||||
// New creates new telegram client with given options.
|
||||
// Default middlewares(retry, recovery, flood wait) always added.
|
||||
func New(ctx context.Context, o Options) (*telegram.Client, error) {
|
||||
// process clock
|
||||
tclock := tdclock.System
|
||||
if ntp := o.NTP; ntp != "" {
|
||||
var err error
|
||||
tclock, err = clock.NewNTP(ntp)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "create network clock")
|
||||
}
|
||||
}
|
||||
|
||||
// process proxy
|
||||
var dialer dcs.DialFunc = proxy.Direct.DialContext
|
||||
if p := o.Proxy; p != "" {
|
||||
d, err := netutil.NewProxy(p)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "get dialer")
|
||||
}
|
||||
dialer = d.DialContext
|
||||
}
|
||||
|
||||
appID, appHash := o.AppID, o.AppHash
|
||||
|
||||
opts := telegram.Options{
|
||||
Resolver: dcs.Plain(dcs.PlainOptions{
|
||||
Dial: dialer,
|
||||
}),
|
||||
ReconnectionBackoff: func() backoff.BackOff {
|
||||
return newBackoff(o.ReconnectTimeout)
|
||||
},
|
||||
UpdateHandler: o.UpdateHandler,
|
||||
Device: tutil.Device,
|
||||
SessionStorage: o.Session,
|
||||
RetryInterval: 5 * time.Second,
|
||||
MaxRetries: -1, // infinite retries
|
||||
DialTimeout: 10 * time.Second,
|
||||
Middlewares: append(NewDefaultMiddlewares(ctx, o.ReconnectTimeout), o.Middlewares...),
|
||||
Clock: tclock,
|
||||
Logger: logctx.From(ctx).Named("td"),
|
||||
}
|
||||
|
||||
// test mode, hook options
|
||||
if o.Test {
|
||||
appID, appHash = telegram.TestAppID, telegram.TestAppHash
|
||||
opts.DC = 2
|
||||
opts.DCList = dcs.Test()
|
||||
// add rate limit to avoid frequent flood wait
|
||||
opts.Middlewares = append(opts.Middlewares, ratelimit.New(rate.Every(100*time.Millisecond), 5))
|
||||
}
|
||||
|
||||
return telegram.NewClient(appID, appHash, opts), nil
|
||||
}
|
||||
|
||||
func NewDefaultMiddlewares(ctx context.Context, timeout time.Duration) []telegram.Middleware {
|
||||
return []telegram.Middleware{
|
||||
recovery.New(ctx, newBackoff(timeout)),
|
||||
retry.New(5),
|
||||
floodwait.NewSimpleWaiter(),
|
||||
}
|
||||
}
|
||||
|
||||
func newBackoff(timeout time.Duration) backoff.BackOff {
|
||||
b := backoff.NewExponentialBackOff()
|
||||
|
||||
b.Multiplier = 1.1
|
||||
b.MaxElapsedTime = timeout
|
||||
b.MaxInterval = 10 * time.Second
|
||||
return b
|
||||
}
|
||||
|
||||
func RunWithAuth(ctx context.Context, client *telegram.Client, f func(ctx context.Context) error) error {
|
||||
return client.Run(ctx, func(ctx context.Context) error {
|
||||
status, err := client.Auth().Status(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !status.Authorized {
|
||||
return fmt.Errorf("not authorized. please login first")
|
||||
}
|
||||
|
||||
return f(ctx)
|
||||
})
|
||||
}
|
1
go.sum
1
go.sum
@ -155,6 +155,7 @@ github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
|
@ -5,22 +5,9 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/cenkalti/backoff/v4"
|
||||
"github.com/go-faster/errors"
|
||||
"github.com/gotd/contrib/middleware/floodwait"
|
||||
"github.com/gotd/contrib/middleware/ratelimit"
|
||||
tdclock "github.com/gotd/td/clock"
|
||||
"github.com/gotd/td/telegram"
|
||||
"github.com/gotd/td/telegram/dcs"
|
||||
"golang.org/x/net/proxy"
|
||||
"golang.org/x/time/rate"
|
||||
|
||||
"github.com/iyear/tdl/core/logctx"
|
||||
"github.com/iyear/tdl/core/middlewares/recovery"
|
||||
"github.com/iyear/tdl/core/middlewares/retry"
|
||||
"github.com/iyear/tdl/core/util/netutil"
|
||||
"github.com/iyear/tdl/core/util/tutil"
|
||||
"github.com/iyear/tdl/pkg/clock"
|
||||
"github.com/iyear/tdl/core/tclient"
|
||||
"github.com/iyear/tdl/pkg/key"
|
||||
"github.com/iyear/tdl/pkg/kv"
|
||||
"github.com/iyear/tdl/pkg/storage"
|
||||
@ -36,15 +23,6 @@ type Options struct {
|
||||
}
|
||||
|
||||
func New(ctx context.Context, o Options, login bool, middlewares ...telegram.Middleware) (*telegram.Client, error) {
|
||||
_clock := tdclock.System
|
||||
if ntp := o.NTP; ntp != "" {
|
||||
var err error
|
||||
_clock, err = clock.New()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "create network clock")
|
||||
}
|
||||
}
|
||||
|
||||
mode, err := o.KV.Get(key.App())
|
||||
if err != nil {
|
||||
mode = []byte(AppBuiltin)
|
||||
@ -53,75 +31,16 @@ func New(ctx context.Context, o Options, login bool, middlewares ...telegram.Mid
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("can't find app: %s, please try re-login", mode)
|
||||
}
|
||||
appId, appHash := app.AppID, app.AppHash
|
||||
|
||||
// process proxy
|
||||
var dialer dcs.DialFunc = proxy.Direct.DialContext
|
||||
if p := o.Proxy; p != "" {
|
||||
d, err := netutil.NewProxy(p)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "get dialer")
|
||||
}
|
||||
dialer = d.DialContext
|
||||
}
|
||||
|
||||
opts := telegram.Options{
|
||||
Resolver: dcs.Plain(dcs.PlainOptions{
|
||||
Dial: dialer,
|
||||
}),
|
||||
ReconnectionBackoff: func() backoff.BackOff {
|
||||
return newBackoff(o.ReconnectTimeout)
|
||||
},
|
||||
UpdateHandler: o.UpdateHandler,
|
||||
Device: tutil.Device,
|
||||
SessionStorage: storage.NewSession(o.KV, login),
|
||||
RetryInterval: 5 * time.Second,
|
||||
MaxRetries: -1, // infinite retries
|
||||
DialTimeout: 10 * time.Second,
|
||||
Middlewares: append(NewDefaultMiddlewares(ctx, o.ReconnectTimeout), middlewares...),
|
||||
Clock: _clock,
|
||||
Logger: logctx.From(ctx).Named("td"),
|
||||
}
|
||||
|
||||
// test mode, hook options
|
||||
if o.Test {
|
||||
appId, appHash = telegram.TestAppID, telegram.TestAppHash
|
||||
opts.DC = 2
|
||||
opts.DCList = dcs.Test()
|
||||
// add rate limit to avoid frequent flood wait
|
||||
opts.Middlewares = append(opts.Middlewares, ratelimit.New(rate.Every(100*time.Millisecond), 5))
|
||||
}
|
||||
|
||||
return telegram.NewClient(appId, appHash, opts), nil
|
||||
}
|
||||
|
||||
func NewDefaultMiddlewares(ctx context.Context, timeout time.Duration) []telegram.Middleware {
|
||||
return []telegram.Middleware{
|
||||
recovery.New(ctx, newBackoff(timeout)),
|
||||
retry.New(5),
|
||||
floodwait.NewSimpleWaiter(),
|
||||
}
|
||||
}
|
||||
|
||||
func newBackoff(timeout time.Duration) backoff.BackOff {
|
||||
b := backoff.NewExponentialBackOff()
|
||||
|
||||
b.Multiplier = 1.1
|
||||
b.MaxElapsedTime = timeout
|
||||
b.MaxInterval = 10 * time.Second
|
||||
return b
|
||||
}
|
||||
|
||||
func Run(ctx context.Context, client *telegram.Client, f func(ctx context.Context) error) error {
|
||||
return client.Run(ctx, func(ctx context.Context) error {
|
||||
status, err := client.Auth().Status(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !status.Authorized {
|
||||
return fmt.Errorf("not authorized. please login first")
|
||||
}
|
||||
|
||||
return f(ctx)
|
||||
return tclient.New(ctx, tclient.Options{
|
||||
AppID: app.AppID,
|
||||
AppHash: app.AppHash,
|
||||
Session: storage.NewSession(o.KV, login),
|
||||
Middlewares: middlewares,
|
||||
Proxy: o.Proxy,
|
||||
NTP: o.NTP,
|
||||
ReconnectTimeout: o.ReconnectTimeout,
|
||||
Test: o.Test,
|
||||
UpdateHandler: o.UpdateHandler,
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user