Initial commit

This commit is contained in:
2026-03-13 20:43:44 +08:00
commit 17cdb7ad0d
19 changed files with 4744 additions and 0 deletions

162
main.go Normal file
View File

@@ -0,0 +1,162 @@
package main
import (
"context"
"flag"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"jwts/auth"
"jwts/captcha"
"jwts/client"
"jwts/config"
grpcClient "jwts/grpc"
"jwts/parser"
"github.com/gin-gonic/gin"
)
func main() {
mode := flag.String("mode", "http", "运行模式: http 或 grpc")
grpcAddr := flag.String("grpc-addr", "localhost:50051", "gRPC 服务器地址")
flag.Parse()
if *mode == "grpc" {
runGRPCClient(*grpcAddr)
} else {
runHTTPServer()
}
}
// runGRPCClient 运行 gRPC 客户端模式
func runGRPCClient(serverAddr string) {
runnerID := os.Getenv("RUNNER_ID")
if runnerID == "" {
hostname, _ := os.Hostname()
runnerID = "runner-" + hostname
}
version := os.Getenv("RUNNER_VERSION")
if version == "" {
version = "1.0.0"
}
log.Printf("启动 gRPC 客户端, Runner ID: %s, 版本: %s", runnerID, version)
client := grpcClient.NewClient(serverAddr, runnerID, version)
handler := grpcClient.NewTaskHandler()
client.SetHandler(handler)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// 处理信号
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
if err := client.Connect(ctx); err != nil {
log.Printf("连接失败: %v", err)
os.Exit(1)
}
go func() {
<-sigChan
log.Println("正在关闭...")
client.Close()
cancel()
}()
// 启动心跳
go client.HeartbeatLoop(ctx, 30*time.Second)
// 运行主循环
if err := client.Run(ctx); err != nil {
log.Printf("客户端错误: %v", err)
}
}
// runHTTPServer 运行 HTTP 服务器模式
func runHTTPServer() {
// 初始化客户端
client.InitClient()
r := gin.Default()
// 健康检查接口
r.GET("/ping", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "pong",
})
})
// 任务处理接口
r.POST("/task", func(c *gin.Context) {
// 这里可以根据请求体参数决定执行什么任务
// 目前默认执行原有的登录和获取课表逻辑
if config.Username == "" || config.Password == "" {
c.JSON(http.StatusInternalServerError, gin.H{"error": "环境变量未设置"})
return
}
// 执行任务
err := runTask()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "任务执行成功"})
})
// 启动服务
log.Println("Server starting on :8080")
if err := r.Run(":8080"); err != nil {
log.Fatalf("Failed to run server: %v", err)
}
}
func runTask() error {
// 步骤1: 获取初始Cookie
err := client.GetInitialCookies()
if err != nil {
log.Printf("获取Cookie失败: %v", err)
return err
}
// 重试登录
maxRetries := 3
for attempt := 1; attempt <= maxRetries; attempt++ {
log.Printf("尝试登录 (第%d次)...", attempt)
// 获取并识别验证码
captchaCode, err := captcha.GetAndRecognize(client.Client)
if err != nil {
log.Printf(" 验证码获取失败: %v", err)
continue
}
// 登录
success, err := auth.Login(captchaCode)
if err != nil {
log.Printf(" 登录失败: %v", err)
continue
}
if success {
// 获取课表
_, err = parser.FetchSchedule(client.Client)
if err != nil {
log.Printf("获取课表失败: %v", err)
}
return nil
}
log.Println(" 登录失败3秒后重试...")
}
return nil
}