2021-11-12 07:46:33 +00:00
|
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
2022-05-27 13:37:16 +00:00
|
|
|
|
"flag"
|
2021-11-15 13:52:59 +00:00
|
|
|
|
"fmt"
|
2022-12-14 07:43:39 +00:00
|
|
|
|
"github.com/sjkhsl/study_xxqg/utils/stop"
|
2021-11-15 13:52:59 +00:00
|
|
|
|
"io"
|
2022-08-07 10:39:15 +00:00
|
|
|
|
"math/rand"
|
2022-07-30 10:55:00 +00:00
|
|
|
|
"net/http"
|
2021-11-12 07:46:33 +00:00
|
|
|
|
"os"
|
2022-10-03 03:05:57 +00:00
|
|
|
|
"os/exec"
|
|
|
|
|
"os/signal"
|
2021-11-12 07:46:33 +00:00
|
|
|
|
"path"
|
2022-10-31 10:41:06 +00:00
|
|
|
|
"runtime"
|
2021-11-17 09:39:48 +00:00
|
|
|
|
"strconv"
|
2022-10-17 14:10:59 +00:00
|
|
|
|
"sync"
|
2022-10-03 03:05:57 +00:00
|
|
|
|
"syscall"
|
2021-11-12 07:46:33 +00:00
|
|
|
|
"time"
|
|
|
|
|
|
2022-08-06 02:55:21 +00:00
|
|
|
|
"github.com/gin-gonic/gin"
|
2021-11-12 07:46:33 +00:00
|
|
|
|
rotates "github.com/lestrrat-go/file-rotatelogs"
|
2021-11-17 09:39:48 +00:00
|
|
|
|
"github.com/robfig/cron/v3"
|
2021-11-12 07:46:33 +00:00
|
|
|
|
log "github.com/sirupsen/logrus"
|
2022-09-09 15:14:06 +00:00
|
|
|
|
|
|
|
|
|
nested "github.com/Lyrics-you/sail-logrus-formatter/sailor"
|
2022-10-03 03:05:57 +00:00
|
|
|
|
"github.com/huoxue1/xdaemon"
|
2021-11-12 07:46:33 +00:00
|
|
|
|
|
2022-12-14 07:43:39 +00:00
|
|
|
|
"github.com/sjkhsl/study_xxqg/conf"
|
|
|
|
|
"github.com/sjkhsl/study_xxqg/lib/state"
|
|
|
|
|
"github.com/sjkhsl/study_xxqg/utils"
|
|
|
|
|
// "github.com/sjkhsl/study_xxqg/gui"
|
|
|
|
|
"github.com/sjkhsl/study_xxqg/lib"
|
|
|
|
|
"github.com/sjkhsl/study_xxqg/model"
|
|
|
|
|
"github.com/sjkhsl/study_xxqg/push"
|
|
|
|
|
"github.com/sjkhsl/study_xxqg/utils/update"
|
|
|
|
|
"github.com/sjkhsl/study_xxqg/web"
|
2021-11-12 07:46:33 +00:00
|
|
|
|
)
|
|
|
|
|
|
2022-05-27 13:37:16 +00:00
|
|
|
|
var (
|
2022-08-12 01:17:23 +00:00
|
|
|
|
u bool
|
|
|
|
|
i bool
|
2022-10-17 14:10:59 +00:00
|
|
|
|
now bool
|
2022-08-12 01:17:23 +00:00
|
|
|
|
configPath = ""
|
2022-05-27 13:37:16 +00:00
|
|
|
|
)
|
|
|
|
|
|
2022-02-11 10:13:50 +00:00
|
|
|
|
var VERSION = "unknown"
|
|
|
|
|
|
2021-11-12 07:46:33 +00:00
|
|
|
|
func init() {
|
2022-11-12 11:56:05 +00:00
|
|
|
|
if runtime.GOOS != "windows" {
|
|
|
|
|
runBack()
|
|
|
|
|
}
|
2022-09-09 15:14:06 +00:00
|
|
|
|
fmt.Printf("\033[1;31;40m%s\033[0m\n\n", "******************************************************************")
|
|
|
|
|
|
|
|
|
|
fmt.Printf("\033[1;31;40m%s\033[0m\n\n", "软件仅可用户学习和个人使用,禁止用于任何商业活动!!!!")
|
|
|
|
|
|
|
|
|
|
fmt.Printf("\033[1;31;40m%s\033[0m\n\n", "软件仅可用户学习和个人使用,禁止用于任何商业活动!!!!")
|
|
|
|
|
|
|
|
|
|
fmt.Printf("\033[1;31;40m%s\033[0m\n\n", "软件仅可用户学习和个人使用,禁止用于任何商业活动!!!!")
|
|
|
|
|
|
|
|
|
|
fmt.Printf("\033[1;31;40m%s\033[0m\n\n", "******************************************************************")
|
2022-10-03 03:05:57 +00:00
|
|
|
|
time.Sleep(3 * time.Second)
|
2022-09-09 15:14:06 +00:00
|
|
|
|
|
2022-08-12 01:17:23 +00:00
|
|
|
|
flag.BoolVar(&u, "u", false, "更新应用")
|
2022-07-04 03:27:57 +00:00
|
|
|
|
flag.BoolVar(&i, "init", false, "init the app")
|
2022-10-17 14:10:59 +00:00
|
|
|
|
flag.BoolVar(&now, "now", false, "run cron now")
|
2022-08-12 01:17:23 +00:00
|
|
|
|
flag.StringVar(&configPath, "config", "./config/config.yml", "设置配置文件路径")
|
2022-05-27 13:37:16 +00:00
|
|
|
|
flag.Parse()
|
2022-08-12 01:17:23 +00:00
|
|
|
|
// 初始化配置文件
|
2022-08-27 05:12:12 +00:00
|
|
|
|
conf.InitConfig(configPath, utils.Restart)
|
2022-07-27 10:21:49 +00:00
|
|
|
|
config = conf.GetConfig()
|
2022-07-29 08:02:41 +00:00
|
|
|
|
w, err := rotates.New(path.Join("config", "logs", "%Y-%m-%d.log"), rotates.WithRotationTime(time.Hour*24))
|
2021-11-12 07:46:33 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("rotates init err: %v", err)
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
2022-09-09 15:14:06 +00:00
|
|
|
|
gin.DefaultWriter = io.MultiWriter(w, &utils.LogWriter{})
|
2021-11-15 13:52:59 +00:00
|
|
|
|
log.SetOutput(io.MultiWriter(w, os.Stdout))
|
2022-09-09 15:14:06 +00:00
|
|
|
|
|
2021-11-12 07:46:33 +00:00
|
|
|
|
level, err := log.ParseLevel(config.LogLevel)
|
2022-05-02 12:30:49 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
log.SetLevel(log.DebugLevel)
|
|
|
|
|
}
|
2021-11-12 07:46:33 +00:00
|
|
|
|
log.SetLevel(level)
|
2022-09-09 15:14:06 +00:00
|
|
|
|
|
|
|
|
|
showPosition := false
|
|
|
|
|
|
|
|
|
|
if level == log.DebugLevel {
|
|
|
|
|
showPosition = true
|
|
|
|
|
}
|
|
|
|
|
log.SetFormatter(&nested.Formatter{
|
|
|
|
|
FieldsOrder: nil,
|
|
|
|
|
TimeStampFormat: "2006-01-02 15:04:05",
|
|
|
|
|
CharStampFormat: "",
|
|
|
|
|
HideKeys: false,
|
|
|
|
|
Position: showPosition,
|
|
|
|
|
Colors: true,
|
|
|
|
|
FieldsColors: true,
|
|
|
|
|
FieldsSpace: true,
|
|
|
|
|
ShowFullLevel: false,
|
|
|
|
|
LowerCaseLevel: true,
|
|
|
|
|
TrimMessages: true,
|
|
|
|
|
CallerFirst: false,
|
|
|
|
|
CustomCallerFormatter: nil,
|
|
|
|
|
})
|
2022-08-26 15:00:28 +00:00
|
|
|
|
if !utils.CheckQuestionDB() {
|
2022-09-22 12:17:06 +00:00
|
|
|
|
go utils.DownloadDbFile()
|
2022-12-14 07:43:39 +00:00
|
|
|
|
//log.Errorln("题库文件不存在或已损坏,请手动前往 https://github.com/sjkhsl/study_xxqg/blob/main/conf/QuestionBank.db 下载并放入程序根目录")
|
2022-08-26 15:00:28 +00:00
|
|
|
|
}
|
2021-11-12 07:46:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-03-10 06:33:05 +00:00
|
|
|
|
func init() {
|
|
|
|
|
pid := os.Getpid()
|
|
|
|
|
pi := strconv.Itoa(pid)
|
|
|
|
|
err := os.WriteFile("pid.pid", []byte(pi), 0666)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorln("pid写入失败")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-12 07:46:33 +00:00
|
|
|
|
var (
|
2022-07-27 10:21:49 +00:00
|
|
|
|
config conf.Config
|
2021-11-12 07:46:33 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
|
_, err := os.Stat(`./config/`)
|
|
|
|
|
if err != nil {
|
2022-11-09 00:20:20 +00:00
|
|
|
|
_ = os.Mkdir("./config/", 0666)
|
2021-11-12 07:46:33 +00:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func main() {
|
2022-08-05 10:08:05 +00:00
|
|
|
|
conf.SetVersion(VERSION)
|
2022-08-05 09:39:01 +00:00
|
|
|
|
log.Infoln("当前程序运行版本: " + VERSION)
|
2022-07-04 03:27:57 +00:00
|
|
|
|
if i {
|
|
|
|
|
core := &lib.Core{}
|
|
|
|
|
core.Init()
|
|
|
|
|
core.Quit()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-27 13:37:16 +00:00
|
|
|
|
go update.CheckUpdate(VERSION)
|
|
|
|
|
|
|
|
|
|
if u {
|
|
|
|
|
update.SelfUpdate("", VERSION)
|
|
|
|
|
log.Infoln("请重启应用")
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-31 12:33:39 +00:00
|
|
|
|
engine := web.RouterInit()
|
|
|
|
|
go func() {
|
|
|
|
|
h := http.NewServeMux()
|
2022-11-08 12:22:58 +00:00
|
|
|
|
if config.QQ.Enable {
|
|
|
|
|
h.Handle("/qq", push.InitQQ())
|
|
|
|
|
log.Infoln(fmt.Sprintf("已开启qq配置,监听地址: ==》 %v:%v", config.Web.Host, config.Web.Port))
|
|
|
|
|
}
|
2022-07-31 12:33:39 +00:00
|
|
|
|
if config.Web.Enable {
|
2022-08-07 10:39:15 +00:00
|
|
|
|
log.Infoln(fmt.Sprintf("已开启web配置,web监听地址 ==> %v:%v", config.Web.Host, config.Web.Port))
|
2022-07-30 10:55:00 +00:00
|
|
|
|
h.Handle("/", engine)
|
2022-07-31 12:33:39 +00:00
|
|
|
|
}
|
|
|
|
|
if config.Wechat.Enable {
|
2022-08-07 10:39:15 +00:00
|
|
|
|
log.Infoln(fmt.Sprintf("已开启wechat公众号配置,监听地址: ==》 %v:%v", config.Web.Host, config.Web.Port))
|
2022-08-15 07:07:03 +00:00
|
|
|
|
h.HandleFunc("/wx", push.HandleWechat)
|
2022-07-31 12:33:39 +00:00
|
|
|
|
}
|
2022-11-09 00:20:20 +00:00
|
|
|
|
if config.Web.Enable || config.Wechat.Enable || config.QQ.Enable {
|
2022-07-30 10:55:00 +00:00
|
|
|
|
err := http.ListenAndServe(fmt.Sprintf("%s:%d", config.Web.Host, config.Web.Port), h)
|
2022-04-20 13:31:46 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
2022-07-31 12:33:39 +00:00
|
|
|
|
}
|
|
|
|
|
}()
|
2022-04-20 13:31:46 +00:00
|
|
|
|
|
2022-04-14 13:18:36 +00:00
|
|
|
|
if config.StartWait > 0 {
|
|
|
|
|
log.Infoln(fmt.Sprintf("将等待%d秒后启动程序", config.StartWait))
|
|
|
|
|
time.Sleep(time.Second * time.Duration(config.StartWait))
|
|
|
|
|
}
|
2022-05-02 12:30:49 +00:00
|
|
|
|
|
|
|
|
|
if config.Cron != "" {
|
|
|
|
|
go func() {
|
2022-10-26 12:32:26 +00:00
|
|
|
|
|
2022-05-02 12:30:49 +00:00
|
|
|
|
log.Infoln("已采用定时执行模式")
|
2022-08-10 10:17:49 +00:00
|
|
|
|
c := cron.New()
|
2022-08-07 10:39:15 +00:00
|
|
|
|
|
2022-05-02 12:30:49 +00:00
|
|
|
|
_, err := c.AddFunc(config.Cron, func() {
|
2022-08-07 10:39:15 +00:00
|
|
|
|
log.Infoln("即将开始执行定时任务")
|
|
|
|
|
// 检测是否开启了随机等待
|
|
|
|
|
if config.CronRandomWait > 0 {
|
|
|
|
|
rand.Seed(time.Now().UnixNano())
|
|
|
|
|
r := rand.Intn(config.CronRandomWait)
|
2022-08-10 10:17:49 +00:00
|
|
|
|
log.Infoln(fmt.Sprintf("随机延迟%d分钟", r))
|
2022-08-07 10:39:15 +00:00
|
|
|
|
time.Sleep(time.Duration(r) * time.Minute)
|
|
|
|
|
}
|
2022-10-31 07:10:29 +00:00
|
|
|
|
do()
|
2022-05-02 12:30:49 +00:00
|
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorln(err.Error())
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
c.Start()
|
|
|
|
|
}()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if config.TG.Enable {
|
2022-08-15 07:07:03 +00:00
|
|
|
|
push.TgInit()
|
2022-05-02 12:30:49 +00:00
|
|
|
|
}
|
2022-08-15 07:07:03 +00:00
|
|
|
|
getPush := push.GetPush(config)
|
|
|
|
|
getPush("", "flush", "学习强国助手已上线")
|
2022-09-03 12:01:51 +00:00
|
|
|
|
|
|
|
|
|
if config.CustomCron != "" {
|
|
|
|
|
c2 := cron.New()
|
|
|
|
|
_, err := c2.AddFunc(config.CustomCron, func() {
|
|
|
|
|
getPush("all", "flush", config.CustomMessage)
|
|
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorln("添加自定义定时消息推送错误" + err.Error())
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
c2.Run()
|
|
|
|
|
}
|
2022-11-06 07:01:22 +00:00
|
|
|
|
initTask()
|
2022-08-18 07:39:03 +00:00
|
|
|
|
model.SetPush(getPush)
|
2022-10-17 14:10:59 +00:00
|
|
|
|
if now {
|
2022-10-31 07:10:29 +00:00
|
|
|
|
do()
|
2021-11-17 09:39:48 +00:00
|
|
|
|
}
|
2022-11-12 11:56:05 +00:00
|
|
|
|
stop.Stop()
|
2022-10-31 10:41:06 +00:00
|
|
|
|
|
2021-11-17 09:39:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-10-31 07:10:29 +00:00
|
|
|
|
func do() {
|
2022-04-25 10:39:54 +00:00
|
|
|
|
|
2021-11-12 07:46:33 +00:00
|
|
|
|
log.Infoln("检测到模式", config.Model)
|
2021-11-27 08:24:24 +00:00
|
|
|
|
|
2021-11-17 09:39:48 +00:00
|
|
|
|
getPush := push.GetPush(config)
|
2022-08-15 07:07:03 +00:00
|
|
|
|
getPush("", "flush", "学习强国助手已上线")
|
2022-03-17 15:11:43 +00:00
|
|
|
|
users, _ := model.Query()
|
2022-05-13 04:38:04 +00:00
|
|
|
|
|
2022-08-26 00:25:07 +00:00
|
|
|
|
failUser, _ := model.QueryFailUser()
|
|
|
|
|
for _, user := range failUser {
|
|
|
|
|
go func(user2 *model.User) {
|
|
|
|
|
c := &lib.Core{Push: getPush, ShowBrowser: config.ShowBrowser}
|
|
|
|
|
getPush(user2.PushId, "flush", user2.Nick+"的cookie已过期")
|
|
|
|
|
newUser, err := c.L(config.Retry.Times, user2.PushId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
c.Push(user2.PushId, "flush", "用户"+user2.Nick+"登录超时!")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
c.Init()
|
|
|
|
|
defer c.Quit()
|
2022-11-06 07:01:22 +00:00
|
|
|
|
lib.Study(c, newUser)
|
2022-08-26 00:25:07 +00:00
|
|
|
|
}(user)
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-31 07:10:29 +00:00
|
|
|
|
s := &sync.WaitGroup{}
|
|
|
|
|
// 如果为定时模式则直接循环所以用户依次运行
|
|
|
|
|
|
2022-11-06 07:01:22 +00:00
|
|
|
|
if config.PoolSize == 1 {
|
|
|
|
|
for _, user := range users {
|
2022-11-08 07:44:47 +00:00
|
|
|
|
if state.IsStudy(user.Uid) {
|
2022-11-06 07:01:22 +00:00
|
|
|
|
log.Infoln("检测到该用户已在学习中!")
|
|
|
|
|
continue
|
|
|
|
|
} else {
|
|
|
|
|
core := &lib.Core{ShowBrowser: config.ShowBrowser, Push: getPush}
|
|
|
|
|
core.Init()
|
2022-11-08 07:44:47 +00:00
|
|
|
|
state.Add(user.Uid, core)
|
2022-11-06 07:01:22 +00:00
|
|
|
|
lib.Study(core, user)
|
|
|
|
|
core.Quit()
|
2022-11-08 07:44:47 +00:00
|
|
|
|
state.Delete(user.Uid)
|
2022-11-06 07:01:22 +00:00
|
|
|
|
}
|
2022-05-24 13:36:35 +00:00
|
|
|
|
|
2022-05-13 04:38:04 +00:00
|
|
|
|
}
|
2022-11-06 07:01:22 +00:00
|
|
|
|
} else {
|
|
|
|
|
for _, u := range users {
|
2022-11-08 07:44:47 +00:00
|
|
|
|
if state.IsStudy(u.Uid) {
|
2022-11-06 07:01:22 +00:00
|
|
|
|
log.Infoln("检测到该用户已在学习中!")
|
|
|
|
|
continue
|
|
|
|
|
} else {
|
|
|
|
|
core := &lib.Core{ShowBrowser: config.ShowBrowser, Push: getPush}
|
|
|
|
|
core.Init()
|
|
|
|
|
t := &Task{
|
|
|
|
|
Core: core,
|
|
|
|
|
User: u,
|
|
|
|
|
wg: s,
|
|
|
|
|
}
|
2022-10-31 07:10:29 +00:00
|
|
|
|
|
2022-11-06 07:01:22 +00:00
|
|
|
|
run(t)
|
|
|
|
|
s.Add(1)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
s.Wait()
|
2022-10-31 07:10:29 +00:00
|
|
|
|
}
|
2022-11-06 07:01:22 +00:00
|
|
|
|
log.Infoln("定时任务执行完成")
|
|
|
|
|
return
|
2022-10-17 14:10:59 +00:00
|
|
|
|
|
2021-11-12 07:46:33 +00:00
|
|
|
|
}
|
2022-10-03 03:05:57 +00:00
|
|
|
|
|
|
|
|
|
func runBack() {
|
|
|
|
|
cmd, err := xdaemon.Background(os.Stdout, false)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Fatalln(err.Error())
|
|
|
|
|
}
|
|
|
|
|
if xdaemon.IsParent() {
|
|
|
|
|
go onKill(cmd)
|
|
|
|
|
for true {
|
|
|
|
|
_ = cmd.Wait()
|
|
|
|
|
if cmd.ProcessState.Exited() {
|
2022-10-03 03:13:09 +00:00
|
|
|
|
log.Infoln(cmd.ProcessState)
|
2022-10-03 03:20:56 +00:00
|
|
|
|
if cmd.ProcessState.ExitCode() != 201 {
|
2022-10-03 03:05:57 +00:00
|
|
|
|
break
|
2022-10-03 03:13:09 +00:00
|
|
|
|
} else {
|
|
|
|
|
log.Infoln("检测到重启,开始重启程序")
|
2022-10-03 03:05:57 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
cmd, err = xdaemon.Background(os.Stdout, false)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
os.Exit(0)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func onKill(cmd *exec.Cmd) {
|
|
|
|
|
c := make(chan os.Signal)
|
|
|
|
|
//监听指定信号 ctrl+c kill
|
|
|
|
|
signal.Notify(c, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
|
|
|
|
|
<-c
|
|
|
|
|
|
|
|
|
|
if cmd.Process != nil {
|
|
|
|
|
cmd.Process.Kill()
|
|
|
|
|
}
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|