feat(grpc): add support for fetching grades and exams
All checks were successful
Build / build (push) Successful in 2m14s
All checks were successful
Build / build (push) Successful in 2m14s
Implement new gRPC task handlers for retrieving student grades and exam schedules. This includes adding new parser logic for processing score and exam data, and updating the client capabilities to advertise support for these new task types. - Add `getGrades` and `getExams` handlers in `grpc/handler.go` - Add `parser/encoding.go`, `parser/exam.go`, and `parser/score.go` for data parsing - Update `grpc/client.go` to include `TASK_TYPE_GET_GRADES` and `TASK_TYPE_GET_EXAMS` in capabilities
This commit is contained in:
74
parser/encoding.go
Normal file
74
parser/encoding.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/text/encoding/simplifiedchinese"
|
||||
"golang.org/x/text/transform"
|
||||
)
|
||||
|
||||
func decodeResponseBody(resp *http.Response) (string, error) {
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return decodeBody(body, resp.Header.Get("Content-Type")), nil
|
||||
}
|
||||
|
||||
func decodeBody(body []byte, contentType string) string {
|
||||
lowerCT := strings.ToLower(contentType)
|
||||
if strings.Contains(lowerCT, "charset=gb") || strings.Contains(lowerCT, "charset=gb2312") || strings.Contains(lowerCT, "charset=gbk") {
|
||||
decoded, err := decodeGBK(body)
|
||||
if err == nil {
|
||||
return decoded
|
||||
}
|
||||
}
|
||||
|
||||
if isValidUTF8(body) {
|
||||
return string(body)
|
||||
}
|
||||
|
||||
decoded, err := decodeGBK(body)
|
||||
if err == nil {
|
||||
return decoded
|
||||
}
|
||||
return string(body)
|
||||
}
|
||||
|
||||
func decodeGBK(data []byte) (string, error) {
|
||||
reader := transform.NewReader(bytes.NewReader(data), simplifiedchinese.GBK.NewDecoder())
|
||||
decoded, err := io.ReadAll(reader)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(decoded), nil
|
||||
}
|
||||
|
||||
func isValidUTF8(data []byte) bool {
|
||||
for i := 0; i < len(data); i++ {
|
||||
if data[i]&0x80 != 0 {
|
||||
if data[i]&0xE0 == 0xC0 {
|
||||
if i+1 >= len(data) || data[i+1]&0xC0 != 0x80 {
|
||||
return false
|
||||
}
|
||||
i++
|
||||
} else if data[i]&0xF0 == 0xE0 {
|
||||
if i+2 >= len(data) || data[i+1]&0xC0 != 0x80 || data[i+2]&0xC0 != 0x80 {
|
||||
return false
|
||||
}
|
||||
i += 2
|
||||
} else if data[i]&0xF8 == 0xF0 {
|
||||
if i+3 >= len(data) || data[i+1]&0xC0 != 0x80 || data[i+2]&0xC0 != 0x80 || data[i+3]&0xC0 != 0x80 {
|
||||
return false
|
||||
}
|
||||
i += 3
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
Reference in New Issue
Block a user