From 235ff521bdb947959e375784709f6fbbbeb4945d Mon Sep 17 00:00:00 2001 From: johlanse Date: Mon, 4 Jul 2022 11:27:57 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0docker=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yml | 1 + .github/workflows/push-to-docker.yml | 38 +++++++++ Dockerfile | 46 +++-------- lib/config_default.yml | 2 +- lib/core.go | 117 +++++++++++++++++---------- main.go | 14 +++- utils/stydyState.go | 35 ++++++++ 7 files changed, 174 insertions(+), 79 deletions(-) create mode 100644 .github/workflows/push-to-docker.yml create mode 100644 utils/stydyState.go diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6102a2d..20e6d98 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,3 +53,4 @@ jobs: name: ${{ matrix.goos }}_${{ matrix.goarch }} path: output/ + diff --git a/.github/workflows/push-to-docker.yml b/.github/workflows/push-to-docker.yml new file mode 100644 index 0000000..65dd1c3 --- /dev/null +++ b/.github/workflows/push-to-docker.yml @@ -0,0 +1,38 @@ +name: docker build + +on: [push, pull_request] + +env: + BINARY_PREFIX: "study_xxqg_" + BINARY_SUFFIX: "" + PR_PROMPT: "::warning:: Build artifact will not be uploaded due to the workflow is trigged by pull request." + LD_FLAGS: "-w -s" + +jobs: + build: + name: Build binary CI + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Setup Go environment + uses: actions/setup-go@v2.1.3 + with: + go-version: 1.17 + - name: Build binary file + run: | + export LD_FLAGS="-w -s -X main.VERSION=${COMMIT_ID::7}" + go mod tidy + go build -o "output/study_xxqg" -trimpath -ldflags "$LD_FLAGS" ./ + + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + - name: push to docker + run: | + docker login -u ${{secrets.DOCKERHUB_USERNAME}} -p ${{secrets.DOCKERHUB_PASSWORD}} + ls -R + pwd + docker build -t jolanse/study_xxqg ./ + docker push jolanse/study_xxqg + diff --git a/Dockerfile b/Dockerfile index b2949d8..ce3bb29 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,40 +1,18 @@ -FROM golang:bullseye AS build_study_xxqg - -ARG TARGETARCH -ARG BUILDARCH - -ENV CGO_ENABLED="0" -ENV GOOS="linux" -ENV GOPROXY="https://goproxy.cn" -ARG UPX_VERSION="3.96" - -RUN sed -i "s@http://deb.debian.org@https://mirrors.163.com@g" /etc/apt/sources.list && apt update && apt install -y xz-utils git gcc curl -COPY / /study_xxqg -RUN cd /study_xxqg && \ - version=$(git describe --tags --long --always) && \ - echo "${version}" && \ - GOARCH=${TARGETARCH} go build -ldflags "-s -w -X main.version=${version}" -trimpath -o study_xxqg -RUN target="${BUILDARCH}" && \ - curl -sSL https://github.com/upx/upx/releases/download/v${UPX_VERSION}/upx-${UPX_VERSION}-${target}_linux.tar.xz | tar xvJf - -C / && \ - cp -f /upx-${UPX_VERSION}-${target}_linux/upx /usr/bin/ && \ - /usr/bin/upx -9 -v /study_xxqg/study_xxqg - - FROM debian:bullseye-slim -ARG TARGETARCH +COPY ./output/study_xxqg /opt/study_xxqg -ENV TIMEZONE="Asia/Shanghai" +RUN mkdir /opt/config/ -RUN apt update \ - && apt install -y --no-install-recommends ca-certificates tzdata libglib2.0-0 libnss3 libatk1.0-0 libcups2 libatk-bridge2.0-0 libdrm2 libxcb1 libxkbcommon0 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 libgbm1 libpango-1.0-0 libcairo2 libasound2 libxshmfence1 \ - && ln -sf /usr/share/zoneinfo/${TIMEZONE} /etc/localtime \ - && echo "${TIMEZONE}" > /etc/timezone \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* -# install study_xxqg -COPY --from=build_study_xxqg /study_xxqg/study_xxqg /study_xxqg +COPY ./lib/config_default.yml /opt/config/config.yml -VOLUME ["/config"] +RUN apt-get -qq update \ + && apt-get -qq install -y --no-install-recommends ca-certificates curl \ + && apt-get update && apt-get install -y libx11-6 libgbm1 libasound2 libcairo2 libxshmfence1 libatspi2.0-0 libpango-1.0-0 libnss3 \ + libatk1.0-0 libatk-bridge2.0-0 libcups2 libxrandr2 libxfixes3 libxdamage1 libxcomposite1 libxkbcommon0 \ + && chmod -R 777 /opt/study_xxqg && cd /opt/ && ./study_xxqg --init +EXPOSE 8080 -ENTRYPOINT ["/study_xxqg"] +VOLUME /opt/config + +CMD cd /opt && ./study_xxqg \ No newline at end of file diff --git a/lib/config_default.yml b/lib/config_default.yml index 1876091..80b4f4f 100644 --- a/lib/config_default.yml +++ b/lib/config_default.yml @@ -63,7 +63,7 @@ retry: # 设置是否定时执行学习程序,格式为cron格式 # "9 19 * * *" 每天19点9分执行一次 # "* 10 * * *” 每天早上十点执行一次 -cron: "" +cron: "0 0 * * *" #windows环境自定义浏览器路径,仅支持chromium系列 edge_path: "" diff --git a/lib/core.go b/lib/core.go index 147fdec..b029322 100644 --- a/lib/core.go +++ b/lib/core.go @@ -127,32 +127,25 @@ func GetToken(code, sign string) (bool, error) { return true, err } -// L -/** - * @Description: +// GenerateCode +/* @Description: 生成二维码 * @receiver c - * @return *model.User + * @return string 二维码连接 + * @return string 二维码回调查询的code * @return error */ -func (c *Core) L(retryTimes int) (*model.User, error) { +func (c *Core) GenerateCode() (string, string, error) { client := req.C() client.OnAfterResponse(func(client *req.Client, response *req.Response) error { return nil }) client.SetCommonHeader("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36") - s := new(signResp) - _, err := client.R().SetResult(s).Get("https://pc-api.xuexi.cn/open/api/sns/sign") - if err != nil { - log.Errorln(err.Error()) - return nil, err - } - log.Debugln("获取sign成功==》" + s.Data.Sign) g := new(gennerateResp) - _, err = client.R().SetResult(g).Get("https://login.xuexi.cn/user/qrcode/generate") + _, err := client.R().SetResult(g).Get("https://login.xuexi.cn/user/qrcode/generate") if err != nil { log.Errorln(err.Error()) - return nil, err + return "", "", err } log.Infoln(g.Result) codeURL := fmt.Sprintf("https://login.xuexi.cn/login/qrcommit?showmenu=false&code=%v&appId=dingoankubyrfkttorhpou", g.Result) @@ -172,10 +165,20 @@ func (c *Core) L(retryTimes int) (*model.User, error) { qrCodeString := qrcodeTerminal.New2(qrcodeTerminal.ConsoleColors.BrightBlack, qrcodeTerminal.ConsoleColors.BrightWhite, qrcodeTerminal.QRCodeRecoveryLevels.Low).Get(codeURL) qrCodeString.Print() c.Push("flush", "登录链接:\r\n"+config.Scheme+url.QueryEscape(codeURL)) + return codeURL, g.Result, err +} + +func (c *Core) CheckQrCode(code string) (*model.User, bool, error) { + client := req.C() + client.OnAfterResponse(func(client *req.Client, response *req.Response) error { + return nil + }) + client.SetCommonHeader("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36") + checkQrCode := func() (bool, string) { res := new(checkQrCodeResp) _, err := client.R().SetResult(res).SetFormData(map[string]string{ - "qrCode": g.Result, + "qrCode": code, "goto": "https://oa.xuexi.cn", "pdmToken": ""}).SetHeader("content-type", "application/x-www-form-urlencoded;charset=UTF-8").Post("https://login.xuexi.cn/login/login_with_qr") if err != nil { @@ -186,33 +189,65 @@ func (c *Core) L(retryTimes int) (*model.User, error) { } return false, "" } - for i := 0; i < 150; i++ { - code, data := checkQrCode() - if code { - s2 := strings.Split(data, "=")[1] - response, err := client.R().SetQueryParams(map[string]string{ - "code": s2, - "state": s.Data.Sign + uuid.New().String(), - }).Get("https://pc-api.xuexi.cn/login/secure_check") - if err != nil { - return nil, err - } + qrCode, s := checkQrCode() + if !qrCode { + return nil, false, nil + } else { + sign := new(signResp) + _, err := client.R().SetResult(s).Get("https://pc-api.xuexi.cn/open/api/sns/sign") + if err != nil { + log.Errorln(err.Error()) + return nil, false, err + } + s2 := strings.Split(s, "=")[1] + response, err := client.R().SetQueryParams(map[string]string{ + "code": s2, + "state": sign.Data.Sign + uuid.New().String(), + }).Get("https://pc-api.xuexi.cn/login/secure_check") + if err != nil { + return nil, false, err + } - uid, nick, err := GetUserInfo(response.Cookies()) - if err != nil { - return nil, err - } - user := &model.User{ - Nick: nick, - UID: uid, - Token: response.Cookies()[0].Value, - LoginTime: time.Now().Unix(), - } - err = model.AddUser(user) - if err != nil { - return nil, err - } - c.Push("text", "登录成功,用户名:"+nick) + uid, nick, err := GetUserInfo(response.Cookies()) + if err != nil { + return nil, false, err + } + user := &model.User{ + Nick: nick, + UID: uid, + Token: response.Cookies()[0].Value, + LoginTime: time.Now().Unix(), + } + err = model.AddUser(user) + if err != nil { + return nil, false, err + } + c.Push("text", "登录成功,用户名:"+nick) + return user, true, err + } +} + +// L +/** + * @Description: + * @receiver c + * @return *model.User + * @return error + */ +func (c *Core) L(retryTimes int) (*model.User, error) { + _, codeData, err := c.GenerateCode() + if err != nil { + return nil, err + } + client := req.C() + client.OnAfterResponse(func(client *req.Client, response *req.Response) error { + return nil + }) + client.SetCommonHeader("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36") + + for i := 0; i < 150; i++ { + user, b, err := c.CheckQrCode(codeData) + if b && err == nil { return user, err } } diff --git a/main.go b/main.go index 6a5dcb2..00bf9cf 100644 --- a/main.go +++ b/main.go @@ -14,6 +14,7 @@ import ( log "github.com/sirupsen/logrus" easy "github.com/t-tomalak/logrus-easy-formatter" + //"github.com/huoxue1/study_xxqg/gui" "github.com/huoxue1/study_xxqg/lib" "github.com/huoxue1/study_xxqg/model" "github.com/huoxue1/study_xxqg/push" @@ -23,13 +24,14 @@ import ( var ( u bool + i bool ) var VERSION = "unknown" func init() { - flag.BoolVar(&u, "u", false, "update the study_xxqg") + flag.BoolVar(&i, "init", false, "init the app") flag.Parse() config = lib.GetConfig() @@ -74,6 +76,13 @@ func init() { } func main() { + if i { + core := &lib.Core{} + core.Init() + core.Quit() + return + } + go update.CheckUpdate(VERSION) if u { @@ -123,7 +132,6 @@ func main() { return } c.Start() - select {} }() } @@ -143,7 +151,6 @@ func main() { Proxy: config.TG.Proxy, } telegram.Init() - select {} }() } @@ -151,6 +158,7 @@ func main() { log.Infoln("已采用普通学习模式") do("normal") } else { + //gui.InitWindow() select {} } } diff --git a/utils/stydyState.go b/utils/stydyState.go new file mode 100644 index 0000000..abfc420 --- /dev/null +++ b/utils/stydyState.go @@ -0,0 +1,35 @@ +package utils + +import ( + "errors" + "sync" + + "github.com/huoxue1/study_xxqg/lib" +) + +// 该文件的方法为保存当前正在学习的用户 + +var ( + state sync.Map +) + +func Add(uid string, core *lib.Core) error { + _, ok := state.Load(uid) + if ok { + return errors.New("the user is studying") + } else { + state.Store(uid, core) + return nil + } +} + +func Delete(uid string) error { + state.Delete(uid) + return nil +} + +func Item(item func(uid string, core *lib.Core) bool) { + state.Range(func(key, value interface{}) bool { + return item(key.(string), value.(*lib.Core)) + }) +}