diff --git a/.gitea/workflows/deployProd.yml b/.gitea/workflows/deployProd.yml new file mode 100644 index 0000000..d2d57e8 --- /dev/null +++ b/.gitea/workflows/deployProd.yml @@ -0,0 +1,26 @@ +name: Deploy +run-name: ${{ gitea.actor }} build image and push to container registry + +on: + push: + branches: + - 'main' + +jobs: + CreateImage: + runs-on: [squizstaging] + uses: https://gitea.pena/PenaDevops/actions.git/.gitea/workflows/build-image.yml@v1.1.6-p + with: + runner: hubstaging + secrets: + REGISTRY_USER: ${{ secrets.REGISTRY_USER }} + REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }} + DeployService: + runs-on: [squizprod] + needs: CreateImage + uses: https://gitea.pena/PenaDevops/actions.git/.gitea/workflows/deploy.yml@v1.1.4-p7 + with: + runner: hubprod + actionid: ${{ gitea.run_id }} + + diff --git a/.gitea/workflows/deployStaging.yml b/.gitea/workflows/deployStaging.yml new file mode 100644 index 0000000..d497c68 --- /dev/null +++ b/.gitea/workflows/deployStaging.yml @@ -0,0 +1,26 @@ +name: Deploy +run-name: ${{ gitea.actor }} build image and push to container registry + +on: + push: + branches: + - 'staging' + +jobs: + CreateImage: + runs-on: [squizstaging] + uses: http://gitea.pena/PenaDevops/actions.git/.gitea/workflows/build-image.yml@v1.1.6-p + with: + runner: squizstaging + secrets: + REGISTRY_USER: ${{ secrets.REGISTRY_USER }} + REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }} + DeployService: + runs-on: [squizstaging] + needs: CreateImage + uses: http://gitea.pena/PenaDevops/actions.git/.gitea/workflows/deploy.yml@v1.1.4-p7 + with: + runner: squizstaging + actionid: ${{ gitea.run_id }} + + diff --git a/Dockerfile b/Dockerfile index 28fc8de..9070302 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,15 +1,11 @@ FROM gitea.pena/penadevops/container-images/golang:main as build WORKDIR /app COPY . . -RUN apk add git +RUN go env -w GONOSUMDB=gitea.pena/PenaSide/trashlog,gitea.pena/PenaSide/hlog,gitea.pena/PenaSide/common,gitea.pena/SQuiz/common +RUN export GOPROXY=direct RUN go mod download RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o ans ./main.go -FROM gitea.pena/penadevops/container-images/alpine:main +FROM gitea.pena/penadevops/container-images/alpine:main as prod COPY --from=build /app/ans . -EXPOSE 1490 -ENV IS_PROD_LOG=false -ENV IS_PROD=false -ENV PORT=1490 -ENV PG_CRED="host=postgres port=5432 user=squiz password=Redalert2 dbname=squiz sslmode=disable" CMD ["/ans"] diff --git a/Taskfile.yml b/Taskfile.yml new file mode 100644 index 0000000..72c6882 --- /dev/null +++ b/Taskfile.yml @@ -0,0 +1,7 @@ + +version: "3" + +tasks: + setenvs: + cmds: + - export GOPRIVATE=gitea.pena/SQuiz/common diff --git a/app/app.go b/app/app.go index 605c5be..849efbc 100644 --- a/app/app.go +++ b/app/app.go @@ -4,15 +4,10 @@ import ( "context" "errors" "fmt" - "github.com/go-redis/redis/v8" - "github.com/gofiber/fiber/v2" - "github.com/minio/minio-go/v7" - "github.com/minio/minio-go/v7/pkg/credentials" - "github.com/skeris/appInit" - "gitea.pena/PenaSide/hlog" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" "gitea.pena/PenaSide/common/log_mw" + "gitea.pena/PenaSide/hlog" + "gitea.pena/PenaSide/trashlog/wrappers/zaptrashlog" + "gitea.pena/SQuiz/answerer/clients" dalBS "gitea.pena/SQuiz/answerer/dal" "gitea.pena/SQuiz/answerer/models" "gitea.pena/SQuiz/answerer/savewc" @@ -22,7 +17,13 @@ import ( "gitea.pena/SQuiz/common/middleware" "gitea.pena/SQuiz/common/model" "gitea.pena/SQuiz/common/utils" - "gitea.pena/PenaSide/trashlog/wrappers/zaptrashlog" + "github.com/go-redis/redis/v8" + "github.com/gofiber/fiber/v2" + "github.com/minio/minio-go/v7" + "github.com/minio/minio-go/v7/pkg/credentials" + "github.com/skeris/appInit" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" "time" ) @@ -101,17 +102,17 @@ func New(ctx context.Context, opts interface{}, ver appInit.Version) (appInit.Co 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) - } - + if err != nil { + panic(err) + } + loggerForHlog := zapLogger.WithOptions(zap.WrapCore(func(core zapcore.Core) zapcore.Core { - return zapcore.NewTee(core, clickHouseLogger) - })) + return zapcore.NewTee(core, clickHouseLogger) + })) loggerHlog := hlog.New(loggerForHlog).Module(options.ModuleLogger) + loggerHlog.With(models.AllFields{}) loggerHlog.Emit(InfoSvcStarted{}) @@ -153,6 +154,7 @@ func New(ctx context.Context, opts interface{}, ver appInit.Version) (appInit.Co WorkerRespondentCh: workerRespondentCh, Encrypt: encrypt, RedirectURl: options.RedirectURL, + AiClient: clients.NewAiClient("http://35.206.94.7:80/api/engine/generate_question_by_answer/"), }) saveRespWcData := savewc.DepsForResp{ @@ -173,6 +175,16 @@ func New(ctx context.Context, opts interface{}, ver appInit.Version) (appInit.Co go saveClientWorker.Start(ctx) app := fiber.New(fiber.Config{BodyLimit: 70 * 1024 * 1024}) + + app.Use(func(c *fiber.Ctx) error { + defer func() { + if err := recover(); err != nil { + c.Status(fiber.StatusInternalServerError).SendString("internal server error") + } + }() + return c.Next() + }) + app.Use(middleware.AnswererChain()) app.Use(log_mw.ContextLogger(loggerHlog)) app.Get("/liveness", healthchecks.Liveness) diff --git a/clients/aiClient.go b/clients/aiClient.go new file mode 100644 index 0000000..4acf52b --- /dev/null +++ b/clients/aiClient.go @@ -0,0 +1,69 @@ +package clients + +import ( + "encoding/json" + "errors" + "fmt" + "github.com/gofiber/fiber/v2" +) + +type AIClient struct { + baseURL string + httpClient *fiber.Client +} + +type SendAnswerRequest struct { + Tipe string `json:"type"` + Message string `json:"message"` + Final bool `json:"final"` + Session string `json:"session"` +} + +func NewAiClient(baseURL string) *AIClient { + return &AIClient{ + baseURL: baseURL, + httpClient: fiber.AcquireClient(), + } +} + +func (client *AIClient) SendAnswerer(final bool, tipe, message, session string) (string, error) { + //req := SendAnswerRequest{ + // Tipe: tipe, + // Message: message, + // Final: final, + // Session: session, + //} + + clownRequest := struct { + Text string `json:"text"` + }{ + Text: message, + } + + body, err := json.Marshal(clownRequest) + if err != nil { + return "", err + } + + agent := client.httpClient.Post(client.baseURL) + agent.Set("Content-Type", "application/json").Body(body) + + statusCode, respBody, errs := agent.Bytes() + if len(errs) > 0 { + return "", errors.Join(errs...) + } + + if statusCode != fiber.StatusCreated { + return "", fmt.Errorf("invalid response status code: %d", statusCode) + } + + resp := struct { + Text string `json:"text"` + }{} + + if err := json.Unmarshal(respBody, &resp); err != nil { + return "", err + } + + return resp.Text, nil +} diff --git a/clients/aiClient_test.go b/clients/aiClient_test.go new file mode 100644 index 0000000..34975bb --- /dev/null +++ b/clients/aiClient_test.go @@ -0,0 +1,17 @@ +package clients + +import ( + "fmt" + "testing" +) + +func Test_AiClient(t *testing.T) { + aiClient := NewAiClient("http://35.206.94.7:80/api/engine/generate_question_by_answer/") + for i := 0; i < 10; i++ { + question, err := aiClient.SendAnswerer(false, "type", "Дартвейдер был хорошим.", "1234") + if err != nil { + t.Error(err) + } + fmt.Println(question) + } +} diff --git a/deployments/main/docker-compose.yaml b/deployments/main/docker-compose.yaml index 39e17b9..8d5d5fd 100644 --- a/deployments/main/docker-compose.yaml +++ b/deployments/main/docker-compose.yaml @@ -1,20 +1,23 @@ services: - answerer: - hostname: squiz-answerer - container_name: squiz-answerer - image: $CI_REGISTRY_IMAGE/main-answerer:$CI_COMMIT_REF_SLUG.$CI_PIPELINE_ID + answererv1.0.0: + image: gitea.pena/squiz/answerer/main:$GITHUB_RUN_NUMBER tty: true environment: IS_PROD_LOG: 'false' IS_PROD: 'false' - PUBLIC_ACCESS_SECRET_KEY: $JWT_PUBLIC_KEY + PUBLIC_ACCESS_SECRET_KEY: "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCLW1tlHyKC9AG0hGpmkksET2DE\nr7ojSPemxFWAgFgcPJWQ7x3uNbsdJ3bIZFoA/FClaWKMCZmjnH9tv0bKZtY/CDhM\nZEyHpMruRSn6IKrxjtQZWy4uv/w6MzUeyBYG0OvNCiYpdvz5SkAGAUHD5ZNFqn2w\nKKFD0I2Dr59BFVSGJwIDAQAB\n-----END PUBLIC KEY-----" PORT: 1490 - MINIO_EP: 'storage.yandexcloud.net' - MINIO_AK: 'YCAJEOcqqTHpiwL4qFwLfHPNA' - MINIO_SK: 'YCNIAIat0XqdDzycWsYKX3OU7mPor6S0WmMoG4Ry' - PG_CRED: 'host=10.8.0.9 port=5433 user=squiz password=Redalert2 dbname=squiz sslmode=disable' - REDIS_HOST: '10.8.0.9:6379' + MINIO_EP: s3.timeweb.cloud + MINIO_AK: 5CV77KVDUU9H0II9R24M + MINIO_SK: '0W0m8DyvdAKRJnsAy6mB5zndQ7RouJBLhqhtThcu' + PG_CRED: 'host=10.8.0.12 port=5433 user=squiz password=Redalert2 dbname=squiz sslmode=disable' + REDIS_HOST: '10.8.0.12:6379' REDIS_PASSWORD: 'Redalert2' REDIS_DB: 2 + PUBLIC_KEY: "-----BEGIN PUBLIC KEY-----\nMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAn/Q3CKvaxK4YR3N3Iy8O\nIOs218oDQIwoHpmRh3a9V+vTEqT+rY8/Dkf5cnbTMuEBFP1NYtS+pcSFF7nLlZdm\nVb6rhtjLCV0awogeWxJsXCHBOHF7Fv4iqDa85qMwl7XiVXxKo/9kH9TkPsgFsuYt\nvL4Xc1u6ogoYeVHP7ULDMxgmdLd2N9VIVphxsiGDq304NbgWFVr47/J3x3DU0bw+\nF5QdI7ScU/m4T3S0WlhFaG0hblVbH8x+8U81F9OIyJCX9tGZYb6eR3v1pnWP191L\nkpJPSlj9cPPJhl3d6bCyYzGv6k8KQClSs8lsSklPrcXl0ut3raC+oEFp2JkHQL7R\nUlwPr2ZOt9DTTs7l70gvr8FswO4/N6+t+6spce2s3lwN41BWGWHYcc9PuOHqUQTw\nJ3IQQU6NmAyZOjDiZJw7uoNG2rtCqWQRykTULZvtfxh3lMXI/qKM1em+Qo3AZnKC\nY01xhCr4ahPs9Rb4eReigTJSzq+IRSJa1+xPaR4dNm6tAgMBAAE=\n-----END PUBLIC KEY-----" + PRIVATE_KEY: "-----BEGIN RSA PRIVATE KEY-----\n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\n-----END RSA PRIVATE KEY-----" + TRASH_LOG_HOST: "10.8.0.200:7113" + MODULE_LOGGER: "quiz-answerer-main" + REDIRECT_URL: "https://quiz.pena.digital" ports: - - 10.8.0.9:1490:1490 + - 10.8.0.12:1491:1490 diff --git a/go.mod b/go.mod index 2a3ab61..6fd71ae 100644 --- a/go.mod +++ b/go.mod @@ -2,12 +2,13 @@ module gitea.pena/SQuiz/answerer go 1.23.2 +toolchain go1.23.4 + require ( gitea.pena/PenaSide/common v0.0.0-20250103085335-91ea31fee517 gitea.pena/PenaSide/hlog v0.0.0-20241125221102-a54c29c002a9 - gitea.pena/PenaSide/linters-golang v0.0.0-20241207122018-933207374735 - gitea.pena/PenaSide/trashlog v0.0.0-20241210185614-9ec567aa311f - gitea.pena/SQuiz/common v0.0.0-20250205160239-4ed00d74894b + gitea.pena/PenaSide/trashlog v0.0.0-20250224122049-ddb4d72e9d07 + gitea.pena/SQuiz/common v0.0.0-20250514124515-870e52266ca5 github.com/go-redis/redis/v8 v8.11.5 github.com/gofiber/fiber/v2 v2.52.5 github.com/minio/minio-go/v7 v7.0.81 @@ -17,9 +18,10 @@ require ( ) require ( + gitea.pena/PenaSide/linters-golang v0.0.0-20241207122018-933207374735 // indirect github.com/ClickHouse/clickhouse-go v1.5.4 // indirect github.com/andybalholm/brotli v1.1.0 // indirect - github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dustin/go-humanize v1.0.1 // indirect @@ -29,22 +31,22 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/google/uuid v1.6.0 // indirect github.com/klauspost/compress v1.17.11 // indirect - github.com/klauspost/cpuid/v2 v2.2.8 // indirect + github.com/klauspost/cpuid/v2 v2.2.9 // indirect github.com/lib/pq v1.10.9 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect github.com/minio/md5-simd v1.1.2 // indirect - github.com/rivo/uniseg v0.4.7 // indirect + github.com/rivo/uniseg v0.2.0 // indirect github.com/tealeg/xlsx v1.0.5 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasthttp v1.54.0 // indirect + github.com/valyala/fasthttp v1.51.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect go.etcd.io/bbolt v1.3.10 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/crypto v0.28.0 // indirect golang.org/x/net v0.30.0 // indirect - golang.org/x/sys v0.26.0 // indirect + golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.19.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240610135401-a8a62080eff3 // indirect google.golang.org/grpc v1.64.0 // indirect diff --git a/go.sum b/go.sum index 6d90649..a2f39ce 100644 --- a/go.sum +++ b/go.sum @@ -4,10 +4,10 @@ gitea.pena/PenaSide/hlog v0.0.0-20241125221102-a54c29c002a9 h1:tBkXWNIt8icmkMMnq gitea.pena/PenaSide/hlog v0.0.0-20241125221102-a54c29c002a9/go.mod h1:sanhSL8aEsfcq21P+eItYiAnKAre+B67nGJmDfk2cf0= gitea.pena/PenaSide/linters-golang v0.0.0-20241207122018-933207374735 h1:jDVeUhGBTXBibmW5dmtJg2m2+z5z2Rf6J4G0LpjVoJ0= gitea.pena/PenaSide/linters-golang v0.0.0-20241207122018-933207374735/go.mod h1:gdd+vOT6up9STkEbxa2qESLIMZFjCmRbkcheFQCVgZU= -gitea.pena/PenaSide/trashlog v0.0.0-20241210185614-9ec567aa311f h1:vwuUtO03Qowaf2XtSxDeI817+MsvPp/M4jAC2ecYr1M= -gitea.pena/PenaSide/trashlog v0.0.0-20241210185614-9ec567aa311f/go.mod h1:GRfWJerTUlgy82CiYAxE4tVYSVV54zEJJQy17Fx46E4= -gitea.pena/SQuiz/common v0.0.0-20250205160239-4ed00d74894b h1:N3DdDWQyTXC0B5mI7OpjxHQuHtt6EJCK+vqRrLqcb1w= -gitea.pena/SQuiz/common v0.0.0-20250205160239-4ed00d74894b/go.mod h1:zCrUwDh0APpztKk6NUqTZv+zhjVbWpGBJiJ5z9dAH0U= +gitea.pena/PenaSide/trashlog v0.0.0-20250224122049-ddb4d72e9d07 h1:bUIUgzXQt16aBqSccI//BaODpRCTIaqlddSepM98QSc= +gitea.pena/PenaSide/trashlog v0.0.0-20250224122049-ddb4d72e9d07/go.mod h1:GRfWJerTUlgy82CiYAxE4tVYSVV54zEJJQy17Fx46E4= +gitea.pena/SQuiz/common v0.0.0-20250514124515-870e52266ca5 h1:C+iCsGMSUJonOTNNk8wWYOfzZ0Jjw+2IQ5FaEGwRVT0= +gitea.pena/SQuiz/common v0.0.0-20250514124515-870e52266ca5/go.mod h1:zCrUwDh0APpztKk6NUqTZv+zhjVbWpGBJiJ5z9dAH0U= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/ClickHouse/clickhouse-go v1.5.4 h1:cKjXeYLNWVJIx2J1K6H2CqyRmfwVJVY1OV1coaaFcI0= github.com/ClickHouse/clickhouse-go v1.5.4/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI= @@ -17,8 +17,8 @@ github.com/bkaradzic/go-lz4 v1.0.0 h1:RXc4wYsyz985CkXXeX04y4VnZFGG8Rd43pRaHsOXAK github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4= github.com/caarlos0/env/v8 v8.0.0 h1:POhxHhSpuxrLMIdvTGARuZqR4Jjm8AYmoi/JKlcScs0= github.com/caarlos0/env/v8 v8.0.0/go.mod h1:7K4wMY9bH0esiXSSHlfHLX5xKGQMnkH5Fk4TDSSSzfo= -github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= -github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 h1:F1EaeKL/ta07PY/k9Os/UFtwERei2/XzGemhpGnBKNg= github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -55,8 +55,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= -github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY= +github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -71,8 +71,8 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= -github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= @@ -93,9 +93,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= -github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= @@ -112,8 +111,8 @@ github.com/themakers/bdd v0.0.0-20210316111417-6b1dfe326f33 h1:N9f/Q+2Ssa+yDcbfa github.com/themakers/bdd v0.0.0-20210316111417-6b1dfe326f33/go.mod h1:rpcH99JknBh8seZmlOlUg51gasZH6QH34oXNsIwYT6E= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.54.0 h1:cCL+ZZR3z3HPLMVfEYVUMtJqVaui0+gu7Lx63unHwS0= -github.com/valyala/fasthttp v1.54.0/go.mod h1:6dt4/8olwq9QARP/TDuPmWyWcl4byhpvTJ4AAtcz+QM= +github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA= +github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g= github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= go.etcd.io/bbolt v1.3.10 h1:+BqfJTcCzTItrop8mq/lbzL8wSGtj94UO/3U31shqG0= @@ -145,10 +144,9 @@ golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 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-20220811171246-fbc7d0a398ab/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.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.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.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= diff --git a/main.go b/main.go index 3c3b5e5..051a758 100644 --- a/main.go +++ b/main.go @@ -1,9 +1,8 @@ package main import ( - "github.com/skeris/appInit" "gitea.pena/SQuiz/answerer/app" - _ "gitea.pena/PenaSide/linters-golang/pkg/dummy" + "github.com/skeris/appInit" ) func main() { diff --git a/savewc/for_client.go b/savewc/for_client.go index b8ead40..c886dbf 100644 --- a/savewc/for_client.go +++ b/savewc/for_client.go @@ -4,9 +4,9 @@ import ( "context" "encoding/json" "fmt" - "github.com/go-redis/redis/v8" - "gitea.pena/PenaSide/hlog" + "gitea.pena/PenaSide/hlog" "gitea.pena/SQuiz/common/model" + "github.com/go-redis/redis/v8" "time" ) diff --git a/savewc/for_respondent.go b/savewc/for_respondent.go index 47e13e1..eb0fd64 100644 --- a/savewc/for_respondent.go +++ b/savewc/for_respondent.go @@ -4,9 +4,9 @@ import ( "context" "encoding/json" "fmt" - "github.com/go-redis/redis/v8" + "gitea.pena/PenaSide/hlog" "gitea.pena/SQuiz/common/model" - "gitea.pena/PenaSide/hlog" + "github.com/go-redis/redis/v8" "time" ) diff --git a/service/service.go b/service/service.go index c2c98f0..746fa66 100644 --- a/service/service.go +++ b/service/service.go @@ -3,15 +3,16 @@ package service import ( "encoding/json" "fmt" - "github.com/gofiber/fiber/v2" - "net/url" "gitea.pena/PenaSide/common/log_mw" + "gitea.pena/SQuiz/answerer/clients" "gitea.pena/SQuiz/answerer/dal" "gitea.pena/SQuiz/answerer/models" quizdal "gitea.pena/SQuiz/common/dal" "gitea.pena/SQuiz/common/middleware" "gitea.pena/SQuiz/common/model" "gitea.pena/SQuiz/common/utils" + "github.com/gofiber/fiber/v2" + "net/url" "strconv" "strings" "sync" @@ -34,6 +35,7 @@ type Service struct { workerSendClientCh chan<- model.Answer encrypt *utils.Encrypt redirectURl string + aiClient *clients.AIClient } type ServiceDeps struct { @@ -43,6 +45,7 @@ type ServiceDeps struct { WorkerSendClientCh chan<- model.Answer Encrypt *utils.Encrypt RedirectURl string + AiClient *clients.AIClient } func New(deps ServiceDeps) *Service { @@ -55,6 +58,7 @@ func New(deps ServiceDeps) *Service { workerSendClientCh: deps.WorkerSendClientCh, encrypt: deps.Encrypt, redirectURl: deps.RedirectURl, + aiClient: deps.AiClient, } } @@ -71,11 +75,12 @@ type GetQuizDataReq struct { Limit uint64 `json:"limit"` Page uint64 `json:"page"` NeedConfig bool `json:"need_config"` // true if you need not only question page + Auditory int64 `json:"auditory"` } // GetQuizDataResp response with prepared data for user type GetQuizDataResp struct { - Settings ShavedQuiz `json:"settings"` + Settings *ShavedQuiz `json:"settings,omitempty"` Items []ShavedQuestion `json:"items"` Count uint64 `json:"cnt"` ShowBadge bool `json:"show_badge"` @@ -91,6 +96,7 @@ type ShavedQuiz struct { DueTo uint64 `json:"due"` TimeOfPassing uint64 `json:"delay"` Pausable bool `json:"pausable"` + Status string `json:"status"` } // ShavedQuestion shortened struct for delivery data to customer @@ -106,6 +112,11 @@ type ShavedQuestion struct { // GetQuizData handler for obtaining data for quiz front rendering func (s *Service) GetQuizData(c *fiber.Ctx) error { + cs, ok := c.Context().Value(middleware.ContextKey(middleware.SessionKey)).(string) + if !ok { + return c.Status(fiber.StatusUnauthorized).SendString("no session in cookie") + } + hlogger := log_mw.ExtractLogger(c) var req GetQuizDataReq if err := c.BodyParser(&req); err != nil { @@ -126,15 +137,16 @@ func (s *Service) GetQuizData(c *fiber.Ctx) error { } if req.Limit == 0 && req.NeedConfig { + quizDto := dao2dtoQuiz(quiz) return c.Status(fiber.StatusOK).JSON(GetQuizDataResp{ - Settings: dao2dtoQuiz(quiz), + Settings: &quizDto, }) } if quiz.UniqueAnswers { //todo implement after creating store answers } - if quiz.Status != model.StatusStart { + if quiz.Status != model.StatusStart && quiz.Status != model.StatusAI { return c.Status(fiber.StatusLocked).SendString("quiz is inactive") } @@ -162,14 +174,24 @@ func (s *Service) GetQuizData(c *fiber.Ctx) error { } } - questions, cnt, err := s.dal.QuestionRepo.GetQuestionList( - c.Context(), - req.Limit, - req.Page*req.Limit, - 0, 0, quiz.Id, false, false, "", "", - ) - if err != nil { - return c.Status(fiber.StatusInternalServerError).SendString(err.Error()) + var questions []model.Question + var cnt uint64 + + if quiz.Status == model.StatusAI { + questions, cnt, err = s.dal.QuestionRepo.GetQuestionsAI(c.Context(), int64(quiz.Id), cs, int32(req.Limit), int32(req.Page*req.Limit), req.Auditory) + if err != nil { + return c.Status(fiber.StatusInternalServerError).SendString(err.Error()) + } + } else { + questions, cnt, err = s.dal.QuestionRepo.GetQuestionList( + c.Context(), + req.Limit, + req.Page*req.Limit, + 0, 0, quiz.Id, false, false, "", "", req.Auditory, + ) + if err != nil { + return c.Status(fiber.StatusInternalServerError).SendString(err.Error()) + } } result := GetQuizDataResp{ @@ -179,7 +201,8 @@ func (s *Service) GetQuizData(c *fiber.Ctx) error { } if req.NeedConfig { - result.Settings = dao2dtoQuiz(quiz) + quizDto := dao2dtoQuiz(quiz) + result.Settings = &quizDto } for _, q := range questions { @@ -218,38 +241,40 @@ func (s *Service) GetQuizData(c *fiber.Ctx) error { if cfp := c.Cookies(fingerprintCookie); cfp != "" { fp = cfp } - cs, ok := c.Context().Value(middleware.ContextKey(middleware.SessionKey)).(string) - if !ok { - return c.Status(fiber.StatusUnauthorized).SendString("no session in cookie") - } - answers, errs := s.dal.AnswerRepo.CreateAnswers(c.Context(), []model.Answer{{ - Content: "start", - QuestionId: questions[0].Id, - QuizId: quiz.Id, - Start: true, - DeviceType: deviceType, - Device: device, - Browser: browser, - IP: ip, - OS: os, - Utm: utmData, - }}, cs, fp, quiz.Id) - if len(errs) != 0 { - return c.Status(fiber.StatusInternalServerError).SendString(errs[0].Error()) - } + if req.NeedConfig { + if len(questions) == 0 { + return c.Status(fiber.StatusNotFound).SendString("question not found") + } - hlogger.Emit(models.InfoQuizOpen{ - KeyOS: os, - KeyDevice: device, - KeyDeviceType: deviceType, - KeyBrowser: browser, - CtxQuiz: req.QuizId, - CtxQuizID: int64(quiz.Id), - CtxReferrer: referrer, - CtxIDInt: int64(answers[0].Id), - CtxSession: cs, - }) + answers, errs := s.dal.AnswerRepo.CreateAnswers(c.Context(), []model.Answer{{ + Content: "start", + QuestionId: questions[0].Id, + QuizId: quiz.Id, + Start: true, + DeviceType: deviceType, + Device: device, + Browser: browser, + IP: ip, + OS: os, + Utm: utmData, + }}, cs, fp, quiz.Id) + if len(errs) != 0 { + return c.Status(fiber.StatusInternalServerError).SendString(errs[0].Error()) + } + + hlogger.Emit(models.InfoQuizOpen{ + KeyOS: os, + KeyDevice: device, + KeyDeviceType: deviceType, + KeyBrowser: browser, + CtxQuiz: req.QuizId, + CtxQuizID: int64(quiz.Id), + CtxReferrer: referrer, + CtxIDInt: int64(answers[0].Id), + CtxSession: cs, + }) + } fmt.Println("SETTIIIIII", cnt <= req.Limit, result) if cnt <= req.Limit { @@ -282,6 +307,7 @@ func dao2dtoQuiz(quiz model.Quiz) ShavedQuiz { DueTo: quiz.DueTo, TimeOfPassing: quiz.TimeOfPassing, Pausable: quiz.Pausable, + Status: quiz.Status, } } @@ -362,6 +388,42 @@ func (s *Service) PutAnswersOnePiece(c *fiber.Ctx) error { for _, ans := range answersRaw { + if quiz.Status == model.StatusAI { + final := false + if finalStr, exists := form.Value["final"]; exists && len(finalStr) > 0 { + parsedFinal, err := strconv.ParseBool(finalStr[0]) + if err != nil { + return c.Status(fiber.StatusBadRequest).SendString("invalid final value") + } + final = parsedFinal + } + + question, err := s.dal.QuestionRepo.GetQuestionListByIDs(c.Context(), []int32{int32(ans.QuestionId)}) + if err != nil { + return c.Status(fiber.StatusInternalServerError).SendString("can not get questions") + } + + if len(question) == 0 { + return c.Status(fiber.StatusNotFound).SendString("no questions found") + } + + questionText, err := s.aiClient.SendAnswerer(final, question[0].Type, ans.Content, cs) + if err != nil { + return c.Status(fiber.StatusInternalServerError).SendString(fmt.Sprintf("failed send answer to ai, err: %s", err.Error())) + } + + _, err = s.dal.QuestionRepo.CreateQuestion(c.Context(), &model.Question{ + QuizId: quiz.Id, + Title: " ", + Type: model.TypeText, + Session: cs, + Description: questionText, + }) + if err != nil { + return c.Status(fiber.StatusInternalServerError).SendString(fmt.Sprintf("failed create question type ai, err: %s", err.Error())) + } + } + ans.DeviceType = deviceType ans.OS = os ans.Browser = browser