From a88d6405f00d3571479feabda1dc88e790a8c405 Mon Sep 17 00:00:00 2001 From: ozline Date: Sun, 20 Oct 2024 00:17:38 +0800 Subject: [PATCH] feat: license and ci support autotest --- .github/workflows/ci.yaml | 74 ++++++++++++++ .github/workflows/test.yml | 9 +- .gitignore | 6 +- .golangci.yml | 70 +++++++++++++ .licenseignore | 1 + LICENSE | 201 +++++++++++++++++++++++++++++++++++++ Makefile | 28 ++++++ README.md | 16 ++- calendar.go | 25 ++++- constants/constants.go | 23 +++++ course.go | 24 +++-- credit.go | 19 +++- errno/code.go | 18 +++- errno/default.go | 16 +++ errno/errno.go | 16 +++ hack/add-license.sh | 25 +++++ hack/boilerplate.go.txt | 15 +++ hack/boilerplate.shell.txt | 13 +++ jwch.go | 29 ++++-- jwch_test.go | 177 +++++++++++--------------------- logindata.txt | 19 ---- mark.go | 21 +++- model.go | 24 ++++- room.go | 33 ++++-- user.go | 33 ++++-- utils/utils.go | 26 +++-- xpath.go | 17 +++- 27 files changed, 782 insertions(+), 196 deletions(-) create mode 100644 .github/workflows/ci.yaml create mode 100644 .golangci.yml create mode 100644 .licenseignore create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 hack/add-license.sh create mode 100644 hack/boilerplate.go.txt create mode 100644 hack/boilerplate.shell.txt delete mode 100644 logindata.txt diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..6d09b6b --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,74 @@ +name: CI + +on: + push: + branches: + - main + - dev + pull_request: + branches: + - main + - dev + +permissions: + contents: read + +jobs: + fmt: + name: Format + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version-file: go.mod + cache: false + - name: Check Go modules + run: | + go mod tidy && git add go.* && + git diff --cached --exit-code || (echo 'Please run "go mod tidy" to sync Go modules' && exit 1); + - name: Verify gofumpt + run: | + echo "refer to https://github.com/mvdan/gofumpt for detailed info" && + GO111MODULE=on go install mvdan.cc/gofumpt@v0.4.0 && + make fmt && git add pkg cmd && + git diff --cached --exit-code || (echo 'Please run "make fmt" to verify fmt' && exit 1); + + vet: + name: Vet + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version-file: go.mod + cache: false + - name: Verify govet + run: | + make vet && git add pkg cmd && + git diff --cached --exit-code || (echo 'Please run "make vet" to verify govet' && exit 1); + + lint: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: '1.23' + cache: false + - name: golangci-lint + uses: golangci/golangci-lint-action@v6 + with: + version: latest + args: --timeout=10m + + license: + name: License + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v3 + - name: Check license header + run: | + make license && git add pkg cmd && + git diff --cached --exit-code || (echo 'Please run "make license" to add license headers' && exit 1); \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9808c82..dc2baee 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,7 +8,6 @@ on: jobs: test: runs-on: ubuntu-latest - environment: 052106112 steps: - uses: actions/checkout@v4 @@ -16,10 +15,10 @@ jobs: - name: Set up Go uses: actions/setup-go@v4 with: - go-version: '1.22' + go-version: '1.23' - name: Test - run: go test + run: go test -v ./... env: - JWCH_USERNAME: ${{ secrets.SCHOOL_ID }} - JWCH_PASSWORD: ${{ secrets.PASSWORD }} + JWCH_USERNAME: ${{ secrets.USERNAME_23 }} + JWCH_PASSWORD: ${{ secrets.PASSWORD_23 }} diff --git a/.gitignore b/.gitignore index 9b11eb9..d3f8117 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,8 @@ test.html cookies.txt config.yaml -tempCodeRunnerFile.go \ No newline at end of file +tempCodeRunnerFile.go + +act_secret_file +result.txt +/output \ No newline at end of file diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..929e679 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,70 @@ +# options for analysis running +run: + # default concurrency is the available CPU number + concurrency: 16 + + # timeout for analysis, e.g. 30s, 5m, default is 1m + timeout: 10m + + # exit code when at least one issue was found, default is 1 + issues-exit-code: 1 + + # include test files or not, default is true + tests: true + + # which dirs to skip: they won't be analyzed; + # can use regexp here: generated.*, regexp is applied on full path; + # default value is empty list, but next dirs are always skipped independently + # from this option's value: + # third_party$, testdata$, examples$, Godeps$, builtin$ + # skip-dirs: + +# output configuration options +output: + # print lines of code with issue, default is true + print-issued-lines: true + + # print linter name in the end of issue text, default is true + print-linter-name: true + + +# all available settings of specific linters +linters-settings: + golint: + # minimal confidence for issues, default is 0.8 + min-confidence: 0.8 + gofmt: + # simplify code: gofmt with `-s` option, true by default + simplify: true + goimports: + # put imports beginning with prefix after 3rd-party packages; + # it's a comma-separated list of prefixes + local-prefixes: github.com/west2-online + misspell: + # Correct spellings using locale preferences for US or UK. + # Default is to use a neutral variety of English. + # Setting locale to US will correct the British spelling of 'colour' to 'color'. + locale: US + staticcheck: + checks: + - all + - -SA1019 + +linters: + fast: false + disable-all: true + enable: + - errcheck + - staticcheck + - typecheck + - unused + - misspell + - nolintlint + - goimports + - nakedret + - unconvert + - whitespace + - govet + - gosimple + - ineffassign + - gocritic \ No newline at end of file diff --git a/.licenseignore b/.licenseignore new file mode 100644 index 0000000..5657f6e --- /dev/null +++ b/.licenseignore @@ -0,0 +1 @@ +vendor \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a3987f0 --- /dev/null +++ b/Makefile @@ -0,0 +1,28 @@ +# 格式化代码,我们使用 gofumpt,是 fmt 的严格超集 +.PHONY: fmt +fmt: + gofumpt -l -w . + +# 优化 import 顺序结构 +.PHONY: import +import: + goimports -w -local github.com/west2-online . + +# 检查可能的错误 +.PHONY: vet +vet: + go vet ./... + +# 代码格式校验 +.PHONY: lint +lint: + golangci-lint run --config=./.golangci.yml + +# 一键修正规范并执行代码检查 +.PHONY: verify +verify: vet fmt import lint + +# 补齐 license +.PHONY: license +license: + sh ./hack/add-license.sh diff --git a/README.md b/README.md index eb66512..9956914 100644 --- a/README.md +++ b/README.md @@ -65,5 +65,17 @@ For more detail, plz visit API docs. └── utils.go ``` -### 飞书文档: -https://west2-online.feishu.cn/wiki/HAZUwmgkWiRq4zkBkAecu5eGn9n \ No newline at end of file +### Lark Docs +https://west2-online.feishu.cn/wiki/HAZUwmgkWiRq4zkBkAecu5eGn9n + +### Local Action Test + +we can use act to local github action test. + +1. Create `act_secret_file` in root folder +2. Insert items: +```env +USERNAME_23="YourJwchAccount" +PASSWORD_23="YourJwchSecret" +``` +3. use `act push --secret-file ./act_secret_file` \ No newline at end of file diff --git a/calendar.go b/calendar.go index a0fb2a5..b9af4b8 100644 --- a/calendar.go +++ b/calendar.go @@ -1,23 +1,43 @@ +/* +Copyright 2024 The west2-online Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package jwch import ( - "github.com/west2-online/jwch/utils" "regexp" "strings" + "github.com/west2-online/jwch/utils" + "github.com/antchfx/htmlquery" + "github.com/west2-online/jwch/constants" ) func (s *Student) GetSchoolCalendar() (*SchoolCalendar, error) { resp, err := s.GetWithIdentifier(constants.SchoolCalendarURL) - if err != nil { return nil, err } rawCurTerm := htmlquery.InnerText(htmlquery.FindOne(resp, `//html/body/center/div`)) rawCurTerm, err = utils.ConvertGB2312ToUTF8([]byte(rawCurTerm)) + if err != nil { + return nil, err + } curTermRegex := regexp.MustCompile(`当前学期:(\d{6})`) curTerm := curTermRegex.FindStringSubmatch(rawCurTerm)[1] @@ -61,7 +81,6 @@ func (s *Student) GetTermEvents(termId string) (*CalTermEvents, error) { "xq": termId, "submit": "提交", }) - if err != nil { return nil, err } diff --git a/constants/constants.go b/constants/constants.go index 2ef0a32..6c1b8a8 100644 --- a/constants/constants.go +++ b/constants/constants.go @@ -1,3 +1,19 @@ +/* +Copyright 2024 The west2-online Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package constants const ( @@ -11,6 +27,13 @@ const ( SchoolCalendarURL = "https://jwcjwxt2.fzu.edu.cn:82/xl.asp" CreditQueryURL = "https://jwcjwxt2.fzu.edu.cn:81/student/xyzk/xftj/CreditStatistics.aspx" GPAQueryURL = "https://jwcjwxt2.fzu.edu.cn:81/student/xyzk/jdpm/GPA_sheet.aspx" + VerifyCodeURL = "https://jwcjwxt1.fzu.edu.cn/plus/verifycode.asp" + + JwchPrefix = "https://jwcjwxt2.fzu.edu.cn:81" + JwchReferer = "https://jwcjwxt1.fzu.edu.cn/" + JwchOrigin = "https://jwcjwxt1.fzu.edu.cn/" + + AutoCaptchaVerifyURL = "https://statistics.fzuhelper.w2fzu.com/api/login/validateCode?validateCode" ) var BuildingArray = []string{"公共教学楼东1", "公共教学楼东2", "公共教学楼东3", "公共教学楼文科楼", "公共教学楼西1", "公共教学楼西2", "公共教学楼西3", "公共教学楼中楼"} diff --git a/course.go b/course.go index a5f3573..fb36438 100644 --- a/course.go +++ b/course.go @@ -1,3 +1,19 @@ +/* +Copyright 2024 The west2-online Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package jwch import ( @@ -16,7 +32,6 @@ import ( // 获取我的学期 func (s *Student) GetTerms() (*Term, error) { resp, err := s.GetWithIdentifier(constants.CourseURL) - if err != nil { return nil, err } @@ -43,14 +58,12 @@ func (s *Student) GetTerms() (*Term, error) { // 获取我的选课 func (s *Student) GetSemesterCourses(term, viewState, eventValidation string) ([]*Course, error) { - resp, err := s.PostWithIdentifier(constants.CourseURL, map[string]string{ "ctl00$ContentPlaceHolder1$DDL_xnxq": term, "ctl00$ContentPlaceHolder1$BT_submit": "确定", "__VIEWSTATE": viewState, "__EVENTVALIDATION": eventValidation, }) - if err != nil { return nil, err } @@ -64,7 +77,6 @@ func (s *Student) GetSemesterCourses(term, viewState, eventValidation string) ([ res := make([]*Course, 0) for _, node := range list { - // 教务处的表格HTML是不规范的,因此XPath解析会出现一些BUG if strings.TrimSpace(htmlquery.SelectAttr(node, "style")) == "" { continue @@ -309,8 +321,8 @@ func (s *Student) GetSemesterCourses(term, viewState, eventValidation string) ([ // TODO: performance optimization res = append(res, &Course{ Name: htmlquery.OutputHTML(info[1], false), - Syllabus: "https://jwcjwxt2.fzu.edu.cn:81" + safeExtractRegex(`javascript:pop1\('(.*?)&`, safeExtractionValue(info[2], "a", "href", 0)), - LessonPlan: "https://jwcjwxt2.fzu.edu.cn:81" + safeExtractRegex(`javascript:pop1\('(.*?)&`, safeExtractionValue(info[2], "a", "href", 1)), + Syllabus: constants.JwchPrefix + safeExtractRegex(`javascript:pop1\('(.*?)&`, safeExtractionValue(info[2], "a", "href", 0)), + LessonPlan: constants.JwchPrefix + safeExtractRegex(`javascript:pop1\('(.*?)&`, safeExtractionValue(info[2], "a", "href", 1)), Teacher: htmlquery.OutputHTML(info[7], false), ScheduleRules: scheduleRules, RawScheduleRules: strings.Join(courseInfo8, "\n"), diff --git a/credit.go b/credit.go index 62cd48a..7b7ab26 100644 --- a/credit.go +++ b/credit.go @@ -1,3 +1,19 @@ +/* +Copyright 2024 The west2-online Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package jwch import ( @@ -5,11 +21,11 @@ import ( "strings" "github.com/antchfx/htmlquery" + "github.com/west2-online/jwch/constants" ) func (s *Student) GetCredit() (creditStatistics []*CreditStatistics, err error) { - resp, err := s.GetWithIdentifier(constants.CreditQueryURL) if err != nil { return nil, err @@ -64,6 +80,7 @@ func (s *Student) GetCredit() (creditStatistics []*CreditStatistics, err error) return creditStatistics, nil } + func (s *Student) GetGPA() (gpa *GPABean, err error) { gpa = &GPABean{} resp, err := s.GetWithIdentifier(constants.GPAQueryURL) diff --git a/errno/code.go b/errno/code.go index 847722c..78dcf68 100644 --- a/errno/code.go +++ b/errno/code.go @@ -1,3 +1,19 @@ +/* +Copyright 2024 The west2-online Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package errno const ( @@ -6,7 +22,7 @@ const ( SuccessMsg = "success" // Error - ServiceErrorCode = 10001 // 未知微服务错误 + ServiceErrorCode = 10001 // 默认服务错误 ParamErrorCode = 10002 // 参数错误 HTTPQueryErrorCode = 10003 // HTTP请求出错 AuthorizationFailedErrCode = 10004 // 鉴权失败 diff --git a/errno/default.go b/errno/default.go index 6ba31f2..96fe8cc 100644 --- a/errno/default.go +++ b/errno/default.go @@ -1,3 +1,19 @@ +/* +Copyright 2024 The west2-online Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package errno var ( diff --git a/errno/errno.go b/errno/errno.go index 5581387..6478744 100644 --- a/errno/errno.go +++ b/errno/errno.go @@ -1,3 +1,19 @@ +/* +Copyright 2024 The west2-online Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package errno import ( diff --git a/hack/add-license.sh b/hack/add-license.sh new file mode 100644 index 0000000..a70d9f5 --- /dev/null +++ b/hack/add-license.sh @@ -0,0 +1,25 @@ +# Copyright 2024 The west2-online Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +PROJECT=$(cd $(dirname $0)/..; pwd) + +LICENSEHEADERCHECKER_VERSION=v1.5.0 + +GOBIN=${PROJECT}/output go install github.com/lluissm/license-header-checker/cmd/license-header-checker@${LICENSEHEADERCHECKER_VERSION} + +LICENSEIGNORE=$(cat ${PROJECT}/.licenseignore | tr '\n' ',') + +${PROJECT}/output/license-header-checker -r -a -v -i ${LICENSEIGNORE} ${PROJECT}/hack/boilerplate.go.txt . go + +${PROJECT}/output/license-header-checker -r -a -v -i ${LICENSEIGNORE} ${PROJECT}/hack/boilerplate.shell.txt . sh \ No newline at end of file diff --git a/hack/boilerplate.go.txt b/hack/boilerplate.go.txt new file mode 100644 index 0000000..41bec46 --- /dev/null +++ b/hack/boilerplate.go.txt @@ -0,0 +1,15 @@ +/* +Copyright 2024 The west2-online Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ \ No newline at end of file diff --git a/hack/boilerplate.shell.txt b/hack/boilerplate.shell.txt new file mode 100644 index 0000000..8fe0507 --- /dev/null +++ b/hack/boilerplate.shell.txt @@ -0,0 +1,13 @@ +# Copyright 2024 The west2-online Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. \ No newline at end of file diff --git a/jwch.go b/jwch.go index 755c30c..86aaa71 100644 --- a/jwch.go +++ b/jwch.go @@ -1,3 +1,19 @@ +/* +Copyright 2024 The west2-online Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package jwch import ( @@ -7,6 +23,7 @@ import ( "net/http" "strings" + "github.com/west2-online/jwch/constants" "github.com/west2-online/jwch/errno" "github.com/antchfx/htmlquery" @@ -17,8 +34,10 @@ import ( func NewStudent() *Student { // Disable HTTP/2.0 // Disable Redirect - client := resty.New().SetTransport(&http.Transport{TLSNextProto: make(map[string]func(authority string, c *tls.Conn) http.RoundTripper), - TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}).SetRedirectPolicy(resty.NoRedirectPolicy()) + client := resty.New().SetTransport(&http.Transport{ + TLSNextProto: make(map[string]func(authority string, c *tls.Conn) http.RoundTripper), + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }).SetRedirectPolicy(resty.NoRedirectPolicy()) return &Student{ client: client, @@ -58,8 +77,7 @@ func (s *Student) NewRequest() *resty.Request { } func (s *Student) GetWithIdentifier(url string) (*html.Node, error) { - resp, err := s.NewRequest().SetHeader("Referer", "https://jwcjwxt1.fzu.edu.cn/").SetQueryParam("id", s.Identifier).Get(url) - + resp, err := s.NewRequest().SetHeader("Referer", constants.JwchReferer).SetQueryParam("id", s.Identifier).Get(url) if err != nil { return nil, errno.HTTPQueryError.WithErr(err) } @@ -74,7 +92,7 @@ func (s *Student) GetWithIdentifier(url string) (*html.Node, error) { // PostWithSession returns parse tree for the resp of the request. func (s *Student) PostWithIdentifier(url string, formData map[string]string) (*html.Node, error) { - resp, err := s.NewRequest().SetHeader("Referer", "https://jwcjwxt1.fzu.edu.cn/").SetQueryParam("id", s.Identifier).SetFormData(formData).Post(url) + resp, err := s.NewRequest().SetHeader("Referer", constants.JwchReferer).SetQueryParam("id", s.Identifier).SetFormData(formData).Post(url) s.NewRequest().EnableTrace() @@ -104,7 +122,6 @@ func GetValidateCode(image string) (string, error) { } err = json.Unmarshal(resp.Body(), &code) - if err != nil { return "", errno.HTTPQueryError.WithErr(err) } diff --git a/jwch_test.go b/jwch_test.go index f9a555c..40f7ad4 100644 --- a/jwch_test.go +++ b/jwch_test.go @@ -1,3 +1,19 @@ +/* +Copyright 2024 The west2-online Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package jwch import ( @@ -5,13 +21,14 @@ import ( "os" "testing" + "github.com/west2-online/jwch/constants" "github.com/west2-online/jwch/utils" ) var ( - username = os.Getenv("JWCH_USERNAME") // 学号 - password = os.Getenv("JWCH_PASSWORD") // 密码 - localfile = "logindata.txt" + username = os.Getenv("JWCH_USERNAME") // 学号 + password = os.Getenv("JWCH_PASSWORD") // 密码 + // localfile = "logindata.txt" ) var ( @@ -20,15 +37,12 @@ var ( ) func login() error { - err := stu.Login() - if err != nil { return err } err = stu.CheckSession() - if err != nil { return err } @@ -37,10 +51,24 @@ func login() error { return nil } +func TestMain(m *testing.M) { + err := login() + if err != nil { + fmt.Printf("Login failed: %v\n", err) + os.Exit(1) + } + + // 运行测试 + code := m.Run() + + // 在所有测试结束后执行清理 + os.Exit(code) +} + func Test_GetValidateCode(t *testing.T) { // 获取验证码图片 s := NewStudent() - resp, err := s.NewRequest().Get("https://jwcjwxt1.fzu.edu.cn/plus/verifycode.asp") + resp, err := s.NewRequest().Get(constants.VerifyCodeURL) if err != nil { t.Error(err) } @@ -52,91 +80,48 @@ func Test_GetValidateCode(t *testing.T) { } func Test_GetIdentifierAndCookies(t *testing.T) { - Identifier, cookies := stu.GetIdentifierAndCookies() - fmt.Println(Identifier) - fmt.Println(cookies) -} - -func Test_Login(t *testing.T) { - err := login() + _, _, err := stu.GetIdentifierAndCookies() if err != nil { t.Error(err) } } func Test_GetCourse(t *testing.T) { - if !islogin { - err := login() - - if err != nil { - t.Error(err) - } - } - terms, err := stu.GetTerms() - if err != nil { t.Error(err) } list, err := stu.GetSemesterCourses(terms.Terms[0], terms.ViewState, terms.EventValidation) - if err != nil { t.Error(err) } fmt.Println("course num:", len(list)) - for _, v := range list { - fmt.Println(utils.PrintStruct(v)) - } + // 不允许输出具体课程 } func Test_GetInfo(t *testing.T) { - if !islogin { - err := login() - - if err != nil { - t.Error(err) - } - } - - detail, err := stu.GetInfo() - + _, err := stu.GetInfo() if err != nil { t.Error(err) } - fmt.Println(utils.PrintStruct(detail)) + // 不允许输出个人信息 } func Test_GetMarks(t *testing.T) { - if !islogin { - err := login() - - if err != nil { - t.Error(err) - } - } - - marks, err := stu.GetMarks() - + _, err := stu.GetMarks() if err != nil { t.Error(err) } - fmt.Println(utils.PrintStruct(marks)) + // 不允许输出成绩 } -// 使用并发后似乎快了1s( +// 使用并发后似乎快了1s func Test_GetQiShanEmptyRoom(t *testing.T) { - if !islogin { - err := login() - if err != nil { - t.Error(err) - } - } - rooms, err := stu.GetQiShanEmptyRoom(EmptyRoomReq{ Campus: "旗山校区", Time: "2024-09-26", @@ -147,17 +132,11 @@ func Test_GetQiShanEmptyRoom(t *testing.T) { t.Error(err) } + // 此处可以输出空教室信息 fmt.Println(utils.PrintStruct(rooms)) } func Test_GetJinJiangEmptyRoom(t *testing.T) { - if !islogin { - err := login() - if err != nil { - t.Error(err) - } - } - rooms, err := stu.GetEmptyRoom(EmptyRoomReq{ Campus: "晋江校区", Time: "2024-09-19", @@ -168,17 +147,11 @@ func Test_GetJinJiangEmptyRoom(t *testing.T) { t.Error(err) } + // 此处可以输出空教室信息 fmt.Println(utils.PrintStruct(rooms)) } func Test_GetTongPanEmptyRoom(t *testing.T) { - if !islogin { - err := login() - if err != nil { - t.Error(err) - } - } - rooms, err := stu.GetEmptyRoom(EmptyRoomReq{ Campus: "铜盘校区", Time: "2024-09-19", @@ -189,17 +162,11 @@ func Test_GetTongPanEmptyRoom(t *testing.T) { t.Error(err) } + // 此处可以输出空教室信息 fmt.Println(utils.PrintStruct(rooms)) } func Test_GetQuanGangEmptyRoom(t *testing.T) { - if !islogin { - err := login() - if err != nil { - t.Error(err) - } - } - rooms, err := stu.GetEmptyRoom(EmptyRoomReq{ Campus: "泉港校区", Time: "2024-09-19", @@ -210,17 +177,11 @@ func Test_GetQuanGangEmptyRoom(t *testing.T) { t.Error(err) } + // 此处可以输出空教室信息 fmt.Println(utils.PrintStruct(rooms)) } func Test_GetYiShanEmptyRoom(t *testing.T) { - if !islogin { - err := login() - if err != nil { - t.Error(err) - } - } - rooms, err := stu.GetEmptyRoom(EmptyRoomReq{ Campus: "怡山校区", Time: "2024-09-19", @@ -231,17 +192,11 @@ func Test_GetYiShanEmptyRoom(t *testing.T) { t.Error(err) } + // 此处可以输出空教室信息 fmt.Println(utils.PrintStruct(rooms)) } func Test_GetXiaMenEmptyRoom(t *testing.T) { - if !islogin { - err := login() - if err != nil { - t.Error(err) - } - } - rooms, err := stu.GetEmptyRoom(EmptyRoomReq{ Campus: "厦门工艺美院", Time: "2024-09-19", @@ -252,6 +207,7 @@ func Test_GetXiaMenEmptyRoom(t *testing.T) { t.Error(err) } + // 此处可以输出空教室信息 fmt.Println(utils.PrintStruct(rooms)) } @@ -261,6 +217,7 @@ func Test_GetSchoolCalendar(t *testing.T) { t.Error(err) } + // 此处可以输出校历信息 fmt.Println(utils.PrintStruct(calendar)) } @@ -275,58 +232,38 @@ func Test_GetTermEvents(t *testing.T) { t.Error(err) } + // 此处可以输出学期信息 fmt.Println(utils.PrintStruct(events)) } func Test_GetCredit(t *testing.T) { - if !islogin { - err := login() - if err != nil { - t.Error(err) - } - } - - credit, err := stu.GetCredit() + _, err := stu.GetCredit() if err != nil { t.Error(err) } - fmt.Println(utils.PrintStruct(credit)) + // 不允许输出学分信息 } func Test_GetGPA(t *testing.T) { - if !islogin { - err := login() - if err != nil { - t.Error(err) - } - } - gpa, err := stu.GetGPA() + _, err := stu.GetGPA() if err != nil { t.Error(err) } - fmt.Println(utils.PrintStruct(gpa)) + // 不允许输出 GPA 信息 } func TestGetUnifiedExam(t *testing.T) { - if !islogin { - err := login() - if err != nil { - t.Error(err) - } - } - cet, err := stu.GetCET() + _, err := stu.GetCET() if err != nil { t.Error(err) } - fmt.Println(utils.PrintStruct(cet)) - - js, err := stu.GetJS() + _, err = stu.GetJS() if err != nil { t.Error(err) } - fmt.Println(utils.PrintStruct(js)) + // 不允许输出考试成绩信息 } diff --git a/logindata.txt b/logindata.txt deleted file mode 100644 index 9bbc692..0000000 --- a/logindata.txt +++ /dev/null @@ -1,19 +0,0 @@ -{ - "cookies": [ - { - "Name": "ASP.NET_SessionId", - "Value": "1soqnddidmy2ynqvhx02vuqy", - "Path": "/", - "Domain": "", - "Expires": "0001-01-01T00:00:00Z", - "RawExpires": "", - "MaxAge": 0, - "Secure": false, - "HttpOnly": true, - "SameSite": 2, - "Raw": "ASP.NET_SessionId=1soqnddidmy2ynqvhx02vuqy; path=/; HttpOnly; SameSite=Lax", - "Unparsed": null - } - ], - "session": "2023314233350052106112" -} \ No newline at end of file diff --git a/mark.go b/mark.go index f1c4e25..3870691 100644 --- a/mark.go +++ b/mark.go @@ -1,13 +1,30 @@ +/* +Copyright 2024 The west2-online Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package jwch import ( "fmt" "strings" + "golang.org/x/net/html" + "github.com/west2-online/jwch/constants" "github.com/west2-online/jwch/errno" "github.com/west2-online/jwch/utils" - "golang.org/x/net/html" "github.com/antchfx/htmlquery" ) @@ -15,7 +32,6 @@ import ( // 获取成绩,由于教务处缺陷,这里会返回全部的成绩 func (s *Student) GetMarks() (resp []*Mark, err error) { res, err := s.GetWithIdentifier(constants.MarksQueryURL) - if err != nil { return nil, err } @@ -29,7 +45,6 @@ func (s *Student) GetMarks() (resp []*Mark, err error) { resp = make([]*Mark, 0) for _, node := range list { - // 教务处的表格HTML是不规范的,因此XPath解析会出现一些BUG if strings.TrimSpace(htmlquery.SelectAttr(node, "style")) == "" { continue diff --git a/model.go b/model.go index 4bf1bed..2cafe00 100644 --- a/model.go +++ b/model.go @@ -1,3 +1,19 @@ +/* +Copyright 2024 The west2-online Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package jwch import ( @@ -10,10 +26,10 @@ import ( type Student struct { ID string `json:"id"` // 学号 Password string `json:"password"` // 密码 - cookies []*http.Cookie //cookies中将包含session_id和其他数据 - //如果我们使用client进行登陆的话,此时该字段失效,因为client会在登录时自动保存登陆凭证(session) - //所以该字段用于其他服务调用时传递登陆凭证 - Identifier string //位于url上id=....的一个标识符,主要用于组成url + cookies []*http.Cookie // cookies中将包含session_id和其他数据 + // 如果我们使用client进行登陆的话,此时该字段失效,因为client会在登录时自动保存登陆凭证(session) + // 所以该字段用于其他服务调用时传递登陆凭证 + Identifier string // 位于url上id=....的一个标识符,主要用于组成url client *resty.Client // Request对象 } diff --git a/room.go b/room.go index e0d87f3..972df70 100644 --- a/room.go +++ b/room.go @@ -1,9 +1,26 @@ +/* +Copyright 2024 The west2-online Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package jwch import ( "github.com/antchfx/htmlquery" - "github.com/west2-online/jwch/constants" "golang.org/x/net/html" + + "github.com/west2-online/jwch/constants" ) func (s *Student) GetEmptyRoom(req EmptyRoomReq) ([]string, error) { @@ -15,7 +32,7 @@ func (s *Student) GetEmptyRoom(req EmptyRoomReq) ([]string, error) { if err != nil { return nil, err } - //按照教室类型进行并发访问 + // 按照教室类型进行并发访问 channels := make([]chan struct { res []string err error @@ -29,7 +46,8 @@ func (s *Student) GetEmptyRoom(req EmptyRoomReq) ([]string, error) { go func(t string, ch chan struct { res []string err error - }) { + }, + ) { res, err := s.PostWithIdentifier(constants.ClassroomQueryURL, map[string]string{ "__VIEWSTATE": emptyRoomState["VIEWSTATE"], @@ -65,7 +83,6 @@ func (s *Student) GetEmptyRoom(req EmptyRoomReq) ([]string, error) { err error }{res: rooms, err: nil} }(t, channels[i]) - } for _, ch := range channels { temp := <-ch @@ -83,8 +100,8 @@ func (s *Student) GetQiShanEmptyRoom(req EmptyRoomReq) ([]string, error) { return nil, err } var rooms []string - //这里按照building的顺序进行并发爬取 - //创建channel数组 + // 这里按照building的顺序进行并发爬取 + // 创建channel数组 channels := make([]chan struct { res []string err error @@ -98,7 +115,8 @@ func (s *Student) GetQiShanEmptyRoom(req EmptyRoomReq) ([]string, error) { go func(index int, building string, ch chan struct { res []string err error - }) { + }, + ) { roomTypes, emptyRoomState, err := s.getEmptyRoomTypes(viewStateMap, building, req) if err != nil { ans := struct { @@ -175,7 +193,6 @@ func (s *Student) getEmptyRoomState() (map[string]string, error) { "VIEWSTATE": viewState, "EVENTVALIDATION": eventValidation, }, nil - } // 获取教室类型 diff --git a/user.go b/user.go index 263f6ca..4f27380 100644 --- a/user.go +++ b/user.go @@ -1,3 +1,19 @@ +/* +Copyright 2024 The west2-online Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package jwch import ( @@ -33,7 +49,6 @@ func (s *Student) Login() error { passMD5 := utils.Md5Hash(s.Password, 16) // 获取验证码图片 resp, err := s.NewRequest().Get("https://jwcjwxt1.fzu.edu.cn/plus/verifycode.asp") - if err != nil { return errno.HTTPQueryError.WithErr(err) } @@ -41,13 +56,12 @@ func (s *Student) Login() error { // 请求西二服务器,自动识别验证码 resp, err = s.NewRequest().SetFormData(map[string]string{ "validateCode": utils.Base64EncodeHTTPImage(resp.Body()), - }).Post("https://statistics.fzuhelper.w2fzu.com/api/login/validateCode?validateCode") + }).Post(constants.AutoCaptchaVerifyURL) if err != nil { return errno.HTTPQueryError.WithMessage("automatic code identification failed") } err = json.Unmarshal(resp.Body(), &code) - if err != nil { return errno.HTTPQueryError.WithErr(err) } @@ -68,7 +82,7 @@ func (s *Student) Login() error { } // 获取token,第一个是匹配的全部字符,第二个是我们需要的 - token := regexp.MustCompile(`token=(.*?)&`).FindStringSubmatch(string(err.Error())) + token := regexp.MustCompile(`token=(.*?)&`).FindStringSubmatch(err.Error()) if len(token) < 1 { return errno.LoginCheckFailedError } @@ -82,13 +96,11 @@ func (s *Student) Login() error { }).SetFormData(map[string]string{ "token": token[1], }).Post(constants.SSOLoginURL) - if err != nil { return errno.HTTPQueryError.WithErr(err) } err = json.Unmarshal(resp.Body(), &loginResp) - if err != nil { return errno.HTTPQueryError.WithErr(err) } @@ -130,12 +142,14 @@ func (s *Student) Login() error { } // 方面服务端进行测试设置的接口 -func (s *Student) GetIdentifierAndCookies() (string, []*http.Cookie) { +func (s *Student) GetIdentifierAndCookies() (string, []*http.Cookie, error) { err := s.CheckSession() if err != nil { - s.Login() + if err := s.Login(); err != nil { + return "", nil, err + } } - return s.Identifier, s.client.Cookies + return s.Identifier, s.client.Cookies, nil } // CheckSession returns not nil if SessionExpired or AccountConflict @@ -166,7 +180,6 @@ func (s *Student) CheckSession() error { // 获取学生个人信息 func (s *Student) GetInfo() (resp *StudentDetail, err error) { res, err := s.GetWithIdentifier(constants.UserInfoURL) - if err != nil { return nil, err } diff --git a/utils/utils.go b/utils/utils.go index 8d11d38..84d4d64 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -1,3 +1,19 @@ +/* +Copyright 2024 The west2-online Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package utils import ( @@ -7,14 +23,15 @@ import ( "encoding/hex" "encoding/json" "fmt" - "golang.org/x/net/html" - "golang.org/x/text/encoding/simplifiedchinese" - "golang.org/x/text/transform" "io/ioutil" "net/http" "os" "reflect" "strconv" + + "golang.org/x/net/html" + "golang.org/x/text/encoding/simplifiedchinese" + "golang.org/x/text/transform" ) func SaveData(filePath string, data []byte) error { @@ -36,7 +53,6 @@ func SaveData(filePath string, data []byte) error { // Output struct as json format func PrintStruct(s interface{}) string { b, err := json.Marshal(s) - if err != nil { return fmt.Sprintf("%+v", s) } @@ -106,7 +122,6 @@ func StructJSONEncodeBase64(data interface{}) string { func JSONUnmarshalFromFile(filePath string, v any) error { data, err := os.ReadFile(filePath) - if err != nil { return err } @@ -134,7 +149,6 @@ func InnerTextWithBr(n *html.Node) string { func SafeAtoi(s string) int { n, err := strconv.Atoi(s) - if err != nil { return 0 } diff --git a/xpath.go b/xpath.go index 94d9ef5..8da1fda 100644 --- a/xpath.go +++ b/xpath.go @@ -1,3 +1,19 @@ +/* +Copyright 2024 The west2-online Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package jwch import ( @@ -52,5 +68,4 @@ func safeExtractHTMLFirst(node *html.Node, expr string) string { } return htmlquery.OutputHTML(res, false) - }