merge datexslx
This commit is contained in:
commit
4bf92cd14a
@ -5,11 +5,17 @@ include:
|
|||||||
file: "/templates/docker/deploy-template.gitlab-ci.yml"
|
file: "/templates/docker/deploy-template.gitlab-ci.yml"
|
||||||
- project: "devops/pena-continuous-integration"
|
- project: "devops/pena-continuous-integration"
|
||||||
file: "/templates/docker/golint.gitlab-ci.yml"
|
file: "/templates/docker/golint.gitlab-ci.yml"
|
||||||
|
- project: "devops/pena-continuous-integration"
|
||||||
|
file: "/templates/docker/service-discovery.gitlab-ci.yml"
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- lint
|
- lint
|
||||||
- build
|
- build
|
||||||
- deploy
|
- deploy
|
||||||
|
- service-discovery
|
||||||
|
|
||||||
|
lint:
|
||||||
|
extends: .golint_template
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
extends: .golint_template
|
extends: .golint_template
|
||||||
@ -42,3 +48,6 @@ deploy-prod:
|
|||||||
- if: "$CI_COMMIT_BRANCH == $PRODUCTION_BRANCH"
|
- if: "$CI_COMMIT_BRANCH == $PRODUCTION_BRANCH"
|
||||||
after_script:
|
after_script:
|
||||||
- ls
|
- ls
|
||||||
|
|
||||||
|
service-discovery:
|
||||||
|
extends: .sd_artefacts_template
|
||||||
|
259
app/app.go
Normal file
259
app/app.go
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/go-redis/redis/v8"
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"github.com/skeris/appInit"
|
||||||
|
"github.com/themakers/hlog"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"go.uber.org/zap/zapcore"
|
||||||
|
"penahub.gitlab.yandexcloud.net/backend/penahub_common/log_mw"
|
||||||
|
"penahub.gitlab.yandexcloud.net/backend/penahub_common/privilege"
|
||||||
|
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal"
|
||||||
|
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/healthchecks"
|
||||||
|
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/middleware"
|
||||||
|
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model"
|
||||||
|
"penahub.gitlab.yandexcloud.net/backend/quiz/core/brokers"
|
||||||
|
"penahub.gitlab.yandexcloud.net/backend/quiz/core/clients/auth"
|
||||||
|
//"penahub.gitlab.yandexcloud.net/backend/quiz/core/clients/telegram"
|
||||||
|
"penahub.gitlab.yandexcloud.net/backend/quiz/core/initialize"
|
||||||
|
"penahub.gitlab.yandexcloud.net/backend/quiz/core/models"
|
||||||
|
"penahub.gitlab.yandexcloud.net/backend/quiz/core/server"
|
||||||
|
"penahub.gitlab.yandexcloud.net/backend/quiz/core/service"
|
||||||
|
"penahub.gitlab.yandexcloud.net/backend/quiz/core/tools"
|
||||||
|
//"penahub.gitlab.yandexcloud.net/backend/quiz/core/workers"
|
||||||
|
"penahub.gitlab.yandexcloud.net/external/trashlog/wrappers/zaptrashlog"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type App struct {
|
||||||
|
logger *zap.Logger
|
||||||
|
err chan error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a App) GetLogger() *zap.Logger {
|
||||||
|
return a.logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a App) GetErr() chan error {
|
||||||
|
return a.err
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
errInvalidOptions = errors.New("invalid options")
|
||||||
|
)
|
||||||
|
|
||||||
|
var zapOptions = []zap.Option{
|
||||||
|
zap.AddCaller(),
|
||||||
|
zap.AddCallerSkip(2),
|
||||||
|
zap.AddStacktrace(zap.ErrorLevel),
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ appInit.CommonApp = (*App)(nil)
|
||||||
|
|
||||||
|
type Options struct {
|
||||||
|
LoggerProdMode bool `env:"IS_PROD_LOG" default:"false"`
|
||||||
|
IsProd bool `env:"IS_PROD" default:"false"`
|
||||||
|
NumberPort string `env:"PORT" default:"1488"`
|
||||||
|
CrtFile string `env:"CRT" default:"server.crt"`
|
||||||
|
KeyFile string `env:"KEY" default:"server.key"`
|
||||||
|
PostgresCredentials string `env:"PG_CRED" default:"host=localhost port=35432 user=squiz password=Redalert2 dbname=squiz sslmode=disable"`
|
||||||
|
HubAdminUrl string `env:"HUB_ADMIN_URL" default:"http://localhost:8001/"`
|
||||||
|
ServiceName string `env:"SERVICE_NAME" default:"squiz"`
|
||||||
|
AuthServiceURL string `env:"AUTH_URL" default:"http://localhost:8000/"`
|
||||||
|
GrpcHost string `env:"GRPC_HOST" default:"localhost"`
|
||||||
|
GrpcPort string `env:"GRPC_PORT" default:"9000"`
|
||||||
|
KafkaBrokers string `env:"KAFKA_BROKERS" default:"localhost:9092"`
|
||||||
|
KafkaTopic string `env:"KAFKA_TOPIC" default:"test-topic"`
|
||||||
|
KafkaGroup string `env:"KAFKA_GROUP" default:"mailnotifier"`
|
||||||
|
TrashLogHost string `env:"TRASH_LOG_HOST" default:"localhost:7113"`
|
||||||
|
ModuleLogger string `env:"MODULE_LOGGER" default:"core-local"`
|
||||||
|
ClickHouseCred string `env:"CLICK_HOUSE_CRED" default:"tcp://10.8.0.15:9000/default?sslmode=disable"`
|
||||||
|
RedisHost string `env:"REDIS_HOST" default:"localhost:6379"`
|
||||||
|
RedisPassword string `env:"REDIS_PASSWORD" default:"admin"`
|
||||||
|
RedisDB uint64 `env:"REDIS_DB" default:"2"`
|
||||||
|
S3Prefix string `env:"S3_PREFIX"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(ctx context.Context, opts interface{}, ver appInit.Version) (appInit.CommonApp, error) {
|
||||||
|
var (
|
||||||
|
err, workerErr error
|
||||||
|
zapLogger *zap.Logger
|
||||||
|
errChan = make(chan error)
|
||||||
|
options Options
|
||||||
|
ok bool
|
||||||
|
)
|
||||||
|
|
||||||
|
if options, ok = opts.(Options); !ok {
|
||||||
|
return App{}, errInvalidOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
if options.LoggerProdMode {
|
||||||
|
zapLogger, err = zap.NewProduction(zapOptions...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
zapLogger, err = zap.NewDevelopment(zapOptions...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zapLogger = zapLogger.With(
|
||||||
|
zap.String("SvcCommit", ver.Commit),
|
||||||
|
zap.String("SvcVersion", ver.Release),
|
||||||
|
zap.String("SvcBuildTime", ver.BuildTime),
|
||||||
|
)
|
||||||
|
|
||||||
|
clickHouseLogger, err := zaptrashlog.NewCore(ctx, zap.InfoLevel, options.TrashLogHost, ver.Release, ver.Commit, time.Now().Unix())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
loggerForHlog := zapLogger.WithOptions(zap.WrapCore(func(core zapcore.Core) zapcore.Core {
|
||||||
|
return zapcore.NewTee(core, clickHouseLogger)
|
||||||
|
}))
|
||||||
|
|
||||||
|
loggerHlog := hlog.New(loggerForHlog).Module(options.ModuleLogger)
|
||||||
|
loggerHlog.With(models.AllFields{})
|
||||||
|
loggerHlog.Emit(InfoSvcStarted{})
|
||||||
|
|
||||||
|
authClient := auth.NewAuthClient(options.AuthServiceURL)
|
||||||
|
|
||||||
|
pgdal, err := dal.New(ctx, options.PostgresCredentials, nil)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("NEW", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
chDal, err := dal.NewClickHouseDAL(ctx, options.ClickHouseCred)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("failed init clickhouse", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
kafkaClient, err := initialize.KafkaInit(ctx, initialize.KafkaDeps{
|
||||||
|
KafkaGroup: options.KafkaGroup,
|
||||||
|
KafkaBrokers: options.KafkaBrokers,
|
||||||
|
KafkaTopic: options.KafkaTopic,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
producer := brokers.NewProducer(brokers.ProducerDeps{
|
||||||
|
KafkaClient: kafkaClient,
|
||||||
|
Logger: zapLogger,
|
||||||
|
})
|
||||||
|
|
||||||
|
redisClient := redis.NewClient(&redis.Options{
|
||||||
|
Addr: options.RedisHost,
|
||||||
|
Password: options.RedisPassword,
|
||||||
|
DB: int(options.RedisDB),
|
||||||
|
})
|
||||||
|
err = redisClient.Ping(ctx).Err()
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("error ping to redis db %v", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
clientData := privilege.Client{
|
||||||
|
URL: options.HubAdminUrl,
|
||||||
|
ServiceName: options.ServiceName,
|
||||||
|
Privileges: model.Privileges,
|
||||||
|
}
|
||||||
|
fiberClient := &fiber.Client{}
|
||||||
|
privilegeController := privilege.NewPrivilege(clientData, fiberClient)
|
||||||
|
go tools.PublishPrivilege(privilegeController, 10, 5*time.Minute)
|
||||||
|
|
||||||
|
// tgClient, err := telegram.NewTelegramClient(ctx, pgdal)
|
||||||
|
// if err != nil {
|
||||||
|
// panic(fmt.Sprintf("failed init tg clietns: %v", err))
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// tgWC := workers.NewTgListenerWC(workers.Deps{
|
||||||
|
// BotID: int64(6712573453), // todo убрать
|
||||||
|
// Redis: redisClient,
|
||||||
|
// Dal: pgdal,
|
||||||
|
// TgClient: tgClient,
|
||||||
|
// })
|
||||||
|
//
|
||||||
|
// go tgWC.Start(ctx)
|
||||||
|
|
||||||
|
// todo подумать над реализацией всего а то пока мне кажется что немного каша получается такой предикт что через некоторое время
|
||||||
|
// сложно будет разобраться что есть где
|
||||||
|
grpcControllers := initialize.InitRpcControllers(pgdal)
|
||||||
|
grpc, err := server.NewGRPC(zapLogger)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("error:", err)
|
||||||
|
panic("err init grpc server")
|
||||||
|
}
|
||||||
|
grpc.Register(grpcControllers)
|
||||||
|
go grpc.Run(server.DepsGrpcRun{
|
||||||
|
Host: options.GrpcHost,
|
||||||
|
Port: options.GrpcPort,
|
||||||
|
})
|
||||||
|
|
||||||
|
app := fiber.New()
|
||||||
|
app.Use(middleware.JWTAuth())
|
||||||
|
app.Use(log_mw.ContextLogger(loggerHlog))
|
||||||
|
app.Get("/liveness", healthchecks.Liveness)
|
||||||
|
app.Get("/readiness", healthchecks.Readiness(&workerErr)) //todo parametrized readiness. should discuss ready reason
|
||||||
|
|
||||||
|
svc := service.New(service.Deps{
|
||||||
|
Dal: pgdal,
|
||||||
|
AuthClient: authClient,
|
||||||
|
Producer: producer,
|
||||||
|
ServiceName: options.ServiceName,
|
||||||
|
ChDAL: chDal,
|
||||||
|
// TelegramClient: tgClient,
|
||||||
|
RedisClient: redisClient,
|
||||||
|
S3Prefix: options.S3Prefix,
|
||||||
|
})
|
||||||
|
|
||||||
|
svc.Register(app)
|
||||||
|
|
||||||
|
loggerHlog.Emit(InfoSvcReady{})
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
if pgdal != nil {
|
||||||
|
pgdal.Close()
|
||||||
|
}
|
||||||
|
if chDal != nil {
|
||||||
|
if derr := chDal.Close(ctx); derr != nil {
|
||||||
|
fmt.Printf("error closing clickhouse: %v", derr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err := grpc.Stop(ctx)
|
||||||
|
err = app.Shutdown()
|
||||||
|
loggerHlog.Emit(InfoSvcShutdown{Signal: err.Error()})
|
||||||
|
}()
|
||||||
|
|
||||||
|
if options.IsProd {
|
||||||
|
if err := app.ListenTLS(fmt.Sprintf(":%s", options.NumberPort), options.CrtFile, options.KeyFile); err != nil {
|
||||||
|
loggerHlog.Emit(ErrorCanNotServe{
|
||||||
|
Err: err,
|
||||||
|
})
|
||||||
|
errChan <- err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err := app.Listen(fmt.Sprintf(":%s", options.NumberPort)); err != nil {
|
||||||
|
loggerHlog.Emit(ErrorCanNotServe{
|
||||||
|
Err: err,
|
||||||
|
})
|
||||||
|
errChan <- err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
errChan <- nil
|
||||||
|
}()
|
||||||
|
// todo implement helper func for service app type. such as server preparing, logger preparing, healthchecks and etc.
|
||||||
|
return &App{
|
||||||
|
logger: zapLogger,
|
||||||
|
err: errChan,
|
||||||
|
}, err
|
||||||
|
}
|
@ -1,10 +1,12 @@
|
|||||||
version: "3"
|
version: "3"
|
||||||
services:
|
services:
|
||||||
core:
|
core:
|
||||||
hostname: squiz-core
|
hostname: squiz
|
||||||
container_name: squiz-core
|
container_name: squiz
|
||||||
image: $CI_REGISTRY_IMAGE/staging-core:$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID
|
image: $CI_REGISTRY_IMAGE/staging-core:$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID
|
||||||
tty: true
|
tty: true
|
||||||
|
labels:
|
||||||
|
com.pena.allowed_headers: content-type,authorization,device,browser,os,devicetype,response-type
|
||||||
environment:
|
environment:
|
||||||
HUB_ADMIN_URL: 'http://10.8.0.6:59303'
|
HUB_ADMIN_URL: 'http://10.8.0.6:59303'
|
||||||
IS_PROD_LOG: 'false'
|
IS_PROD_LOG: 'false'
|
||||||
@ -22,6 +24,9 @@ services:
|
|||||||
TRASH_LOG_HOST: "10.8.0.15:7113"
|
TRASH_LOG_HOST: "10.8.0.15:7113"
|
||||||
MODULE_LOGGER: "quiz-core-staging"
|
MODULE_LOGGER: "quiz-core-staging"
|
||||||
CLICK_HOUSE_CRED: "clickhouse://10.8.0.15:9000/default?sslmode=disable"
|
CLICK_HOUSE_CRED: "clickhouse://10.8.0.15:9000/default?sslmode=disable"
|
||||||
|
REDIS_HOST: '10.8.0.5:6379'
|
||||||
|
REDIS_PASSWORD: 'Redalert2'
|
||||||
|
REDIS_DB: 2
|
||||||
ports:
|
ports:
|
||||||
- 10.8.0.5:1488:1488
|
- 10.8.0.5:1488:1488
|
||||||
- 10.8.0.5:9000:9000
|
- 10.8.0.5:9000:9000
|
||||||
|
21
go.mod
21
go.mod
@ -1,6 +1,6 @@
|
|||||||
module penahub.gitlab.yandexcloud.net/backend/quiz/core
|
module penahub.gitlab.yandexcloud.net/backend/quiz/core
|
||||||
|
|
||||||
go 1.22.4
|
go 1.22.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/go-redis/redis/v8 v8.11.5
|
github.com/go-redis/redis/v8 v8.11.5
|
||||||
@ -10,19 +10,18 @@ require (
|
|||||||
github.com/joho/godotenv v1.5.1
|
github.com/joho/godotenv v1.5.1
|
||||||
github.com/lib/pq v1.10.9
|
github.com/lib/pq v1.10.9
|
||||||
github.com/pioz/faker v1.7.3
|
github.com/pioz/faker v1.7.3
|
||||||
github.com/rs/xid v1.5.0
|
github.com/rs/xid v1.6.0
|
||||||
github.com/skeris/appInit v1.0.2
|
github.com/skeris/appInit v1.0.2
|
||||||
github.com/stretchr/testify v1.9.0
|
github.com/stretchr/testify v1.9.0
|
||||||
github.com/themakers/hlog v0.0.0-20191205140925-235e0e4baddf
|
github.com/themakers/hlog v0.0.0-20191205140925-235e0e4baddf
|
||||||
github.com/twmb/franz-go v1.16.1
|
github.com/twmb/franz-go v1.16.1
|
||||||
github.com/xuri/excelize/v2 v2.8.1
|
github.com/xuri/excelize/v2 v2.8.1
|
||||||
go.uber.org/zap v1.27.0
|
go.uber.org/zap v1.27.0
|
||||||
google.golang.org/grpc v1.64.0
|
google.golang.org/grpc v1.66.0
|
||||||
google.golang.org/protobuf v1.34.2
|
google.golang.org/protobuf v1.34.2
|
||||||
penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240607202348-efe5f2bf3e8c
|
penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240607202348-efe5f2bf3e8c
|
||||||
penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20241025130405-8ab347d96f1f
|
|
||||||
penahub.gitlab.yandexcloud.net/backend/quiz/worker.git v0.0.0-20240421230341-0e086fcbb990
|
penahub.gitlab.yandexcloud.net/backend/quiz/worker.git v0.0.0-20240421230341-0e086fcbb990
|
||||||
penahub.gitlab.yandexcloud.net/backend/tdlib v0.0.0-20240701075856-1731684c936f
|
penahub.gitlab.yandexcloud.net/devops/linters/golang.git v0.0.0-20240829220549-d35409b619a3
|
||||||
penahub.gitlab.yandexcloud.net/external/trashlog v0.1.6-0.20240827173635-78ce9878c387
|
penahub.gitlab.yandexcloud.net/external/trashlog v0.1.6-0.20240827173635-78ce9878c387
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -59,13 +58,13 @@ require (
|
|||||||
github.com/valyala/tcplisten v1.0.0 // indirect
|
github.com/valyala/tcplisten v1.0.0 // indirect
|
||||||
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d // indirect
|
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d // indirect
|
||||||
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 // indirect
|
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 // indirect
|
||||||
go.etcd.io/bbolt v1.3.6 // indirect
|
go.etcd.io/bbolt v1.3.11 // indirect
|
||||||
go.uber.org/multierr v1.11.0 // indirect
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
golang.org/x/crypto v0.24.0 // indirect
|
golang.org/x/crypto v0.27.0 // indirect
|
||||||
golang.org/x/net v0.26.0 // indirect
|
golang.org/x/net v0.29.0 // indirect
|
||||||
golang.org/x/sys v0.21.0 // indirect
|
golang.org/x/sys v0.25.0 // indirect
|
||||||
golang.org/x/text v0.16.0 // indirect
|
golang.org/x/text v0.18.0 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240610135401-a8a62080eff3 // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
43
go.sum
43
go.sum
@ -128,8 +128,8 @@ github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUc
|
|||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||||
github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
|
github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=
|
||||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
github.com/skeris/appInit v1.0.2 h1:Hr4KbXYd6kolTVq4cXGqDpgnpmaauiOiKizA1+Ep4KQ=
|
github.com/skeris/appInit v1.0.2 h1:Hr4KbXYd6kolTVq4cXGqDpgnpmaauiOiKizA1+Ep4KQ=
|
||||||
github.com/skeris/appInit v1.0.2/go.mod h1:4ElEeXWVGzU3dlYq/eMWJ/U5hd+LKisc1z3+ySh1XmY=
|
github.com/skeris/appInit v1.0.2/go.mod h1:4ElEeXWVGzU3dlYq/eMWJ/U5hd+LKisc1z3+ySh1XmY=
|
||||||
@ -165,8 +165,8 @@ github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 h1:hPVCafDV85blFTabnqKgNh
|
|||||||
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
|
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
|
go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0=
|
||||||
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
|
go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I=
|
||||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||||
@ -185,8 +185,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
|||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
|
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
|
||||||
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4=
|
golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4=
|
||||||
golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
|
golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
|
||||||
@ -205,30 +205,31 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
|
|||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
|
||||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||||
|
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
|
||||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
@ -250,15 +251,15 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
|
|||||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240610135401-a8a62080eff3 h1:9Xyg6I9IWQZhRVfCWjKK+l6kI0jHcPesVlMnT//aHNo=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240610135401-a8a62080eff3/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||||
google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY=
|
google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c=
|
||||||
google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg=
|
google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
|
||||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
@ -288,11 +289,11 @@ penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240607202348-efe5
|
|||||||
penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240607202348-efe5f2bf3e8c/go.mod h1:+bPxq2wfW5S1gd+83vZYmHm33AE7nEBfznWS8AM1TKE=
|
penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240607202348-efe5f2bf3e8c/go.mod h1:+bPxq2wfW5S1gd+83vZYmHm33AE7nEBfznWS8AM1TKE=
|
||||||
penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240711133242-0b8534fae5b2 h1:0t6pQHJvA3jMeBB3FPUmA+hw8rWlksTah8KJEtf2KD8=
|
penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240711133242-0b8534fae5b2 h1:0t6pQHJvA3jMeBB3FPUmA+hw8rWlksTah8KJEtf2KD8=
|
||||||
penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240711133242-0b8534fae5b2/go.mod h1:uOuosXduBzd2WbLH6TDZO7ME7ZextulA662oZ6OsoB0=
|
penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240711133242-0b8534fae5b2/go.mod h1:uOuosXduBzd2WbLH6TDZO7ME7ZextulA662oZ6OsoB0=
|
||||||
penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20241025130405-8ab347d96f1f h1:HMXxbIkNmFeQTFI/MlsDBIRUTu8MTbn3i2PVcpQbXEI=
|
penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240919124706-53cacd30903a h1:loD4hoCkx1ZTqw0mg/Br4RT2GI1vT2WvEh0I/j+DPo8=
|
||||||
penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20241025130405-8ab347d96f1f/go.mod h1:uOuosXduBzd2WbLH6TDZO7ME7ZextulA662oZ6OsoB0=
|
penahub.gitlab.yandexcloud.net/backend/quiz/common.git v0.0.0-20240919124706-53cacd30903a/go.mod h1:uOuosXduBzd2WbLH6TDZO7ME7ZextulA662oZ6OsoB0=
|
||||||
penahub.gitlab.yandexcloud.net/backend/quiz/worker.git v0.0.0-20240421230341-0e086fcbb990 h1:jiO8GWO+3sCnDAV8/NAV8tQIUwae/I6/xiDilW7zf0o=
|
penahub.gitlab.yandexcloud.net/backend/quiz/worker.git v0.0.0-20240421230341-0e086fcbb990 h1:jiO8GWO+3sCnDAV8/NAV8tQIUwae/I6/xiDilW7zf0o=
|
||||||
penahub.gitlab.yandexcloud.net/backend/quiz/worker.git v0.0.0-20240421230341-0e086fcbb990/go.mod h1:zswBuTwmEsFHBVRu1nkG3/Fwylk5Vcm8OUm9iWxccSE=
|
penahub.gitlab.yandexcloud.net/backend/quiz/worker.git v0.0.0-20240421230341-0e086fcbb990/go.mod h1:zswBuTwmEsFHBVRu1nkG3/Fwylk5Vcm8OUm9iWxccSE=
|
||||||
penahub.gitlab.yandexcloud.net/backend/tdlib v0.0.0-20240701075856-1731684c936f h1:Qli89wgu0T7nG4VECXZOZ40fjE/hVVfxF3hTaSYS008=
|
penahub.gitlab.yandexcloud.net/devops/linters/golang.git v0.0.0-20240829220549-d35409b619a3 h1:sf6e2mp582L3i/FMDd2q6QuWm1njRXzYpIX0SipsvM4=
|
||||||
penahub.gitlab.yandexcloud.net/backend/tdlib v0.0.0-20240701075856-1731684c936f/go.mod h1:AkE19hcbDwB7hoEASwImm7rUI+cK/8jMVJaTvMK4F+c=
|
penahub.gitlab.yandexcloud.net/devops/linters/golang.git v0.0.0-20240829220549-d35409b619a3/go.mod h1:i7M72RIpkSjcQtHID6KKj9RT/EYZ1rxS6tIPKWa/BSY=
|
||||||
penahub.gitlab.yandexcloud.net/external/trashlog v0.1.6-0.20240827173635-78ce9878c387 h1:G+GIhkkvUsM9No2rf2D4kvQ2ExTw9KxlA8vsSnC0ywU=
|
penahub.gitlab.yandexcloud.net/external/trashlog v0.1.6-0.20240827173635-78ce9878c387 h1:G+GIhkkvUsM9No2rf2D4kvQ2ExTw9KxlA8vsSnC0ywU=
|
||||||
penahub.gitlab.yandexcloud.net/external/trashlog v0.1.6-0.20240827173635-78ce9878c387/go.mod h1:30nezjpGpZuNThbQOCULIfa79RoJ5sray593jhfVP/Q=
|
penahub.gitlab.yandexcloud.net/external/trashlog v0.1.6-0.20240827173635-78ce9878c387/go.mod h1:30nezjpGpZuNThbQOCULIfa79RoJ5sray593jhfVP/Q=
|
||||||
|
@ -1,246 +1,246 @@
|
|||||||
package telegram
|
package telegram
|
||||||
|
//
|
||||||
import (
|
// import (
|
||||||
"context"
|
// "context"
|
||||||
"errors"
|
// "errors"
|
||||||
"fmt"
|
// "fmt"
|
||||||
"path/filepath"
|
// "path/filepath"
|
||||||
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal"
|
// "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal"
|
||||||
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model"
|
// "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model"
|
||||||
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/pj_errors"
|
// "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/pj_errors"
|
||||||
"penahub.gitlab.yandexcloud.net/backend/tdlib/client"
|
// "penahub.gitlab.yandexcloud.net/backend/tdlib/client"
|
||||||
"sync"
|
// "sync"
|
||||||
"time"
|
// "time"
|
||||||
)
|
// )
|
||||||
|
//
|
||||||
type TelegramClient struct {
|
// type TelegramClient struct {
|
||||||
repo *dal.DAL
|
// repo *dal.DAL
|
||||||
TgClients map[int64]*client.Client
|
// TgClients map[int64]*client.Client
|
||||||
WaitingClients map[string]WaitingClient
|
// WaitingClients map[string]WaitingClient
|
||||||
mu sync.Mutex
|
// mu sync.Mutex
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
type WaitingClient struct {
|
// type WaitingClient struct {
|
||||||
PreviousReq AuthTgUserReq
|
// PreviousReq AuthTgUserReq
|
||||||
Authorizer *client.ClientAuthorizer
|
// Authorizer *client.ClientAuthorizer
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
func NewTelegramClient(ctx context.Context, repo *dal.DAL) (*TelegramClient, error) {
|
// func NewTelegramClient(ctx context.Context, repo *dal.DAL) (*TelegramClient, error) {
|
||||||
tgClient := &TelegramClient{
|
// tgClient := &TelegramClient{
|
||||||
repo: repo,
|
// repo: repo,
|
||||||
TgClients: make(map[int64]*client.Client),
|
// TgClients: make(map[int64]*client.Client),
|
||||||
WaitingClients: make(map[string]WaitingClient),
|
// WaitingClients: make(map[string]WaitingClient),
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
allTgAccounts, err := repo.TgRepo.GetAllTgAccounts(ctx)
|
// allTgAccounts, err := repo.TgRepo.GetAllTgAccounts(ctx)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
if errors.Is(err, pj_errors.ErrNotFound) {
|
// if errors.Is(err, pj_errors.ErrNotFound) {
|
||||||
return tgClient, nil
|
// return tgClient, nil
|
||||||
}
|
// }
|
||||||
return nil, err
|
// return nil, err
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
for _, account := range allTgAccounts {
|
// for _, account := range allTgAccounts {
|
||||||
if account.Status == model.ActiveTg {
|
// if account.Status == model.ActiveTg {
|
||||||
authorizer := client.ClientAuthorizerr()
|
// authorizer := client.ClientAuthorizerr()
|
||||||
authorizer.TdlibParameters <- &client.SetTdlibParametersRequest{
|
// authorizer.TdlibParameters <- &client.SetTdlibParametersRequest{
|
||||||
UseTestDc: false,
|
// UseTestDc: false,
|
||||||
DatabaseDirectory: filepath.Join(".tdlib", "database"),
|
// DatabaseDirectory: filepath.Join(".tdlib", "database"),
|
||||||
FilesDirectory: filepath.Join(".tdlib", "files"),
|
// FilesDirectory: filepath.Join(".tdlib", "files"),
|
||||||
UseFileDatabase: true,
|
// UseFileDatabase: true,
|
||||||
UseChatInfoDatabase: true,
|
// UseChatInfoDatabase: true,
|
||||||
UseMessageDatabase: true,
|
// UseMessageDatabase: true,
|
||||||
UseSecretChats: true,
|
// UseSecretChats: true,
|
||||||
ApiId: account.ApiID,
|
// ApiId: account.ApiID,
|
||||||
ApiHash: account.ApiHash,
|
// ApiHash: account.ApiHash,
|
||||||
SystemLanguageCode: "en",
|
// SystemLanguageCode: "en",
|
||||||
DeviceModel: "Server",
|
// DeviceModel: "Server",
|
||||||
SystemVersion: "1.0.0",
|
// SystemVersion: "1.0.0",
|
||||||
ApplicationVersion: "1.0.0",
|
// ApplicationVersion: "1.0.0",
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
_, err := client.SetLogVerbosityLevel(&client.SetLogVerbosityLevelRequest{
|
// _, err := client.SetLogVerbosityLevel(&client.SetLogVerbosityLevelRequest{
|
||||||
NewVerbosityLevel: 1,
|
// NewVerbosityLevel: 1,
|
||||||
})
|
// })
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return nil, err
|
// return nil, err
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
var tdlibClient *client.Client
|
// var tdlibClient *client.Client
|
||||||
var goErr error
|
// var goErr error
|
||||||
go func() {
|
// go func() {
|
||||||
tdlibClient, goErr = client.NewClient(authorizer)
|
// tdlibClient, goErr = client.NewClient(authorizer)
|
||||||
if goErr != nil {
|
// if goErr != nil {
|
||||||
fmt.Println("new client failed", err)
|
// fmt.Println("new client failed", err)
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
fmt.Println("i am down")
|
// fmt.Println("i am down")
|
||||||
}()
|
// }()
|
||||||
if goErr != nil {
|
// if goErr != nil {
|
||||||
return nil, goErr
|
// return nil, goErr
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
for {
|
// for {
|
||||||
state, ok := <-authorizer.State
|
// state, ok := <-authorizer.State
|
||||||
if !ok {
|
// if !ok {
|
||||||
break
|
// break
|
||||||
}
|
// }
|
||||||
fmt.Println("currnet state:", state)
|
// fmt.Println("currnet state:", state)
|
||||||
switch state.AuthorizationStateType() {
|
// switch state.AuthorizationStateType() {
|
||||||
case client.TypeAuthorizationStateWaitPhoneNumber:
|
// case client.TypeAuthorizationStateWaitPhoneNumber:
|
||||||
authorizer.PhoneNumber <- account.PhoneNumber
|
// authorizer.PhoneNumber <- account.PhoneNumber
|
||||||
case client.TypeAuthorizationStateWaitCode:
|
// case client.TypeAuthorizationStateWaitCode:
|
||||||
err := tgClient.repo.TgRepo.UpdateStatusTg(ctx, account.ID, model.InactiveTg)
|
// err := tgClient.repo.TgRepo.UpdateStatusTg(ctx, account.ID, model.InactiveTg)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return nil, err
|
// return nil, err
|
||||||
}
|
// }
|
||||||
case client.TypeAuthorizationStateLoggingOut, client.TypeAuthorizationStateClosing, client.TypeAuthorizationStateClosed:
|
// case client.TypeAuthorizationStateLoggingOut, client.TypeAuthorizationStateClosing, client.TypeAuthorizationStateClosed:
|
||||||
err := tgClient.repo.TgRepo.UpdateStatusTg(ctx, account.ID, model.InactiveTg)
|
// err := tgClient.repo.TgRepo.UpdateStatusTg(ctx, account.ID, model.InactiveTg)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return nil, err
|
// return nil, err
|
||||||
}
|
// }
|
||||||
case client.TypeAuthorizationStateReady:
|
// case client.TypeAuthorizationStateReady:
|
||||||
// костыль так как в либе тож костыль стоит пока там ьд обновиться будет ниловый всегда клиент
|
// // костыль так как в либе тож костыль стоит пока там ьд обновиться будет ниловый всегда клиент
|
||||||
time.Sleep(3 * time.Second)
|
// time.Sleep(3 * time.Second)
|
||||||
me, err := tdlibClient.GetMe()
|
// me, err := tdlibClient.GetMe()
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return nil, err
|
// return nil, err
|
||||||
}
|
// }
|
||||||
fmt.Printf("Me: %s %s [%v]", me.FirstName, me.LastName, me.Usernames)
|
// fmt.Printf("Me: %s %s [%v]", me.FirstName, me.LastName, me.Usernames)
|
||||||
tgClient.mu.Lock()
|
// tgClient.mu.Lock()
|
||||||
tgClient.TgClients[account.ID] = tdlibClient
|
// tgClient.TgClients[account.ID] = tdlibClient
|
||||||
tgClient.mu.Unlock()
|
// tgClient.mu.Unlock()
|
||||||
break
|
// break
|
||||||
case client.TypeAuthorizationStateWaitPassword:
|
// case client.TypeAuthorizationStateWaitPassword:
|
||||||
authorizer.Password <- account.Password
|
// authorizer.Password <- account.Password
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return tgClient, nil
|
// return tgClient, nil
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
type AuthTgUserReq struct {
|
// type AuthTgUserReq struct {
|
||||||
ApiID int32 `json:"api_id"`
|
// ApiID int32 `json:"api_id"`
|
||||||
ApiHash string `json:"api_hash"`
|
// ApiHash string `json:"api_hash"`
|
||||||
PhoneNumber string `json:"phone_number"`
|
// PhoneNumber string `json:"phone_number"`
|
||||||
Password string `json:"password"`
|
// Password string `json:"password"`
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
func (tg *TelegramClient) AddedToMap(data WaitingClient, id string) {
|
// func (tg *TelegramClient) AddedToMap(data WaitingClient, id string) {
|
||||||
fmt.Println("AddedToMap")
|
// fmt.Println("AddedToMap")
|
||||||
tg.mu.Lock()
|
// tg.mu.Lock()
|
||||||
defer tg.mu.Unlock()
|
// defer tg.mu.Unlock()
|
||||||
tg.WaitingClients[id] = data
|
// tg.WaitingClients[id] = data
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
func (tg *TelegramClient) GetFromMap(id string) (WaitingClient, bool) {
|
// func (tg *TelegramClient) GetFromMap(id string) (WaitingClient, bool) {
|
||||||
fmt.Println("GetFromMap")
|
// fmt.Println("GetFromMap")
|
||||||
tg.mu.Lock()
|
// tg.mu.Lock()
|
||||||
defer tg.mu.Unlock()
|
// defer tg.mu.Unlock()
|
||||||
if data, ok := tg.WaitingClients[id]; ok {
|
// if data, ok := tg.WaitingClients[id]; ok {
|
||||||
delete(tg.WaitingClients, id)
|
// delete(tg.WaitingClients, id)
|
||||||
return data, true
|
// return data, true
|
||||||
}
|
// }
|
||||||
return WaitingClient{}, false
|
// return WaitingClient{}, false
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
func (tg *TelegramClient) SaveTgAccount(appID int32, appHash string, tdLibClient *client.Client) {
|
// func (tg *TelegramClient) SaveTgAccount(appID int32, appHash string, tdLibClient *client.Client) {
|
||||||
account, err := tg.repo.TgRepo.SearchIDByAppIDanAppHash(context.Background(), appID, appHash)
|
// account, err := tg.repo.TgRepo.SearchIDByAppIDanAppHash(context.Background(), appID, appHash)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
fmt.Println("err SaveTgAccount", err)
|
// fmt.Println("err SaveTgAccount", err)
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
if account.Status == model.ActiveTg {
|
// if account.Status == model.ActiveTg {
|
||||||
tg.mu.Lock()
|
// tg.mu.Lock()
|
||||||
defer tg.mu.Unlock()
|
// defer tg.mu.Unlock()
|
||||||
tg.TgClients[account.ID] = tdLibClient
|
// tg.TgClients[account.ID] = tdLibClient
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
func (tg *TelegramClient) CreateChannel(channelName string, botID int64) (string, int64, error) {
|
// func (tg *TelegramClient) CreateChannel(channelName string, botID int64) (string, int64, error) {
|
||||||
tg.mu.Lock()
|
// tg.mu.Lock()
|
||||||
defer tg.mu.Unlock()
|
// defer tg.mu.Unlock()
|
||||||
if len(tg.TgClients) == 0 {
|
// if len(tg.TgClients) == 0 {
|
||||||
return "", 0, errors.New("no active Telegram clients")
|
// return "", 0, errors.New("no active Telegram clients")
|
||||||
}
|
// }
|
||||||
var lastError error
|
// var lastError error
|
||||||
var inviteLink string
|
// var inviteLink string
|
||||||
var channelId int64
|
// var channelId int64
|
||||||
for _, activeClient := range tg.TgClients {
|
// for _, activeClient := range tg.TgClients {
|
||||||
// todo пока не понимаю это какой то рандом? в один день бот норм находится в другой уже не находится хотя абсолютно с точки зрения тг кода этой функции и бота не менялось
|
// // todo пока не понимаю это какой то рандом? в один день бот норм находится в другой уже не находится хотя абсолютно с точки зрения тг кода этой функции и бота не менялось
|
||||||
_, err := activeClient.GetUser(&client.GetUserRequest{
|
// _, err := activeClient.GetUser(&client.GetUserRequest{
|
||||||
UserId: botID,
|
// UserId: botID,
|
||||||
})
|
// })
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
lastError = fmt.Errorf("not found this bot, make privacy off: %v", err)
|
// lastError = fmt.Errorf("not found this bot, make privacy off: %v", err)
|
||||||
continue
|
// continue
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// todo нужно поймать ошибку, при которой либо бан либо медленный редим включается для того чтобы прервать
|
// // todo нужно поймать ошибку, при которой либо бан либо медленный редим включается для того чтобы прервать
|
||||||
// исполнение клиента текущего аккаунта и дать задачу следующему пока поймал 1 раз и не запомнил больше не получается
|
// // исполнение клиента текущего аккаунта и дать задачу следующему пока поймал 1 раз и не запомнил больше не получается
|
||||||
channel, err := activeClient.CreateNewSupergroupChat(&client.CreateNewSupergroupChatRequest{
|
// channel, err := activeClient.CreateNewSupergroupChat(&client.CreateNewSupergroupChatRequest{
|
||||||
Title: channelName,
|
// Title: channelName,
|
||||||
IsChannel: true,
|
// IsChannel: true,
|
||||||
Description: "private channel",
|
// Description: "private channel",
|
||||||
})
|
// })
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
lastError = fmt.Errorf("failed to create channel: %s", err.Error())
|
// lastError = fmt.Errorf("failed to create channel: %s", err.Error())
|
||||||
continue
|
// continue
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
_, err = activeClient.SetChatMemberStatus(&client.SetChatMemberStatusRequest{
|
// _, err = activeClient.SetChatMemberStatus(&client.SetChatMemberStatusRequest{
|
||||||
ChatId: channel.Id,
|
// ChatId: channel.Id,
|
||||||
MemberId: &client.MessageSenderUser{UserId: botID},
|
// MemberId: &client.MessageSenderUser{UserId: botID},
|
||||||
Status: &client.ChatMemberStatusAdministrator{
|
// Status: &client.ChatMemberStatusAdministrator{
|
||||||
CustomTitle: "bot",
|
// CustomTitle: "bot",
|
||||||
Rights: &client.ChatAdministratorRights{
|
// Rights: &client.ChatAdministratorRights{
|
||||||
CanManageChat: true,
|
// CanManageChat: true,
|
||||||
CanChangeInfo: true,
|
// CanChangeInfo: true,
|
||||||
CanPostMessages: true,
|
// CanPostMessages: true,
|
||||||
CanEditMessages: true,
|
// CanEditMessages: true,
|
||||||
CanDeleteMessages: true,
|
// CanDeleteMessages: true,
|
||||||
CanInviteUsers: true,
|
// CanInviteUsers: true,
|
||||||
CanRestrictMembers: true,
|
// CanRestrictMembers: true,
|
||||||
CanPinMessages: true,
|
// CanPinMessages: true,
|
||||||
CanManageTopics: true,
|
// CanManageTopics: true,
|
||||||
CanPromoteMembers: true,
|
// CanPromoteMembers: true,
|
||||||
CanManageVideoChats: true,
|
// CanManageVideoChats: true,
|
||||||
CanPostStories: true,
|
// CanPostStories: true,
|
||||||
CanEditStories: true,
|
// CanEditStories: true,
|
||||||
CanDeleteStories: true,
|
// CanDeleteStories: true,
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
})
|
// })
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
lastError = fmt.Errorf("failed to make bot admin: %s", err.Error())
|
// lastError = fmt.Errorf("failed to make bot admin: %s", err.Error())
|
||||||
continue
|
// continue
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
inviteLinkResp, err := activeClient.CreateChatInviteLink(&client.CreateChatInviteLinkRequest{
|
// inviteLinkResp, err := activeClient.CreateChatInviteLink(&client.CreateChatInviteLinkRequest{
|
||||||
ChatId: channel.Id,
|
// ChatId: channel.Id,
|
||||||
Name: channelName,
|
// Name: channelName,
|
||||||
ExpirationDate: 0,
|
// ExpirationDate: 0,
|
||||||
MemberLimit: 0,
|
// MemberLimit: 0,
|
||||||
CreatesJoinRequest: false,
|
// CreatesJoinRequest: false,
|
||||||
})
|
// })
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
lastError = fmt.Errorf("failed to get invite link: %s", err.Error())
|
// lastError = fmt.Errorf("failed to get invite link: %s", err.Error())
|
||||||
continue
|
// continue
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
_, err = activeClient.LeaveChat(&client.LeaveChatRequest{
|
// _, err = activeClient.LeaveChat(&client.LeaveChatRequest{
|
||||||
ChatId: channel.Id,
|
// ChatId: channel.Id,
|
||||||
})
|
// })
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
lastError = fmt.Errorf("failed to leave the channel: %s", err.Error())
|
// lastError = fmt.Errorf("failed to leave the channel: %s", err.Error())
|
||||||
continue
|
// continue
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
inviteLink = inviteLinkResp.InviteLink
|
// inviteLink = inviteLinkResp.InviteLink
|
||||||
channelId = channel.Id
|
// channelId = channel.Id
|
||||||
return inviteLink, channelId, nil
|
// return inviteLink, channelId, nil
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
return "", 0, lastError
|
// return "", 0, lastError
|
||||||
}
|
// }
|
||||||
|
@ -2,15 +2,14 @@ package telegram
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
//"fmt"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/rs/xid"
|
// "github.com/rs/xid"
|
||||||
"path/filepath"
|
//"path/filepath"
|
||||||
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal"
|
// "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model"
|
||||||
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/model"
|
|
||||||
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/pj_errors"
|
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/pj_errors"
|
||||||
"penahub.gitlab.yandexcloud.net/backend/quiz/core/internal/clients/telegram"
|
// "penahub.gitlab.yandexcloud.net/backend/quiz/core/clients/telegram"
|
||||||
"penahub.gitlab.yandexcloud.net/backend/tdlib/client"
|
// "penahub.gitlab.yandexcloud.net/backend/tdlib/client"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -49,87 +48,88 @@ func (r *Telegram) GetPoolTgAccounts(ctx *fiber.Ctx) error {
|
|||||||
return ctx.Status(fiber.StatusOK).JSON(allAccounts)
|
return ctx.Status(fiber.StatusOK).JSON(allAccounts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Telegram) AddingTgAccount(ctx *fiber.Ctx) error {
|
func (s *Service) AddingTgAccount(ctx *fiber.Ctx) error {
|
||||||
var req telegram.AuthTgUserReq
|
// var req telegram.AuthTgUserReq
|
||||||
if err := ctx.BodyParser(&req); err != nil {
|
// if err := ctx.BodyParser(&req); err != nil {
|
||||||
return ctx.Status(fiber.StatusBadRequest).SendString("Invalid request data")
|
// return ctx.Status(fiber.StatusBadRequest).SendString("Invalid request data")
|
||||||
}
|
// }
|
||||||
if req.ApiID == 0 || req.ApiHash == "" || req.Password == "" || req.PhoneNumber == "" {
|
// if req.ApiID == 0 || req.ApiHash == "" || req.Password == "" || req.PhoneNumber == "" {
|
||||||
return ctx.Status(fiber.StatusBadRequest).SendString("empty required fields")
|
// return ctx.Status(fiber.StatusBadRequest).SendString("empty required fields")
|
||||||
}
|
// }
|
||||||
allAccounts, err := r.dal.TgRepo.GetAllTgAccounts(ctx.Context())
|
// allAccounts, err := s.dal.TgRepo.GetAllTgAccounts(ctx.Context())
|
||||||
if err != nil && !errors.Is(err, pj_errors.ErrNotFound) {
|
// if err != nil && !errors.Is(err, pj_errors.ErrNotFound) {
|
||||||
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
// return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
||||||
}
|
// }
|
||||||
if !errors.Is(err, pj_errors.ErrNotFound) {
|
// if !errors.Is(err, pj_errors.ErrNotFound) {
|
||||||
for _, account := range allAccounts {
|
// for _, account := range allAccounts {
|
||||||
if account.ApiID == req.ApiID && account.ApiHash == req.ApiHash && account.Status == model.ActiveTg {
|
// if account.ApiID == req.ApiID && account.ApiHash == req.ApiHash && account.Status == model.ActiveTg {
|
||||||
return ctx.Status(fiber.StatusConflict).SendString("this account already exist and active")
|
// return ctx.Status(fiber.StatusConflict).SendString("this account already exist and active")
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
authorizer := client.ClientAuthorizerr()
|
// authorizer := client.ClientAuthorizerr()
|
||||||
authorizer.TdlibParameters <- &client.SetTdlibParametersRequest{
|
// authorizer.TdlibParameters <- &client.SetTdlibParametersRequest{
|
||||||
UseTestDc: false,
|
// UseTestDc: false,
|
||||||
DatabaseDirectory: filepath.Join(".tdlib", "database"),
|
// DatabaseDirectory: filepath.Join(".tdlib", "database"),
|
||||||
FilesDirectory: filepath.Join(".tdlib", "files"),
|
// FilesDirectory: filepath.Join(".tdlib", "files"),
|
||||||
UseFileDatabase: true,
|
// UseFileDatabase: true,
|
||||||
UseChatInfoDatabase: true,
|
// UseChatInfoDatabase: true,
|
||||||
UseMessageDatabase: true,
|
// UseMessageDatabase: true,
|
||||||
UseSecretChats: true,
|
// UseSecretChats: true,
|
||||||
ApiId: req.ApiID,
|
// ApiId: req.ApiID,
|
||||||
ApiHash: req.ApiHash,
|
// ApiHash: req.ApiHash,
|
||||||
SystemLanguageCode: "en",
|
// SystemLanguageCode: "en",
|
||||||
DeviceModel: "Server",
|
// DeviceModel: "Server",
|
||||||
SystemVersion: "1.0.0",
|
// SystemVersion: "1.0.0",
|
||||||
ApplicationVersion: "1.0.0",
|
// ApplicationVersion: "1.0.0",
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
_, err = client.SetLogVerbosityLevel(&client.SetLogVerbosityLevelRequest{
|
// _, err = client.SetLogVerbosityLevel(&client.SetLogVerbosityLevelRequest{
|
||||||
NewVerbosityLevel: 1,
|
// NewVerbosityLevel: 1,
|
||||||
})
|
// })
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
// return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
var tdlibClient *client.Client
|
// var tdlibClient *client.Client
|
||||||
// завершается уже в другом контроллере
|
// // завершается уже в другом контроллере
|
||||||
var goErr error
|
// var goErr error
|
||||||
// todo ужно продумать завершение горутины если код вставлять не пошли
|
// // todo ужно продумать завершение горутины если код вставлять не пошли
|
||||||
go func() {
|
// go func() {
|
||||||
tdlibClient, goErr = client.NewClient(authorizer)
|
// tdlibClient, goErr = client.NewClient(authorizer)
|
||||||
if goErr != nil {
|
// if goErr != nil {
|
||||||
fmt.Println("new client failed", err)
|
// fmt.Println("new client failed", err)
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
r.telegramClient.SaveTgAccount(req.ApiID, req.ApiHash, tdlibClient)
|
// s.telegramClient.SaveTgAccount(req.ApiID, req.ApiHash, tdlibClient)
|
||||||
fmt.Println("i am down")
|
// fmt.Println("i am down")
|
||||||
}()
|
// }()
|
||||||
if goErr != nil {
|
// if goErr != nil {
|
||||||
return ctx.Status(fiber.StatusInternalServerError).SendString(goErr.Error())
|
// return ctx.Status(fiber.StatusInternalServerError).SendString(goErr.Error())
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
for {
|
// for {
|
||||||
state, ok := <-authorizer.State
|
// state, ok := <-authorizer.State
|
||||||
if !ok {
|
// if !ok {
|
||||||
return ctx.Status(fiber.StatusOK).SendString("state chan is close auth maybe ok")
|
// return ctx.Status(fiber.StatusOK).SendString("state chan is close auth maybe ok")
|
||||||
}
|
// }
|
||||||
fmt.Println("currnet state:", state)
|
// fmt.Println("currnet state:", state)
|
||||||
switch state.AuthorizationStateType() {
|
// switch state.AuthorizationStateType() {
|
||||||
case client.TypeAuthorizationStateWaitPhoneNumber:
|
// case client.TypeAuthorizationStateWaitPhoneNumber:
|
||||||
authorizer.PhoneNumber <- req.PhoneNumber
|
// authorizer.PhoneNumber <- req.PhoneNumber
|
||||||
case client.TypeAuthorizationStateWaitCode:
|
// case client.TypeAuthorizationStateWaitCode:
|
||||||
signature := xid.New()
|
// signature := xid.New()
|
||||||
r.telegramClient.AddedToMap(telegram.WaitingClient{
|
// s.telegramClient.AddedToMap(telegram.WaitingClient{
|
||||||
PreviousReq: req,
|
// PreviousReq: req,
|
||||||
Authorizer: authorizer,
|
// Authorizer: authorizer,
|
||||||
}, signature.String())
|
// }, signature.String())
|
||||||
return ctx.Status(fiber.StatusOK).JSON(fiber.Map{"signature": signature.String()})
|
// return ctx.Status(fiber.StatusOK).JSON(fiber.Map{"signature": signature.String()})
|
||||||
|
//
|
||||||
case client.TypeAuthorizationStateLoggingOut, client.TypeAuthorizationStateClosing, client.TypeAuthorizationStateClosed:
|
// case client.TypeAuthorizationStateLoggingOut, client.TypeAuthorizationStateClosing, client.TypeAuthorizationStateClosed:
|
||||||
return ctx.Status(fiber.StatusForbidden).SendString(fmt.Sprintf("auth failed, last state is %s", state))
|
// return ctx.Status(fiber.StatusForbidden).SendString(fmt.Sprintf("auth failed, last state is %s", state))
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Telegram) SettingTgCode(ctx *fiber.Ctx) error {
|
func (r *Telegram) SettingTgCode(ctx *fiber.Ctx) error {
|
||||||
@ -144,37 +144,38 @@ func (r *Telegram) SettingTgCode(ctx *fiber.Ctx) error {
|
|||||||
if req.Code == "" || req.Signature == "" {
|
if req.Code == "" || req.Signature == "" {
|
||||||
return ctx.Status(fiber.StatusBadRequest).SendString("empty required fields")
|
return ctx.Status(fiber.StatusBadRequest).SendString("empty required fields")
|
||||||
}
|
}
|
||||||
|
// data, ok := s.telegramClient.GetFromMap(req.Signature)
|
||||||
data, ok := r.telegramClient.GetFromMap(req.Signature)
|
// if !ok {
|
||||||
if !ok {
|
// return ctx.Status(fiber.StatusBadRequest).SendString("Invalid id, don't have data")
|
||||||
return ctx.Status(fiber.StatusBadRequest).SendString("Invalid id, don't have data")
|
// }
|
||||||
}
|
// data.Authorizer.Code <- req.Code
|
||||||
data.Authorizer.Code <- req.Code
|
// for {
|
||||||
for {
|
// state, ok := <-data.Authorizer.State
|
||||||
state, ok := <-data.Authorizer.State
|
// if !ok {
|
||||||
if !ok {
|
// return ctx.Status(fiber.StatusNoContent).SendString("state chan is close auth maybe ok")
|
||||||
return ctx.Status(fiber.StatusNoContent).SendString("state chan is close auth maybe ok")
|
// }
|
||||||
}
|
// fmt.Println("currnet state:", state)
|
||||||
fmt.Println("currnet state:", state)
|
// }
|
||||||
switch state.AuthorizationStateType() {
|
return nil
|
||||||
case client.TypeAuthorizationStateReady:
|
// switch state.AuthorizationStateType() {
|
||||||
id, err := r.dal.TgRepo.CreateTgAccount(ctx.Context(), model.TgAccount{
|
// case client.TypeAuthorizationStateReady:
|
||||||
ApiID: data.PreviousReq.ApiID,
|
// id, err := s.dal.TgRepo.CreateTgAccount(ctx.Context(), model.TgAccount{
|
||||||
ApiHash: data.PreviousReq.ApiHash,
|
// ApiID: data.PreviousReq.ApiID,
|
||||||
PhoneNumber: data.PreviousReq.PhoneNumber,
|
// ApiHash: data.PreviousReq.ApiHash,
|
||||||
Status: model.ActiveTg,
|
// PhoneNumber: data.PreviousReq.PhoneNumber,
|
||||||
Password: data.PreviousReq.Password,
|
// Status: model.ActiveTg,
|
||||||
})
|
// Password: data.PreviousReq.Password,
|
||||||
if err != nil {
|
// })
|
||||||
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
// if err != nil {
|
||||||
}
|
// return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
||||||
return ctx.Status(fiber.StatusOK).JSON(fiber.Map{"id": id})
|
// }
|
||||||
case client.TypeAuthorizationStateWaitPassword:
|
// return ctx.Status(fiber.StatusOK).JSON(fiber.Map{"id": id})
|
||||||
data.Authorizer.Password <- data.PreviousReq.Password
|
// case client.TypeAuthorizationStateWaitPassword:
|
||||||
case client.TypeAuthorizationStateLoggingOut, client.TypeAuthorizationStateClosing, client.TypeAuthorizationStateClosed:
|
// data.Authorizer.Password <- data.PreviousReq.Password
|
||||||
return ctx.Status(fiber.StatusForbidden).SendString(fmt.Sprintf("auth failed, last state is %s", state))
|
// case client.TypeAuthorizationStateLoggingOut, client.TypeAuthorizationStateClosing, client.TypeAuthorizationStateClosed:
|
||||||
}
|
// return ctx.Status(fiber.StatusForbidden).SendString(fmt.Sprintf("auth failed, last state is %s", state))
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Telegram) DeleteTgAccountByID(ctx *fiber.Ctx) error {
|
func (r *Telegram) DeleteTgAccountByID(ctx *fiber.Ctx) error {
|
||||||
|
@ -42,6 +42,8 @@ func WriteDataToExcel(buffer io.Writer, questions []model.Question, answers []mo
|
|||||||
})
|
})
|
||||||
|
|
||||||
headers, mapQueRes := prepareHeaders(questions)
|
headers, mapQueRes := prepareHeaders(questions)
|
||||||
|
headers = append([]string{"Дата и время"}, headers...)
|
||||||
|
|
||||||
for col, header := range headers {
|
for col, header := range headers {
|
||||||
cell := ToAlphaString(col+1) + "1"
|
cell := ToAlphaString(col+1) + "1"
|
||||||
if err := file.SetCellValue(sheet, cell, header); err != nil {
|
if err := file.SetCellValue(sheet, cell, header); err != nil {
|
||||||
@ -107,10 +109,15 @@ func processSession(file *excelize.File, sheet, session, s3Prefix string, respon
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if err := file.SetCellValue(sheet, "A"+strconv.Itoa(row), results[session].Content); err != nil {
|
if err := file.SetCellValue(sheet, "A"+strconv.Itoa(row), results[session].CreatedAt.Format("2006-01-02 15:04:05")); err != nil {
|
||||||
fmt.Println(err.Error())
|
fmt.Println(err.Error())
|
||||||
}
|
}
|
||||||
count := 2
|
|
||||||
|
if err := file.SetCellValue(sheet, "B"+strconv.Itoa(row), results[session].Content); err != nil {
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
count := 3
|
||||||
for _, q := range questions {
|
for _, q := range questions {
|
||||||
if !q.Deleted && q.Type != model.TypeResult {
|
if !q.Deleted && q.Type != model.TypeResult {
|
||||||
cell := ToAlphaString(count) + strconv.Itoa(row)
|
cell := ToAlphaString(count) + strconv.Itoa(row)
|
||||||
|
101
service/service.go
Normal file
101
service/service.go
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/go-redis/redis/v8"
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal"
|
||||||
|
"penahub.gitlab.yandexcloud.net/backend/quiz/core/brokers"
|
||||||
|
"penahub.gitlab.yandexcloud.net/backend/quiz/core/clients/auth"
|
||||||
|
// "penahub.gitlab.yandexcloud.net/backend/quiz/core/clients/telegram"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Service is an entity for http requests handling
|
||||||
|
type Service struct {
|
||||||
|
dal *dal.DAL
|
||||||
|
authClient *auth.AuthClient
|
||||||
|
producer *brokers.Producer
|
||||||
|
serviceName string
|
||||||
|
chDAL *dal.ClickHouseDAL
|
||||||
|
// telegramClient *telegram.TelegramClient
|
||||||
|
redisClient *redis.Client
|
||||||
|
s3Prefix string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Deps struct {
|
||||||
|
Dal *dal.DAL
|
||||||
|
AuthClient *auth.AuthClient
|
||||||
|
Producer *brokers.Producer
|
||||||
|
ServiceName string
|
||||||
|
ChDAL *dal.ClickHouseDAL
|
||||||
|
// TelegramClient *telegram.TelegramClient
|
||||||
|
RedisClient *redis.Client
|
||||||
|
S3Prefix string
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(deps Deps) *Service {
|
||||||
|
return &Service{
|
||||||
|
dal: deps.Dal,
|
||||||
|
authClient: deps.AuthClient,
|
||||||
|
producer: deps.Producer,
|
||||||
|
serviceName: deps.ServiceName,
|
||||||
|
chDAL: deps.ChDAL,
|
||||||
|
// telegramClient: deps.TelegramClient,
|
||||||
|
redisClient: deps.RedisClient,
|
||||||
|
s3Prefix: deps.S3Prefix,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register is a function for add handlers of service to external multiplexer
|
||||||
|
func (s *Service) Register(app *fiber.App) {
|
||||||
|
// quiz manipulating handlers
|
||||||
|
app.Post("/quiz/create", s.CreateQuiz)
|
||||||
|
app.Post("/quiz/getList", s.GetQuizList)
|
||||||
|
app.Patch("/quiz/edit", s.UpdateQuiz)
|
||||||
|
app.Post("/quiz/copy", s.CopyQuiz)
|
||||||
|
app.Post("/quiz/history", s.GetQuizHistory)
|
||||||
|
app.Delete("/quiz/delete", s.DeleteQuiz)
|
||||||
|
app.Patch("/quiz/archive", s.ArchiveQuiz)
|
||||||
|
app.Post("/quiz/move", s.QuizMove)
|
||||||
|
app.Post("/quiz/template", s.TemplateCopy)
|
||||||
|
|
||||||
|
// question manipulating handlers
|
||||||
|
app.Post("/question/create", s.CreateQuestion)
|
||||||
|
app.Post("/question/getList", s.GetQuestionList)
|
||||||
|
app.Patch("/question/edit", s.UpdateQuestion)
|
||||||
|
app.Post("/question/copy", s.CopyQuestion)
|
||||||
|
app.Post("/question/history", s.GetQuestionHistory)
|
||||||
|
app.Delete("/question/delete", s.DeleteQuestion)
|
||||||
|
|
||||||
|
// account handlers
|
||||||
|
app.Get("/account/get", s.getCurrentAccount)
|
||||||
|
app.Post("/account/create", s.createAccount)
|
||||||
|
app.Delete("/account/delete", s.deleteAccount)
|
||||||
|
app.Get("/accounts", s.getAccounts)
|
||||||
|
app.Get("/privilege/:userId", s.getPrivilegeByUserID)
|
||||||
|
app.Delete("/account/:userId", s.deleteAccountByUserID)
|
||||||
|
app.Post("/account/manualdone", s.ManualDone)
|
||||||
|
app.Post("/account/leadtarget", s.PostLeadTarget)
|
||||||
|
app.Delete("/account/leadtarget/:id", s.DeleteLeadTarget)
|
||||||
|
app.Get("/account/leadtarget/:quizID", s.GetLeadTarget)
|
||||||
|
app.Put("/account/leadtarget", s.UpdateLeadTarget)
|
||||||
|
|
||||||
|
// result handlers
|
||||||
|
app.Post("/results/getResults/:quizId", s.GetResultsByQuizID)
|
||||||
|
app.Delete("/results/delete/:resultId", s.DelResultByID)
|
||||||
|
app.Patch("/result/seen", s.SetStatus)
|
||||||
|
app.Post("/results/:quizID/export", s.ExportResultsToCSV)
|
||||||
|
app.Get("/result/:resultID", s.GetResultAnswers)
|
||||||
|
|
||||||
|
// statistics handlers
|
||||||
|
app.Post("/statistic/:quizID/devices", s.GetDeviceStatistics)
|
||||||
|
app.Post("/statistic/:quizID/general", s.GetGeneralStatistics)
|
||||||
|
app.Post("/statistic/:quizID/questions", s.GetQuestionsStatistics)
|
||||||
|
app.Post("/statistic", s.AllServiceStatistics)
|
||||||
|
app.Get("/statistics/:quizID/pipelines", s.GetPipelinesStatistics)
|
||||||
|
|
||||||
|
//telegram handlers
|
||||||
|
app.Get("/telegram/pool", s.GetPoolTgAccounts)
|
||||||
|
app.Post("/telegram/create", s.AddingTgAccount)
|
||||||
|
app.Delete("/telegram/:id", s.DeleteTgAccountByID)
|
||||||
|
app.Post("/telegram/setCode", s.SettingTgCode)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user