添加docker支持

This commit is contained in:
johlanse 2022-07-04 11:27:57 +08:00
parent 71b24a9e14
commit 235ff521bd
7 changed files with 174 additions and 79 deletions

View File

@ -53,3 +53,4 @@ jobs:
name: ${{ matrix.goos }}_${{ matrix.goarch }} name: ${{ matrix.goos }}_${{ matrix.goarch }}
path: output/ path: output/

38
.github/workflows/push-to-docker.yml vendored Normal file
View File

@ -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

View File

@ -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 FROM debian:bullseye-slim
ARG TARGETARCH COPY ./output/study_xxqg /opt/study_xxqg
ENV TIMEZONE="Asia/Shanghai" RUN mkdir /opt/config/
RUN apt update \ COPY ./lib/config_default.yml /opt/config/config.yml
&& 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
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

View File

@ -63,7 +63,7 @@ retry:
# 设置是否定时执行学习程序格式为cron格式 # 设置是否定时执行学习程序格式为cron格式
# "9 19 * * *" 每天19点9分执行一次 # "9 19 * * *" 每天19点9分执行一次
# "* 10 * * *” 每天早上十点执行一次 # "* 10 * * *” 每天早上十点执行一次
cron: "" cron: "0 0 * * *"
#windows环境自定义浏览器路径仅支持chromium系列 #windows环境自定义浏览器路径仅支持chromium系列
edge_path: "" edge_path: ""

View File

@ -127,32 +127,25 @@ func GetToken(code, sign string) (bool, error) {
return true, err return true, err
} }
// L // GenerateCode
/** /* @Description: 生成二维码
* @Description:
* @receiver c * @receiver c
* @return *model.User * @return string 二维码连接
* @return string 二维码回调查询的code
* @return error * @return error
*/ */
func (c *Core) L(retryTimes int) (*model.User, error) { func (c *Core) GenerateCode() (string, string, error) {
client := req.C() client := req.C()
client.OnAfterResponse(func(client *req.Client, response *req.Response) error { client.OnAfterResponse(func(client *req.Client, response *req.Response) error {
return nil 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") 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) 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 { if err != nil {
log.Errorln(err.Error()) log.Errorln(err.Error())
return nil, err return "", "", err
} }
log.Infoln(g.Result) log.Infoln(g.Result)
codeURL := fmt.Sprintf("https://login.xuexi.cn/login/qrcommit?showmenu=false&code=%v&appId=dingoankubyrfkttorhpou", 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 := qrcodeTerminal.New2(qrcodeTerminal.ConsoleColors.BrightBlack, qrcodeTerminal.ConsoleColors.BrightWhite, qrcodeTerminal.QRCodeRecoveryLevels.Low).Get(codeURL)
qrCodeString.Print() qrCodeString.Print()
c.Push("flush", "登录链接:\r\n"+config.Scheme+url.QueryEscape(codeURL)) 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) { checkQrCode := func() (bool, string) {
res := new(checkQrCodeResp) res := new(checkQrCodeResp)
_, err := client.R().SetResult(res).SetFormData(map[string]string{ _, err := client.R().SetResult(res).SetFormData(map[string]string{
"qrCode": g.Result, "qrCode": code,
"goto": "https://oa.xuexi.cn", "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") "pdmToken": ""}).SetHeader("content-type", "application/x-www-form-urlencoded;charset=UTF-8").Post("https://login.xuexi.cn/login/login_with_qr")
if err != nil { if err != nil {
@ -186,33 +189,65 @@ func (c *Core) L(retryTimes int) (*model.User, error) {
} }
return false, "" return false, ""
} }
for i := 0; i < 150; i++ { qrCode, s := checkQrCode()
code, data := checkQrCode() if !qrCode {
if code { return nil, false, nil
s2 := strings.Split(data, "=")[1] } else {
response, err := client.R().SetQueryParams(map[string]string{ sign := new(signResp)
"code": s2, _, err := client.R().SetResult(s).Get("https://pc-api.xuexi.cn/open/api/sns/sign")
"state": s.Data.Sign + uuid.New().String(), if err != nil {
}).Get("https://pc-api.xuexi.cn/login/secure_check") log.Errorln(err.Error())
if err != nil { return nil, false, err
return nil, 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()) uid, nick, err := GetUserInfo(response.Cookies())
if err != nil { if err != nil {
return nil, err return nil, false, err
} }
user := &model.User{ user := &model.User{
Nick: nick, Nick: nick,
UID: uid, UID: uid,
Token: response.Cookies()[0].Value, Token: response.Cookies()[0].Value,
LoginTime: time.Now().Unix(), LoginTime: time.Now().Unix(),
} }
err = model.AddUser(user) err = model.AddUser(user)
if err != nil { if err != nil {
return nil, err return nil, false, err
} }
c.Push("text", "登录成功,用户名:"+nick) 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 return user, err
} }
} }

14
main.go
View File

@ -14,6 +14,7 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
easy "github.com/t-tomalak/logrus-easy-formatter" 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/lib"
"github.com/huoxue1/study_xxqg/model" "github.com/huoxue1/study_xxqg/model"
"github.com/huoxue1/study_xxqg/push" "github.com/huoxue1/study_xxqg/push"
@ -23,13 +24,14 @@ import (
var ( var (
u bool u bool
i bool
) )
var VERSION = "unknown" var VERSION = "unknown"
func init() { func init() {
flag.BoolVar(&u, "u", false, "update the study_xxqg") flag.BoolVar(&u, "u", false, "update the study_xxqg")
flag.BoolVar(&i, "init", false, "init the app")
flag.Parse() flag.Parse()
config = lib.GetConfig() config = lib.GetConfig()
@ -74,6 +76,13 @@ func init() {
} }
func main() { func main() {
if i {
core := &lib.Core{}
core.Init()
core.Quit()
return
}
go update.CheckUpdate(VERSION) go update.CheckUpdate(VERSION)
if u { if u {
@ -123,7 +132,6 @@ func main() {
return return
} }
c.Start() c.Start()
select {}
}() }()
} }
@ -143,7 +151,6 @@ func main() {
Proxy: config.TG.Proxy, Proxy: config.TG.Proxy,
} }
telegram.Init() telegram.Init()
select {}
}() }()
} }
@ -151,6 +158,7 @@ func main() {
log.Infoln("已采用普通学习模式") log.Infoln("已采用普通学习模式")
do("normal") do("normal")
} else { } else {
//gui.InitWindow()
select {} select {}
} }
} }

35
utils/stydyState.go Normal file
View File

@ -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))
})
}