From 7af0fbe8f42bf8b6f9551f902f97c44f2fd71eb5 Mon Sep 17 00:00:00 2001 From: lensferno Date: Wed, 25 Jan 2023 23:13:47 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9C=AC=E7=A7=91=E7=94=9F=EF=BC=9A=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E7=BC=93=E8=80=83=E7=94=B3=E8=AF=B7=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E4=BB=A5=E5=8F=8A=E5=AD=A6=E5=88=86=E4=BF=AE=E8=AF=BB=E6=83=85?= =?UTF-8?q?=E5=86=B5=E7=9A=84=E8=AF=B7=E6=B1=82=EF=BC=9B=E5=AF=B9=E9=83=A8?= =?UTF-8?q?=E5=88=86=E6=96=B9=E6=B3=95=E9=87=8D=E8=BD=BD=E6=96=B9=E4=BE=BF?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=EF=BC=9B=E6=B7=BB=E5=8A=A0=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=AD=A6=E6=A0=A1=E7=9B=B8=E5=85=B3=E4=BF=A1=E6=81=AF=E5=8F=82?= =?UTF-8?q?=E6=95=B0=EF=BC=9B=E4=BF=9D=E7=95=99=E6=81=A2=E5=A4=8D=E6=97=A7?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E7=A7=91=E7=94=9F=E7=99=BB=E5=BD=95=E6=96=B9?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mywust/core/api/UndergradUrls.java | 164 +++++++++++++++++- .../mywust/core/exception/ApiException.java | 2 +- .../UndergradCourseTableParser.java | 7 +- .../UndergradCreditStatusIndexParser.java | 31 ++++ .../mywust/core/request/RequestFactory.java | 4 +- .../core/request/library/response/Map.java | 2 +- .../undergrade/BkjxRequestFactory.java | 60 ++++++- .../core/service/auth/LibraryLogin.java | 5 +- .../core/service/auth/UndergraduateLogin.java | 28 ++- .../graduate/GraduateApiServiceBase.java | 4 + .../UndergradApiServiceBase.java | 6 +- .../UndergradCreditStatusApiService.java | 57 ++++++ .../UndergradExamDelayApiService.java | 83 +++++++++ .../UndergradScoreApiService.java | 4 + .../UndergradStudentInfoApiService.java | 4 + .../UndergradTrainingPlanApiService.java | 4 + .../linghang/mywust/core/util/BkjxUtil.java | 2 +- .../mywust/model/global/Building.java | 32 ++++ .../linghang/mywust/model/global/Campus.java | 29 ++++ .../linghang/mywust/model/global/College.java | 29 ++++ mywust-test/pom.xml | 14 +- .../src/test/java/CourseTableTest.java | 49 ------ mywust-test/src/test/java/ExamInfoTest.java | 46 ----- mywust-test/src/test/java/JwcLoginTest.java | 45 ----- .../src/test/java/LibraryLoginTest.java | 39 ----- mywust-test/src/test/java/SchemeTest.java | 38 ---- .../src/test/java/StudentInfoPageTest.java | 39 ----- .../src/test/java/UnderGraduateTest.java | 2 - mywust-test/src/test/java/WlsyLoginTest.java | 58 ------- .../linghang/mywust/util/PasswordEncoder.java | 10 +- .../cn/linghang/mywust/util/StringUtil.java | 27 +++ pom.xml | 3 +- 32 files changed, 575 insertions(+), 352 deletions(-) create mode 100644 mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/UndergradCreditStatusIndexParser.java create mode 100644 mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/UndergradCreditStatusApiService.java create mode 100644 mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/UndergradExamDelayApiService.java create mode 100644 mywust-model/src/main/java/cn/linghang/mywust/model/global/Building.java create mode 100644 mywust-model/src/main/java/cn/linghang/mywust/model/global/Campus.java create mode 100644 mywust-model/src/main/java/cn/linghang/mywust/model/global/College.java delete mode 100644 mywust-test/src/test/java/CourseTableTest.java delete mode 100644 mywust-test/src/test/java/ExamInfoTest.java delete mode 100644 mywust-test/src/test/java/JwcLoginTest.java delete mode 100644 mywust-test/src/test/java/LibraryLoginTest.java delete mode 100644 mywust-test/src/test/java/SchemeTest.java delete mode 100644 mywust-test/src/test/java/StudentInfoPageTest.java delete mode 100644 mywust-test/src/test/java/UnderGraduateTest.java delete mode 100644 mywust-test/src/test/java/WlsyLoginTest.java diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/api/UndergradUrls.java b/mywust-core/src/main/java/cn/linghang/mywust/core/api/UndergradUrls.java index d42c5fd..2b6fa4d 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/api/UndergradUrls.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/api/UndergradUrls.java @@ -1,28 +1,188 @@ package cn.linghang.mywust.core.api; +import cn.linghang.mywust.model.global.Building; +import cn.linghang.mywust.model.global.Campus; +import cn.linghang.mywust.model.global.College; import lombok.Getter; +import java.util.*; + /** *

Bkjx(本科教学)系统对应的API常量列表(拼音咱就别吐槽了吧...)

*

其实是本科生用的教务处系统

*/ @Getter public class UndergradUrls { + /** + * 登录cookie获取url + */ public static final String BKJX_SESSION_COOKIE_API = "http://bkjx.wust.edu.cn/jsxsd/sso.jsp?ticket=%s"; + /** + * cookie测试url(空白页) + */ public static final String BKJX_TEST_API = "http://bkjx.wust.edu.cn/jsxsd/framework/blankPage.jsp"; + /** + * 学生信息url + */ public static final String BKJX_STUDENT_INFO_API = "http://bkjx.wust.edu.cn/jsxsd/grxx/xsxx"; - public static final String BKJX_EXAM_INFO_API = "http://bkjx.wust.edu.cn/jsxsd/kscj/cjcx_list"; + /** + * 成绩url + */ + public static final String BKJX_SCORE_API = "http://bkjx.wust.edu.cn/jsxsd/kscj/cjcx_list"; - public static final String BKJX_SCHEME_API = "http://bkjx.wust.edu.cn/jsxsd/pyfa/topyfamx"; + /** + * 培养计划url + */ + public static final String BKJX_TRAINING_PLAN_API = "http://bkjx.wust.edu.cn/jsxsd/pyfa/topyfamx"; + /** + * 课表url + */ public static final String BKJX_COURSE_TABLE_API = "http://bkjx.wust.edu.cn/jsxsd/xskb/xskb_list.do"; + /** + * 学分修读计划首页url + */ + public static final String BKJX_CREDIT_STATUS_INDEX_API = "http://bkjx.wust.edu.cn/jsxsd/xxwcqk/xxwcqk_idxOnzh.do"; + + /** + * 学分修读计划url + */ + public static final String BKJX_CREDIT_STATUS_API = "http://bkjx.wust.edu.cn/jsxsd/xxwcqk/xxwcqkOnzh.do"; + + /** + * 考试活动列表url + */ + public static final String BKJX_EXAM_ACTIVITY_LIST_API = "http://bkjx.wust.edu.cn/jsxsd/kscj/hksq_query_ajax?&xnxq01id=%s"; + + /** + * 缓考申请url + */ + public static final String BKJX_EXAM_DELAY_APPLICATION_LIST_API = "http://bkjx.wust.edu.cn/jsxsd/kscj/hksq_list"; + public static class Legacy { public static final String BKJX_INDEX = "http://bkjx.wust.edu.cn"; public static final String BKJX_DATA_STRING_API = "http://bkjx.wust.edu.cn/Logon.do?method=logon&flag=sess"; public static final String BKJX_SESSION_COOKIE_API = "http://bkjx.wust.edu.cn/Logon.do?method=logon"; } + + /** + * 一些需要用到的from参数,一般来说是写死固定的。 + */ + // 别慌,大部分都是脚本自动生成的代码,肯定不会是手写的。 + public static class ConstantParams { + /** + * 默认节次模式 + */ + public static final String DEFAULT_TIME_MODEL = "9486203B90F3E3CBE0532914A8C03BE2"; + + private static final List collegesTmp = new ArrayList<>(27); + public static final List COLLEGES = Collections.unmodifiableList(collegesTmp); + + static { + collegesTmp.add(new College("00001", "[01]资源与环境工程学院")); + collegesTmp.add(new College("00002", "[02]材料与冶金学院")); + collegesTmp.add(new College("00003", "[03]机械自动化学院")); + collegesTmp.add(new College("00004", "[04]信息科学与工程学院(人工智能学院)")); + collegesTmp.add(new College("00005", "[05]管理学院(恒大管理学院)")); + collegesTmp.add(new College("00006", "[06]法学与经济学院")); + collegesTmp.add(new College("00007", "[07]理学院")); + collegesTmp.add(new College("00008", "[08]城市建设学院")); + collegesTmp.add(new College("00009", "[09]医学院")); + collegesTmp.add(new College("00012", "[12]电子技术学院")); + collegesTmp.add(new College("00013", "[13]计算机科学与技术学院")); + collegesTmp.add(new College("00014", "[14]外国语学院")); + collegesTmp.add(new College("00015", "[15]体育学院(恒大足球学院)")); + collegesTmp.add(new College("0D5444D56D8A46EDB75633181B2042A7", "[16]图书馆")); + collegesTmp.add(new College("26057DF4B9354C6EA85860F1357FE8EB", "[17]工程训练中心")); + collegesTmp.add(new College("00018", "[18]生命科学与健康学院")); + collegesTmp.add(new College("00019", "[19]艺术与设计学院")); + collegesTmp.add(new College("00023", "[21]国际学院")); + collegesTmp.add(new College("00024", "[22]化学与化工学院")); + collegesTmp.add(new College("00025", "[23]汽车与交通工程学院")); + collegesTmp.add(new College("00026", "[24]临床学院")); + collegesTmp.add(new College("0W6z90XTY6", "[25]学生工作处")); + collegesTmp.add(new College("jkwHhwCHLl", "[51]马克思主义学院")); + collegesTmp.add(new College("0C4B597EE18B418B9AA5C52FDAB3EC73", "[52]香涛学院")); + collegesTmp.add(new College("379A57BA53DD4F25BA7582CE3180C077", "[54]公共卫生学院")); + collegesTmp.add(new College("9AA8C9B34EE74DEC8E02F4554B1B5125", "[60]研究生院")); + collegesTmp.add(new College("86AC446406A94EF09DE1F8B7C17F994A", "[98]全校")); + } + + private static final List campusTmp = new ArrayList<>(3); + public static final List CAMPUS = Collections.unmodifiableList(campusTmp); + + static { + campusTmp.add(new Campus("00001", "青山校区")); +// tmp.add(new Campus("00002", "洪山校区"); +// tmp.add(new Campus("00003", "医学院"); +// tmp.add(new Campus("00004", "城市学院"); +// tmp.add(new Campus("00005", "东湖教学区"); + campusTmp.add(new Campus("00006", "黄家湖校区")); + campusTmp.add(new Campus("00007", "附属医院")); +// tmp.add(new Campus("00008", "武钢医院"); + } + + /** + * 教室,目前只做了黄家湖、青山和附属医学院的数据,其他校区在制作时相关数据都是空的, + * 需要更多信息请请求相关接口获取 + */ + private static final Map> buildingTmp = new HashMap<>(3); + public static final Map> BUILDINGS = Collections.unmodifiableMap(buildingTmp); + + static { + Campus qingshan = CAMPUS.get(0); + List qingshanBuildings = new ArrayList<>(10); + qingshanBuildings.add(new Building("FE88C3D75F9C4C8CA50B82ACDF83530B", "科大雅苑C栋", qingshan)); + qingshanBuildings.add(new Building("3B76302812FD4262B8BD703814D0D8C3", "科大雅苑A栋", qingshan)); + qingshanBuildings.add(new Building("90C06D274E254A2CADC88DF1CEBD8396", "教十楼", qingshan)); + qingshanBuildings.add(new Building("00001", "主楼", qingshan)); + qingshanBuildings.add(new Building("00002", "教一楼", qingshan)); + qingshanBuildings.add(new Building("00003", "教二楼", qingshan)); + qingshanBuildings.add(new Building("00004", "教三楼", qingshan)); + qingshanBuildings.add(new Building("00005", "教四楼", qingshan)); + qingshanBuildings.add(new Building("00006", "教五楼", qingshan)); + qingshanBuildings.add(new Building("00007", "教六楼", qingshan)); + qingshanBuildings.add(new Building("00008", "图书馆", qingshan)); + qingshanBuildings.add(new Building("00009", "本部东院体育场", qingshan)); + qingshanBuildings.add(new Building("00010", "机械厂", qingshan)); + qingshanBuildings.add(new Building("00024", "本部西院体育场", qingshan)); + qingshanBuildings.add(new Building("00025", "本部北院体育场", qingshan)); + qingshanBuildings.add(new Building("00029", "教七楼", qingshan)); + qingshanBuildings.add(new Building("00031", "本部教二楼化学实验区", qingshan)); + qingshanBuildings.add(new Building("00032", "学院实验室", qingshan)); + qingshanBuildings.add(new Building("00051", "校本部停用教室", qingshan)); + buildingTmp.put(qingshan, qingshanBuildings); + + Campus huangjiahu = CAMPUS.get(1); + List huangjiahuBuildings = new ArrayList<>(10); + huangjiahuBuildings.add(new Building("D1521DE0E4CF4641AB4C49CA39EF5E47", "教八楼(管理学院)", huangjiahu)); + huangjiahuBuildings.add(new Building("FBD19C52EC3B4A93A6268B815EFA9A5A", "教九楼(汽车学院)", huangjiahu)); + huangjiahuBuildings.add(new Building("00034", "恒大楼一区", huangjiahu)); + huangjiahuBuildings.add(new Building("00035", "恒大楼二区", huangjiahu)); + huangjiahuBuildings.add(new Building("00036", "恒大楼三区", huangjiahu)); + huangjiahuBuildings.add(new Building("00037", "黄家湖校区体育场", huangjiahu)); + huangjiahuBuildings.add(new Building("00041", "黄家湖校区体育馆", huangjiahu)); + huangjiahuBuildings.add(new Building("00042", "教二楼(理学院)", huangjiahu)); + huangjiahuBuildings.add(new Building("00043", "教三楼(计算机学院)", huangjiahu)); + huangjiahuBuildings.add(new Building("00045", "教四楼二区(外国语学院)", huangjiahu)); + huangjiahuBuildings.add(new Building("00046", "教四楼一区(文法学院)", huangjiahu)); + huangjiahuBuildings.add(new Building("00048", "教五楼一区", huangjiahu)); + huangjiahuBuildings.add(new Building("00049", "教五楼二区", huangjiahu)); + huangjiahuBuildings.add(new Building("00050", "教六楼(医学院)", huangjiahu)); + huangjiahuBuildings.add(new Building("00052", "黄家湖校区停用教室", huangjiahu)); + huangjiahuBuildings.add(new Building("D29468E2AD8241769F47D82913C537EA", "黄家湖校区工程训练中心", huangjiahu)); + huangjiahuBuildings.add(new Building("F9A375E92D814DD3BC2EF30E33C4907B", "教七楼(艺术学院)", huangjiahu)); + huangjiahuBuildings.add(new Building("DFC73608380C4079A44D4215BD81EB88", "教十一楼", huangjiahu)); + buildingTmp.put(huangjiahu, huangjiahuBuildings); + + Campus medicineSchool = CAMPUS.get(2); + List medicineSchoolBuildings = new ArrayList<>(1); + medicineSchoolBuildings.add(new Building("00047", "附属医院教学楼", medicineSchool)); + buildingTmp.put(medicineSchool, medicineSchoolBuildings); + } + } } diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/exception/ApiException.java b/mywust-core/src/main/java/cn/linghang/mywust/core/exception/ApiException.java index b87798f..a70c0fa 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/exception/ApiException.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/exception/ApiException.java @@ -34,7 +34,7 @@ public class ApiException extends BasicException { @Override public String toString() { - return "接口调用异常: " + code; + return "Mywust接口调用异常: " + code + ";" + getMessage(); } public enum Code { diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/UndergradCourseTableParser.java b/mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/UndergradCourseTableParser.java index 2865630..7ef407d 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/UndergradCourseTableParser.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/UndergradCourseTableParser.java @@ -2,6 +2,7 @@ package cn.linghang.mywust.core.parser.undergraduate; import cn.linghang.mywust.core.exception.ParseException; import cn.linghang.mywust.core.parser.Parser; +import cn.linghang.mywust.core.util.JsoupUtil; import cn.linghang.mywust.model.global.ClassRoom; import cn.linghang.mywust.model.global.Course; import org.jsoup.Jsoup; @@ -68,11 +69,11 @@ public class UndergradCourseTableParser implements Parser> { Elements timeElements = courseElement.getElementsByAttributeValue("title", "周次(节次)"); Elements classroomElements = courseElement.getElementsByAttributeValue("title", "教室"); - courseBuilder.teachClass(classElements.isEmpty() ? "" : classElements.get(0).text()); - courseBuilder.teacher(teacherElements.isEmpty() ? "" : teacherElements.get(0).text()); + courseBuilder.teachClass(JsoupUtil.getElementText(classElements)); + courseBuilder.teacher(JsoupUtil.getElementText(teacherElements)); ClassRoom classRoom = new ClassRoom(); - classRoom.setRoom(classroomElements.isEmpty() ? "" : classroomElements.get(0).text()); + classRoom.setRoom(JsoupUtil.getElementText(classroomElements)); courseBuilder.classroom(classRoom); int weekDay = girdCount % 7; diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/UndergradCreditStatusIndexParser.java b/mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/UndergradCreditStatusIndexParser.java new file mode 100644 index 0000000..4fa761c --- /dev/null +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/UndergradCreditStatusIndexParser.java @@ -0,0 +1,31 @@ +package cn.linghang.mywust.core.parser.undergraduate; + +import cn.linghang.mywust.core.exception.ParseException; +import cn.linghang.mywust.core.parser.Parser; +import cn.linghang.mywust.core.util.JsoupUtil; +import cn.linghang.mywust.core.util.PageFormExtractor; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + +import java.util.HashMap; +import java.util.Map; + +public class UndergradCreditStatusIndexParser implements Parser> { + + private static final String FROM_PARAM_XPATH = "//*[@id=\"Form1\"]/table/tbody/tr/td[3]"; + @Override + public Map parse(String html) throws ParseException { + Elements paramElement = Jsoup.parse(html).selectXpath(FROM_PARAM_XPATH); + if (paramElement.isEmpty()) { + throw new ParseException("学分修读情况首页解析失败,关键元素不存在..."); + } + + Element trimmedElement = paramElement.get(0); + Elements paramElements = trimmedElement.getElementsByAttribute("name"); + Map targetMap = new HashMap<>(2); + paramElements.forEach(element -> targetMap.put(element.attr("name"), element.attr("value"))); + + return targetMap; + } +} diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/request/RequestFactory.java b/mywust-core/src/main/java/cn/linghang/mywust/core/request/RequestFactory.java index c795b23..32ac558 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/request/RequestFactory.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/request/RequestFactory.java @@ -38,10 +38,12 @@ public class RequestFactory { return makeStringDataHttpRequest(url, data, cookies).addHeaders(additionalHeaders); } + private static final byte[] ZERO_BYTE = {0}; + public static HttpRequest makeStringDataHttpRequest(String url, String stringData, String cookies) { return HttpRequest.builder() .url(makeUrl(url)) - .data(stringData.getBytes(StandardCharsets.UTF_8)) + .data(stringData == null ? null : stringData.getBytes(StandardCharsets.UTF_8)) .cookies(cookies) .build() .addHeaders(DEFAULT_HTTP_REQUEST.getHeaders()); diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/request/library/response/Map.java b/mywust-core/src/main/java/cn/linghang/mywust/core/request/library/response/Map.java index aece8f3..c4094fc 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/request/library/response/Map.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/request/library/response/Map.java @@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; @Data -public class Map { +public class Map { @JsonProperty("baseInfo") private BaseInfo baseInfo; diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/request/undergrade/BkjxRequestFactory.java b/mywust-core/src/main/java/cn/linghang/mywust/core/request/undergrade/BkjxRequestFactory.java index 57ec605..0ea1691 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/request/undergrade/BkjxRequestFactory.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/request/undergrade/BkjxRequestFactory.java @@ -2,14 +2,13 @@ package cn.linghang.mywust.core.request.undergrade; import cn.linghang.mywust.core.api.UndergradUrls; import cn.linghang.mywust.core.request.RequestFactory; +import cn.linghang.mywust.model.global.Campus; import cn.linghang.mywust.network.entitys.FormBodyBuilder; import cn.linghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.util.StringUtil; import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.Map; -import java.util.TreeMap; +import java.util.*; public class BkjxRequestFactory extends RequestFactory { public static HttpRequest sessionCookieRequest(String serviceTicket) { @@ -35,11 +34,39 @@ public class BkjxRequestFactory extends RequestFactory { formBodyBuilder.add("xsfs", "all"); byte[] postData = formBodyBuilder.buildAndToString().getBytes(StandardCharsets.UTF_8); - return makeHttpRequest(UndergradUrls.BKJX_EXAM_INFO_API, postData, cookies); + return makeHttpRequest(UndergradUrls.BKJX_SCORE_API, postData, cookies); } public static HttpRequest trainingPlanPageRequest(String cookies) { - return makeHttpRequest(UndergradUrls.BKJX_SCHEME_API, null, cookies); + return makeHttpRequest(UndergradUrls.BKJX_TRAINING_PLAN_API, null, cookies); + } + + public static HttpRequest creditStatusIndexPageRequest(String cookies) { + return makeHttpRequest(UndergradUrls.BKJX_CREDIT_STATUS_INDEX_API, null, cookies); + } + + public static HttpRequest creditStatusPageRequest(String cookies, String majorId, String teachPlainId) { + FormBodyBuilder formBodyBuilder = new FormBodyBuilder(2); + // “年度专业代码”(猜的)和“教学0301执行计划id”的参数 + formBodyBuilder.add("ndzydm", majorId).add("jx0301zxjhid", teachPlainId); + + return makeStringDataHttpRequest(UndergradUrls.BKJX_CREDIT_STATUS_API, formBodyBuilder.buildAndToString(), cookies); + } + + public static HttpRequest creditStatusPageRequest(String cookies, Map params) { + FormBodyBuilder formBodyBuilder = new FormBodyBuilder(2); + Set keys = params.keySet(); + for (String key : keys) { + formBodyBuilder.add(key, params.get(key)); + } + + return makeStringDataHttpRequest(UndergradUrls.BKJX_CREDIT_STATUS_API, formBodyBuilder.buildAndToString(), cookies); + } + + // 不带参数的学分修读情况获取,正常情况下是待带两个参数的(ndzyd和mjx0301zxjhid) + // 但是经过实际测试直接post也是可以的,也就是说post什么都是可以的 + public static HttpRequest creditStatusPageRequest(String cookies) { + return makeStringDataHttpRequest(UndergradUrls.BKJX_CREDIT_STATUS_API, "", cookies); } public static HttpRequest courseTablePageRequest(String term, String cookies) { @@ -52,6 +79,29 @@ public class BkjxRequestFactory extends RequestFactory { return makeHttpRequest(UndergradUrls.BKJX_COURSE_TABLE_API, queryData, cookies); } + public static HttpRequest examActivityListRequest(String term, String cookie) { + String url = String.format(UndergradUrls.BKJX_EXAM_ACTIVITY_LIST_API, term); + return makeHttpRequest(url, null, cookie); + } + + public static HttpRequest examDelayApplicationListRequest(String term, String activityId, String cookie) { + FormBodyBuilder formBodyBuilder = new FormBodyBuilder(4); + formBodyBuilder.add("xnxqid", term); + formBodyBuilder.add("cj0701id", activityId); + formBodyBuilder.add("kch", ""); + formBodyBuilder.add("iswfmes", ""); + + return makeStringDataHttpRequest(UndergradUrls.BKJX_EXAM_DELAY_APPLICATION_LIST_API, formBodyBuilder.buildAndToString(), cookie); + } + + public static HttpRequest buildingListRequest(String campus, String cookie) { + return null; + } + + public static HttpRequest buildingListRequest(Campus campus, String cookie) { + return buildingListRequest(campus.id, cookie); + } + public static class Legacy { public static HttpRequest dataStringRequest() { return makeHttpRequest(UndergradUrls.Legacy.BKJX_DATA_STRING_API); diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/LibraryLogin.java b/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/LibraryLogin.java index e4e06d6..8597cca 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/LibraryLogin.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/LibraryLogin.java @@ -39,7 +39,10 @@ public class LibraryLogin { } public boolean checkCookie(String cookies) throws IOException { - RequestClientOption option = RequestClientOption.DEFAULT_OPTION; + return this.checkCookie(cookies, null); + } + + public boolean checkCookie(String cookies, RequestClientOption option) throws IOException { HttpRequest testRequest = LibraryRequestFactory.makeHttpRequest(LibraryUrls.LIBRARY_COOKIE_TEST_URL, null, cookies); HttpResponse testResponse = requester.get(testRequest, option); diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/UndergraduateLogin.java b/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/UndergraduateLogin.java index bfefb1e..5fd23d3 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/UndergraduateLogin.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/UndergraduateLogin.java @@ -35,14 +35,14 @@ public class UndergraduateLogin { HttpResponse sessionResponse = requester.get(sessionRequest, requestOption); String cookies = sessionResponse.getCookies(); - if (!roughCheckCookie(cookies)) { + if (roughCheckCookieFail(cookies)) { log.error("[mywust]: Cookie粗查不通过:{}", cookies); throw new ApiException(ApiException.Code.UNKNOWN_EXCEPTION, "登录获取的Cookie无效"); } // 检查Cookie是否真正可用,同时请求一次任意接口使后续接口能够正确响应 // 拿到Cookie后调用的第一个接口会产生302/301跳转,需要再次调用才能正确响应 - if (!checkCookies(cookies, requestOption)) { + if (checkCookiesFail(cookies, requestOption)) { log.warn("[mywust]: Cookie检查不通过:{}", cookies); } @@ -89,28 +89,38 @@ public class UndergraduateLogin { HttpResponse sessionResponse = requester.get(sessionRequest, requestOption); String cookies = sessionResponse.getCookies(); - if (checkCookies(cookies, requestOption)) { - log.warn("[mywust]: Cookie检查不通过:{}", cookies); + if (roughCheckCookieFail(cookies)) { + log.error("[mywust]: Cookie粗查不通过:{}", cookies); throw new ApiException(ApiException.Code.UNKNOWN_EXCEPTION, "登录获取的Cookie无效"); } + // 检查Cookie是否真正可用,同时请求一次任意接口使后续接口能够正确响应 + // 拿到Cookie后调用的第一个接口会产生302/301跳转,需要再次调用才能正确响应 + if (checkCookiesFail(cookies, requestOption)) { + log.warn("[mywust]: Cookie检查不通过:{}", cookies); + } + return cookies; } - private boolean roughCheckCookie(String cookies) { - return cookies != null && cookies.contains("JSESSIONID") && cookies.contains("SERVERID"); + private boolean roughCheckCookieFail(String cookies) { + return cookies == null || !cookies.contains("JSESSIONID") || !cookies.contains("SERVERID"); } private static final int COOKIES_ERROR_RESPONSE_LENGTH = ("") .length(); - public boolean checkCookies(String cookies, RequestClientOption option) throws IOException { + public boolean checkCookiesFail(String cookies, RequestClientOption option) throws IOException { HttpRequest testRequest = BkjxRequestFactory.makeHttpRequest(UndergradUrls.BKJX_TEST_API, null, cookies); HttpResponse testResponse = requester.get(testRequest, option); // 判断响应长度是否为这么多个字,登录跳转响应长度 // 这种办法虽然在极端情况下可能会出错(而且还挺蠢的),但是是最快的办法中比较准确的了 - return Math.abs(COOKIES_ERROR_RESPONSE_LENGTH - testResponse.getBody().length) > 8; + return Math.abs(COOKIES_ERROR_RESPONSE_LENGTH - testResponse.getBody().length) <= 8; + } + + public boolean checkCookiesFail(String cookies) throws IOException { + return this.checkCookiesFail(cookies, null); } -} +} \ No newline at end of file diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/service/graduate/GraduateApiServiceBase.java b/mywust-core/src/main/java/cn/linghang/mywust/core/service/graduate/GraduateApiServiceBase.java index 6c7bf29..46ef5f5 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/service/graduate/GraduateApiServiceBase.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/service/graduate/GraduateApiServiceBase.java @@ -33,4 +33,8 @@ public class GraduateApiServiceBase { this.checkResponse(response); } + + public void checkCookies(String cookie) throws ApiException, IOException { + this.checkCookies(cookie, null); + } } diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/UndergradApiServiceBase.java b/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/UndergradApiServiceBase.java index 36e171c..8d2774d 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/UndergradApiServiceBase.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/UndergradApiServiceBase.java @@ -23,7 +23,7 @@ public abstract class UndergradApiServiceBase { // 检查响应是否正确 if (response.getBody() == null || response.getStatusCode() != HttpResponse.HTTP_OK || - BkjxUtil.checkLoginFinger(response.getBody())) { + BkjxUtil.hasLoginFinger(response.getBody())) { throw new ApiException(ApiException.Code.COOKIE_INVALID); } @@ -36,6 +36,10 @@ public abstract class UndergradApiServiceBase { this.checkResponse(response); } + public void checkCookies(String cookie) throws ApiException, IOException { + this.checkCookies(cookie, null); + } + public abstract String getPage(String cookie, Map params, RequestClientOption option) throws ApiException, IOException; public abstract String getPage(String cookie, Map params) throws ApiException, IOException; } diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/UndergradCreditStatusApiService.java b/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/UndergradCreditStatusApiService.java new file mode 100644 index 0000000..3085883 --- /dev/null +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/UndergradCreditStatusApiService.java @@ -0,0 +1,57 @@ +package cn.linghang.mywust.core.service.undergraduate; + +import cn.linghang.mywust.core.exception.ApiException; +import cn.linghang.mywust.core.exception.ParseException; +import cn.linghang.mywust.core.parser.undergraduate.UndergradCreditStatusIndexParser; +import cn.linghang.mywust.core.request.undergrade.BkjxRequestFactory; +import cn.linghang.mywust.network.RequestClientOption; +import cn.linghang.mywust.network.Requester; +import cn.linghang.mywust.network.entitys.HttpRequest; +import cn.linghang.mywust.network.entitys.HttpResponse; + +import java.io.IOException; +import java.util.Map; + +public class UndergradCreditStatusApiService extends UndergradApiServiceBase { + private static final UndergradCreditStatusIndexParser parser = new UndergradCreditStatusIndexParser(); + + public UndergradCreditStatusApiService(Requester requester) { + super(requester); + } + + @Override + public String getPage(String cookie, Map params, RequestClientOption option) throws ApiException, IOException { + return this.getPage(cookie, option, false); + } + + @Override + public String getPage(String cookie, Map params) throws ApiException, IOException { + return this.getPage(cookie, params, null); + } + + public String getPage(String cookie, RequestClientOption option, boolean quick) throws IOException, ApiException { + HttpRequest request; + if (quick) { + request = BkjxRequestFactory.creditStatusPageRequest(cookie); + } else { + HttpRequest indexRequest = BkjxRequestFactory.creditStatusIndexPageRequest(cookie); + HttpResponse indexResponse = requester.get(indexRequest, option); + this.checkResponse(indexResponse); + + String indexHtml = indexResponse.getStringBody(); + Map params; + try { + params = parser.parse(indexHtml); + } catch (ParseException e) { + throw new ApiException(ApiException.Code.COOKIE_INVALID); + } + + request = BkjxRequestFactory.creditStatusPageRequest(cookie, params); + } + + HttpResponse response = requester.post(request, option); + this.checkResponse(response); + + return response.getStringBody(); + } +} diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/UndergradExamDelayApiService.java b/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/UndergradExamDelayApiService.java new file mode 100644 index 0000000..0895f41 --- /dev/null +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/UndergradExamDelayApiService.java @@ -0,0 +1,83 @@ +package cn.linghang.mywust.core.service.undergraduate; + +import cn.linghang.mywust.core.exception.ApiException; +import cn.linghang.mywust.core.request.undergrade.BkjxRequestFactory; +import cn.linghang.mywust.network.RequestClientOption; +import cn.linghang.mywust.network.Requester; +import cn.linghang.mywust.network.entitys.HttpRequest; +import cn.linghang.mywust.network.entitys.HttpResponse; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; +import java.util.Map; + +/** + * 缓考申请查询 + */ +public class UndergradExamDelayApiService extends UndergradApiServiceBase { + public UndergradExamDelayApiService(Requester requester) { + super(requester); + } + + @Override + public String getPage(String cookie, Map params, RequestClientOption option) throws ApiException, IOException { + if (params == null) { + throw new ApiException(ApiException.Code.INTERNAL_EXCEPTION); + } + + String term = params.get("term"); + String activityId = params.get("activityId"); + if (term == null || activityId == null) { + throw new ApiException(ApiException.Code.INTERNAL_EXCEPTION); + } + + return this.getPage(term, activityId, cookie, option); + } + + @Override + public String getPage(String cookie, Map params) throws ApiException, IOException { + return this.getPage(cookie, params, null); + } + + public String getPage(String term, String activityId, String cookie, RequestClientOption option) throws ApiException, IOException { + HttpRequest request = BkjxRequestFactory.examDelayApplicationListRequest(term, activityId, cookie); + HttpResponse response = requester.post(request, option); + this.checkResponse(response); + + return request.getStringData(); + } + + public String getPage(String term, String activityId, String cookie) throws ApiException, IOException { + return this.getPage(term, activityId, cookie, null); + } + + public ExamActivity[] getActivities(String term, String cookie, RequestClientOption option) throws ApiException, IOException { + HttpRequest request = BkjxRequestFactory.examActivityListRequest(term, cookie); + HttpResponse response = requester.get(request, option); + this.checkResponse(response); + + try { + return new ObjectMapper().readValue(response.getBody(), ExamActivity[].class); + } catch (IOException e) { + throw new ApiException(ApiException.Code.UNKNOWN_EXCEPTION, "解析考试活动id列表失败:响应数据:" + response.getStringBody()); + } + } + + public ExamActivity[] getActivities(String term, String cookie) throws ApiException, IOException { + return this.getActivities(term, cookie, null); + } + + public static class ExamActivity { + @JsonProperty("cj0701id") + public final String id; + + @JsonProperty("cjlrmc") + public final String name; + + public ExamActivity(String id, String name) { + this.id = id; + this.name = name; + } + } +} diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/UndergradScoreApiService.java b/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/UndergradScoreApiService.java index 3ba22ee..66bb029 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/UndergradScoreApiService.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/UndergradScoreApiService.java @@ -34,4 +34,8 @@ public class UndergradScoreApiService extends UndergradApiServiceBase { return new String(response.getBody()); } + + public String getPage(String cookies) throws IOException, ApiException { + return this.getPage(cookies, (RequestClientOption) null); + } } diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/UndergradStudentInfoApiService.java b/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/UndergradStudentInfoApiService.java index 82e6624..6f38b92 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/UndergradStudentInfoApiService.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/UndergradStudentInfoApiService.java @@ -34,4 +34,8 @@ public class UndergradStudentInfoApiService extends UndergradApiServiceBase { return new String(response.getBody()); } + + public String getPage(String cookies) throws IOException, ApiException { + return this.getPage(cookies, (RequestClientOption) null); + } } diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/UndergradTrainingPlanApiService.java b/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/UndergradTrainingPlanApiService.java index 7d784fe..3ff66dc 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/UndergradTrainingPlanApiService.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/UndergradTrainingPlanApiService.java @@ -34,4 +34,8 @@ public class UndergradTrainingPlanApiService extends UndergradApiServiceBase { return new String(response.getBody()); } + + public String getPage(String cookies) throws IOException, ApiException { + return this.getPage(cookies, (RequestClientOption) null); + } } diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/util/BkjxUtil.java b/mywust-core/src/main/java/cn/linghang/mywust/core/util/BkjxUtil.java index 4bc13ac..964af17 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/util/BkjxUtil.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/util/BkjxUtil.java @@ -16,7 +16,7 @@ public class BkjxUtil { * @param response 响应的字节 * @return 是否需要重新登录 */ - public static boolean checkLoginFinger(byte[] response) { + public static boolean hasLoginFinger(byte[] response) { if (response == null) { return false; } diff --git a/mywust-model/src/main/java/cn/linghang/mywust/model/global/Building.java b/mywust-model/src/main/java/cn/linghang/mywust/model/global/Building.java new file mode 100644 index 0000000..686db24 --- /dev/null +++ b/mywust-model/src/main/java/cn/linghang/mywust/model/global/Building.java @@ -0,0 +1,32 @@ +package cn.linghang.mywust.model.global; + +import java.util.StringJoiner; + +public final class Building { + public final String id; + public final String name; + public final Campus campus; + + public Building(String id, String name, Campus campus) { + this.id = id; + this.name = name; + this.campus = campus; + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } + + @Override + public String toString() { + return new StringJoiner(", ", Building.class.getSimpleName() + "[", "]") + .add("id='" + id + "'") + .add("name='" + name + "'") + .add("campus=" + campus) + .toString(); + } +} diff --git a/mywust-model/src/main/java/cn/linghang/mywust/model/global/Campus.java b/mywust-model/src/main/java/cn/linghang/mywust/model/global/Campus.java new file mode 100644 index 0000000..1bfb696 --- /dev/null +++ b/mywust-model/src/main/java/cn/linghang/mywust/model/global/Campus.java @@ -0,0 +1,29 @@ +package cn.linghang.mywust.model.global; + +import java.util.StringJoiner; + +public final class Campus { + public final String id; + public final String name; + + public Campus(String id, String name) { + this.id = id; + this.name = name; + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } + + @Override + public String toString() { + return new StringJoiner(", ", Campus.class.getSimpleName() + "[", "]") + .add("id='" + id + "'") + .add("name='" + name + "'") + .toString(); + } +} diff --git a/mywust-model/src/main/java/cn/linghang/mywust/model/global/College.java b/mywust-model/src/main/java/cn/linghang/mywust/model/global/College.java new file mode 100644 index 0000000..a127f1e --- /dev/null +++ b/mywust-model/src/main/java/cn/linghang/mywust/model/global/College.java @@ -0,0 +1,29 @@ +package cn.linghang.mywust.model.global; + +import java.util.StringJoiner; + +public final class College { + public final String id; + public final String name; + + public College(String id, String name) { + this.id = id; + this.name = name; + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } + + @Override + public String toString() { + return new StringJoiner(", ", College.class.getSimpleName() + "[", "]") + .add("id='" + id + "'") + .add("name='" + name + "'") + .toString(); + } +} diff --git a/mywust-test/pom.xml b/mywust-test/pom.xml index 0f52487..35887c8 100644 --- a/mywust-test/pom.xml +++ b/mywust-test/pom.xml @@ -4,20 +4,25 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - cn.linghang + + cn.linghang + mywust + ${revision} + + mywust-test - 1.0-SNAPSHOT + cn.linghang mywust-core - 0.0.1-SNAPSHOT + ${project.parent.version} test cn.linghang mywust-network-okhttp - 1.0-SNAPSHOT + ${project.parent.version} test @@ -57,7 +62,6 @@ test - diff --git a/mywust-test/src/test/java/CourseTableTest.java b/mywust-test/src/test/java/CourseTableTest.java deleted file mode 100644 index 96862fc..0000000 --- a/mywust-test/src/test/java/CourseTableTest.java +++ /dev/null @@ -1,49 +0,0 @@ -import cn.linghang.mywust.core.exception.BasicException; -import cn.linghang.mywust.core.parser.Parser; -import cn.linghang.mywust.core.parser.undergraduate.CourseTableParser; -import cn.linghang.mywust.core.service.undergraduate.CourseTableApiService; -import cn.linghang.mywust.model.global.Course; -import cn.linghang.mywust.network.RequestClientOption; -import cn.linghang.mywust.network.Requester; -import cn.linghang.mywust.network.okhttp.SimpleOkhttpRequester; -import org.junit.jupiter.api.Test; - -import java.io.IOException; -import java.util.List; -import java.util.Scanner; - -public class CourseTableTest { - @Test - public void run() throws BasicException, IOException { - System.out.println("课表"); - System.out.println("Cookie:"); - - Scanner scanner = new Scanner(System.in); - - String cookie = scanner.nextLine(); - - System.out.println("使用Cookie:" + cookie); - - System.out.println("学期(如2022-2023-1):"); - String term = scanner.nextLine(); - System.out.println("使用学期:" + term); - - Requester requester = new SimpleOkhttpRequester(); - CourseTableApiService service = new CourseTableApiService(requester); - - RequestClientOption option = new RequestClientOption(); - option.setTimeout(5); - RequestClientOption.Proxy proxy = new RequestClientOption.Proxy(); - proxy.setPort(6060); - proxy.setAddress("127.0.0.1"); - option.setProxy(proxy); - option.setFallowUrlRedirect(false); - - Parser> parser = new CourseTableParser(); - List courses = parser.parse(service.getCourseTablePage(term, cookie, option)); - - for (Course info : courses) { - System.out.println(info); - } - } -} diff --git a/mywust-test/src/test/java/ExamInfoTest.java b/mywust-test/src/test/java/ExamInfoTest.java deleted file mode 100644 index cddbb56..0000000 --- a/mywust-test/src/test/java/ExamInfoTest.java +++ /dev/null @@ -1,46 +0,0 @@ -import cn.linghang.mywust.core.exception.BasicException; -import cn.linghang.mywust.core.parser.Parser; -import cn.linghang.mywust.core.parser.undergraduate.ExamInfoParser; -import cn.linghang.mywust.core.service.undergraduate.ExamInfoApiService; -import cn.linghang.mywust.model.global.ExamInfo; -import cn.linghang.mywust.network.RequestClientOption; -import cn.linghang.mywust.network.Requester; -import cn.linghang.mywust.network.okhttp.SimpleOkhttpRequester; -import org.junit.jupiter.api.Test; - -import java.io.IOException; -import java.util.List; -import java.util.Scanner; - -public class ExamInfoTest { - @Test - public void run() throws BasicException, IOException { - System.out.println("成绩获取"); - System.out.println("Cookie:"); - - Scanner scanner = new Scanner(System.in); - - String cookie = scanner.nextLine(); - - System.out.println("使用Cookie:" + cookie); - - Requester requester = new SimpleOkhttpRequester(); - ExamInfoApiService jwcService = new ExamInfoApiService(requester); - - RequestClientOption option = new RequestClientOption(); - option.setTimeout(5); - RequestClientOption.Proxy proxy = new RequestClientOption.Proxy(); - proxy.setPort(8080); - proxy.setAddress("127.0.0.1"); - option.setProxy(proxy); - option.setFallowUrlRedirect(false); - - Parser> parser = new ExamInfoParser(); - List infos = parser.parse(jwcService.getExamInfoPage(cookie, option)); - - for (ExamInfo info : infos) { - - System.out.println(info); - } - } -} diff --git a/mywust-test/src/test/java/JwcLoginTest.java b/mywust-test/src/test/java/JwcLoginTest.java deleted file mode 100644 index a59dc69..0000000 --- a/mywust-test/src/test/java/JwcLoginTest.java +++ /dev/null @@ -1,45 +0,0 @@ -import cn.linghang.mywust.core.exception.BasicException; -import cn.linghang.mywust.core.service.auth.UnionLogin; -import cn.linghang.mywust.core.service.auth.JwcLogin; -import cn.linghang.mywust.network.RequestClientOption; -import cn.linghang.mywust.network.Requester; -import cn.linghang.mywust.network.okhttp.SimpleOkhttpRequester; -import org.junit.jupiter.api.Test; - -import java.io.IOException; -import java.util.Scanner; - -public class JwcLoginTest { - @Test - public void run() throws BasicException, IOException { - System.out.println("bkjx登录测试(统一身份验证)"); - System.out.println("输入账号(学号)和密码,用“ ”(空格)分割"); - - Scanner scanner = new Scanner(System.in); - - String input = scanner.nextLine(); - - String username = input.split(" ")[0]; - String password = input.split(" ")[1]; - - System.out.println("账号:" + username); - System.out.println("密码:" + password); - - Requester requester = new SimpleOkhttpRequester(); - JwcLogin jwcLogin = new JwcLogin(requester); - - RequestClientOption option = new RequestClientOption(); - option.setTimeout(5); - option.setFallowUrlRedirect(false); - RequestClientOption.Proxy proxy = new RequestClientOption.Proxy(); - proxy.setPort(6060); - proxy.setAddress("127.0.0.1"); - option.setProxy(proxy); - - String cookies = jwcLogin.getLoginCookie(username, password, option); - - System.out.printf("获取到Cookies: %s \n", cookies); - - System.out.printf("检查Cookies: %s", jwcLogin.checkCookies(cookies, RequestClientOption.DEFAULT_OPTION)); - } -} diff --git a/mywust-test/src/test/java/LibraryLoginTest.java b/mywust-test/src/test/java/LibraryLoginTest.java deleted file mode 100644 index 0356d4a..0000000 --- a/mywust-test/src/test/java/LibraryLoginTest.java +++ /dev/null @@ -1,39 +0,0 @@ -import cn.linghang.mywust.core.exception.BasicException; -import cn.linghang.mywust.core.service.auth.UnionLogin; -import cn.linghang.mywust.core.service.auth.LibraryLogin; -import cn.linghang.mywust.network.RequestClientOption; -import cn.linghang.mywust.network.Requester; -import cn.linghang.mywust.network.okhttp.SimpleOkhttpRequester; -import org.junit.jupiter.api.Test; - -import java.io.IOException; -import java.util.Scanner; - -public class LibraryLoginTest { - @Test - public void run() throws BasicException, IOException { - System.out.println("图书馆登陆测试"); - System.out.println("输入账号(学号)和密码,用“ ”(空格)分割"); - - Scanner scanner = new Scanner(System.in); - - String input = scanner.nextLine(); - - String username = input.split(" ")[0]; - String password = input.split(" ")[1]; - - System.out.println("账号:" + username); - System.out.println("密码:" + password); - - Requester requester = new SimpleOkhttpRequester(); - LibraryLogin libraryLogin = new LibraryLogin(requester); - - RequestClientOption option = RequestClientOption.DEFAULT_OPTION; - - String cookies = libraryLogin.getLibraryLoginCookie(username, password, option); - - System.out.printf("获取到的cookies: %s \n", cookies); - - System.out.printf("检查Cookies: %s", libraryLogin.checkCookie(cookies)); - } -} diff --git a/mywust-test/src/test/java/SchemeTest.java b/mywust-test/src/test/java/SchemeTest.java deleted file mode 100644 index 409f62b..0000000 --- a/mywust-test/src/test/java/SchemeTest.java +++ /dev/null @@ -1,38 +0,0 @@ -import cn.linghang.mywust.core.exception.BasicException; -import cn.linghang.mywust.core.service.undergraduate.TrainingPlanApiService; -import cn.linghang.mywust.network.RequestClientOption; -import cn.linghang.mywust.network.Requester; -import cn.linghang.mywust.network.okhttp.SimpleOkhttpRequester; -import org.junit.jupiter.api.Test; - -import java.io.IOException; -import java.util.Scanner; - -public class SchemeTest { - @Test - public void run() throws BasicException, IOException { - System.out.println("培养方案获取"); - System.out.println("Cookie:"); - - Scanner scanner = new Scanner(System.in); - - String cookie = scanner.nextLine(); - - System.out.println("使用Cookie:" + cookie); - - RequestClientOption option = new RequestClientOption(); - option.setTimeout(5); - RequestClientOption.Proxy proxy = new RequestClientOption.Proxy(); - proxy.setPort(6060); - proxy.setAddress("127.0.0.1"); - option.setProxy(null); - option.setFallowUrlRedirect(false); - - Requester requester = new SimpleOkhttpRequester(); - TrainingPlanApiService jwcService = new TrainingPlanApiService(requester); - - String page = jwcService.getTrainingPlanPage(cookie, option); - - System.out.println(page); - } -} diff --git a/mywust-test/src/test/java/StudentInfoPageTest.java b/mywust-test/src/test/java/StudentInfoPageTest.java deleted file mode 100644 index 4b1a8ff..0000000 --- a/mywust-test/src/test/java/StudentInfoPageTest.java +++ /dev/null @@ -1,39 +0,0 @@ -import cn.linghang.mywust.core.exception.BasicException; -import cn.linghang.mywust.core.parser.Parser; -import cn.linghang.mywust.core.parser.undergraduate.StudentInfoPageParser; -import cn.linghang.mywust.core.service.undergraduate.StudentInfoApiService; -import cn.linghang.mywust.model.global.StudentInfo; -import cn.linghang.mywust.network.RequestClientOption; -import cn.linghang.mywust.network.Requester; -import cn.linghang.mywust.network.okhttp.SimpleOkhttpRequester; -import org.junit.jupiter.api.Test; - -import java.io.IOException; -import java.util.Scanner; - -public class StudentInfoPageTest { - @Test - public void run() throws BasicException, IOException { - System.out.println("学生信息获取"); - System.out.println("Cookie:"); - - Scanner scanner = new Scanner(System.in); - - String cookie = scanner.nextLine(); - - System.out.println("使用Cookie:" + cookie); - - Requester requester = new SimpleOkhttpRequester(); - StudentInfoApiService jwcService = new StudentInfoApiService(requester); - - RequestClientOption option = new RequestClientOption(); - option.setTimeout(5); - option.setProxy(null); - option.setFallowUrlRedirect(false); - - Parser parser = new StudentInfoPageParser(); - StudentInfo info = parser.parse(jwcService.getStudentInfoPage(cookie, option)); - - System.out.println(info); - } -} diff --git a/mywust-test/src/test/java/UnderGraduateTest.java b/mywust-test/src/test/java/UnderGraduateTest.java deleted file mode 100644 index 935f602..0000000 --- a/mywust-test/src/test/java/UnderGraduateTest.java +++ /dev/null @@ -1,2 +0,0 @@ -public class UnderGraduateTest { -} diff --git a/mywust-test/src/test/java/WlsyLoginTest.java b/mywust-test/src/test/java/WlsyLoginTest.java deleted file mode 100644 index 495fe40..0000000 --- a/mywust-test/src/test/java/WlsyLoginTest.java +++ /dev/null @@ -1,58 +0,0 @@ -import cn.linghang.mywust.core.exception.BasicException; -import cn.linghang.mywust.core.parser.Parser; -import cn.linghang.mywust.core.parser.physics.PhysicsCoursePageParser; -import cn.linghang.mywust.core.service.auth.PhysicsLogin; -import cn.linghang.mywust.core.service.physics.PhysicsApiService; -import cn.linghang.mywust.model.global.Course; -import cn.linghang.mywust.model.physics.PhysicsCourse; -import cn.linghang.mywust.network.RequestClientOption; -import cn.linghang.mywust.network.Requester; -import cn.linghang.mywust.network.okhttp.SimpleOkhttpRequester; -import org.junit.jupiter.api.Test; - -import java.io.IOException; -import java.util.List; -import java.util.Scanner; - -public class WlsyLoginTest { - @Test - public void run() throws BasicException, IOException { - System.out.println("物理实验登陆测试"); - System.out.println("输入账号(学号)和密码,用“ ”(空格)分割"); - - Scanner scanner = new Scanner(System.in); - - String input = scanner.nextLine(); - - String username = input.split(" ")[0]; - String password = input.split(" ")[1]; - - System.out.println("账号:" + username); - System.out.println("密码:" + password); - - Requester requester = new SimpleOkhttpRequester(); - PhysicsLogin physicsLogin = new PhysicsLogin(requester); - - RequestClientOption option = RequestClientOption.DEFAULT_OPTION; - RequestClientOption.Proxy proxy = new RequestClientOption.Proxy(); - proxy.setAddress("127.0.0.1"); - proxy.setPort(8080); - option.setProxy(proxy); - - String cookies = physicsLogin.getLoginCookie(username, password, option); - - System.out.printf("获取到的cookies: %s \n", cookies); - - option.setFallowUrlRedirect(false); - PhysicsApiService api = new PhysicsApiService(requester); - String response = api.getCoursePage(cookies, option); - System.out.println(response); - - Parser> parser = new PhysicsCoursePageParser(); - List courses = parser.parse(response); - - for (Course info : courses) { - System.out.println(info); - } - } -} diff --git a/mywust-util/src/main/java/cn/linghang/mywust/util/PasswordEncoder.java b/mywust-util/src/main/java/cn/linghang/mywust/util/PasswordEncoder.java index 3c4fe7e..66f17c3 100644 --- a/mywust-util/src/main/java/cn/linghang/mywust/util/PasswordEncoder.java +++ b/mywust-util/src/main/java/cn/linghang/mywust/util/PasswordEncoder.java @@ -115,7 +115,7 @@ public class PasswordEncoder { */ public static String legacyPassword(String username, String password, String dataString) { String[] parts = dataString.split("#"); - String scode = parts[0]; + StringBuilder scode = new StringBuilder(parts[0]); String sxh = parts[1]; String code = username + "%%%" + password; @@ -123,11 +123,11 @@ public class PasswordEncoder { StringBuilder encoded = new StringBuilder(); for (int i = 0, codeLength = code.length(); i < codeLength; i++) { if (i < 20) { - int endIndex = parseInt(sxh.substring(i, i + 1)); - encoded.append(code.charAt(i)).append(scode, 0, endIndex); - scode = scode.substring(endIndex); + int index = sxh.charAt(i) - 48; + encoded.append(code.charAt(i)).append(scode, 0, index); + scode.delete(0, index); } else { - encoded.append(code.substring(i)); + encoded.append(code, i, codeLength); i = codeLength; } } diff --git a/mywust-util/src/main/java/cn/linghang/mywust/util/StringUtil.java b/mywust-util/src/main/java/cn/linghang/mywust/util/StringUtil.java index c4e7fca..a0ffcbb 100644 --- a/mywust-util/src/main/java/cn/linghang/mywust/util/StringUtil.java +++ b/mywust-util/src/main/java/cn/linghang/mywust/util/StringUtil.java @@ -70,4 +70,31 @@ public class StringUtil { return Base64.encodeBase64String(rawText.toString().getBytes(StandardCharsets.UTF_8)); } + + public static String NoneNullString(String str) { + return str == null ? "" : str; + } + + public static String getTermString(Date date, boolean autumn) { + Calendar calendar = new GregorianCalendar(); + calendar.setTime(date); + + return getTermString(calendar, autumn); + } + + public static String getTermString(Calendar calendar, boolean autumn) { + int year = calendar.get(Calendar.YEAR); + int nextYear = year + 1; + + // 秋季期,就是第一个学期 + return String.format("%d-%d-%s", year, nextYear, autumn ? "1" : "2"); + } + + public static String getCurrentTermString() { + Calendar now = Calendar.getInstance(); + int month = now.get(Calendar.MONTH); + + // 一般八月到第二年二月算是是秋季期 + return getTermString(now, month >= 8 || month < 2); + } } diff --git a/pom.xml b/pom.xml index b207c4f..858f918 100644 --- a/pom.xml +++ b/pom.xml @@ -14,6 +14,7 @@ mywust-model mywust-network mywust-util + mywust-test mywust-network-httpclient mywust-network-okhttp @@ -28,7 +29,7 @@ - 0.0.1-fixed + 0.0.2-SNAPSHOT 1.18.22