Compare commits

..

No commits in common. 'main' and 'old-package' have entirely different histories.

  1. 24
      README.md
  2. 41
      mywust-common/pom.xml
  3. 3
      mywust-common/src/main/java/cn/linghang/mywust/captcha/SolvedImageCaptcha.java
  4. 2
      mywust-common/src/main/java/cn/linghang/mywust/captcha/UnsolvedImageCaptcha.java
  5. 2
      mywust-common/src/main/java/cn/linghang/mywust/data/global/Building.java
  6. 2
      mywust-common/src/main/java/cn/linghang/mywust/data/global/Campus.java
  7. 2
      mywust-common/src/main/java/cn/linghang/mywust/data/global/Classroom.java
  8. 2
      mywust-common/src/main/java/cn/linghang/mywust/data/global/College.java
  9. 2
      mywust-common/src/main/java/cn/linghang/mywust/data/global/Course.java
  10. 2
      mywust-common/src/main/java/cn/linghang/mywust/data/global/Score.java
  11. 2
      mywust-common/src/main/java/cn/linghang/mywust/data/global/StudentInfo.java
  12. 4
      mywust-common/src/main/java/cn/linghang/mywust/data/physics/PhysicsCourse.java
  13. 2
      mywust-common/src/main/java/cn/linghang/mywust/data/undergrad/ExamDelayApplication.java
  14. 21
      mywust-common/src/main/java/cn/linghang/mywust/exception/ApiException.java
  15. 2
      mywust-common/src/main/java/cn/linghang/mywust/exception/BasicException.java
  16. 2
      mywust-common/src/main/java/cn/linghang/mywust/exception/ParseException.java
  17. 20
      mywust-common/src/main/java/cn/wustlinghang/mywust/data/library/PagingResult.java
  18. 61
      mywust-common/src/main/java/cn/wustlinghang/mywust/data/library/origin/BaseLoanBook.java
  19. 67
      mywust-common/src/main/java/cn/wustlinghang/mywust/data/library/origin/BookSearchRequest.java
  20. 80
      mywust-common/src/main/java/cn/wustlinghang/mywust/data/library/origin/BookSearchResult.java
  21. 12
      mywust-common/src/main/java/cn/wustlinghang/mywust/data/library/origin/CurrentLoanBook.java
  22. 12
      mywust-common/src/main/java/cn/wustlinghang/mywust/data/library/origin/HistoryLoanBook.java
  23. 51
      mywust-common/src/main/java/cn/wustlinghang/mywust/data/library/parsed/BookDetail.java
  24. 56
      mywust-common/src/main/java/cn/wustlinghang/mywust/data/library/parsed/BookHolding.java
  25. 69
      mywust-common/src/main/java/cn/wustlinghang/mywust/data/library/parsed/BookSearchResult.java
  26. 46
      mywust-core/pom.xml
  27. 2
      mywust-core/src/main/java/cn/linghang/mywust/core/api/ConstantParams.java
  28. 2
      mywust-core/src/main/java/cn/linghang/mywust/core/api/GraduateUrls.java
  29. 14
      mywust-core/src/main/java/cn/linghang/mywust/core/api/LibraryUrls.java
  30. 2
      mywust-core/src/main/java/cn/linghang/mywust/core/api/PhysicsSystemUrls.java
  31. 2
      mywust-core/src/main/java/cn/linghang/mywust/core/api/UndergradUrls.java
  32. 2
      mywust-core/src/main/java/cn/linghang/mywust/core/api/UnionAuthUrls.java
  33. 6
      mywust-core/src/main/java/cn/linghang/mywust/core/parser/HuangjiahuClassroomNameParser.java
  34. 7
      mywust-core/src/main/java/cn/linghang/mywust/core/parser/Parser.java
  35. 10
      mywust-core/src/main/java/cn/linghang/mywust/core/parser/graduate/GraduateCourseTableParser.java
  36. 8
      mywust-core/src/main/java/cn/linghang/mywust/core/parser/graduate/GraduateScoreParser.java
  37. 10
      mywust-core/src/main/java/cn/linghang/mywust/core/parser/graduate/GraduateStudentInfoPageParser.java
  38. 13
      mywust-core/src/main/java/cn/linghang/mywust/core/parser/graduate/GraduateTrainingPlanPageParser.java
  39. 12
      mywust-core/src/main/java/cn/linghang/mywust/core/parser/physics/PhysicsCoursePageParser.java
  40. 6
      mywust-core/src/main/java/cn/linghang/mywust/core/parser/physics/PhysicsIndexPageParser.java
  41. 8
      mywust-core/src/main/java/cn/linghang/mywust/core/parser/physics/PhysicsScoreListPageParser.java
  42. 10
      mywust-core/src/main/java/cn/linghang/mywust/core/parser/physics/PhysicsScorePageParser.java
  43. 16
      mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/UndergradCourseTableParser.java
  44. 6
      mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/UndergradCreditStatusIndexParser.java
  45. 6
      mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/UndergradCreditStatusParser.java
  46. 10
      mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/UndergradExamDelayParser.java
  47. 10
      mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/UndergradScoreParser.java
  48. 10
      mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/UndergradStudentInfoPageParser.java
  49. 6
      mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/UndergradTrainingPlanPageParser.java
  50. 10
      mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/global/GlobalCourseTableParser.java
  51. 8
      mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/global/UndergradAllCourseScheduleParser.java
  52. 8
      mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/global/UndergradTeacherCourseParser.java
  53. 10
      mywust-core/src/main/java/cn/linghang/mywust/core/request/factory/RequestFactory.java
  54. 10
      mywust-core/src/main/java/cn/linghang/mywust/core/request/factory/auth/UnionAuthRequestFactory.java
  55. 16
      mywust-core/src/main/java/cn/linghang/mywust/core/request/factory/graduate/GraduateRequestFactory.java
  56. 47
      mywust-core/src/main/java/cn/linghang/mywust/core/request/factory/library/LibraryRequestFactory.java
  57. 40
      mywust-core/src/main/java/cn/linghang/mywust/core/request/factory/library/request/SearchRequest.java
  58. 16
      mywust-core/src/main/java/cn/linghang/mywust/core/request/factory/physics/PhysicsSystemRequestFactory.java
  59. 15
      mywust-core/src/main/java/cn/linghang/mywust/core/request/factory/undergrade/BkjxRequestFactory.java
  60. 16
      mywust-core/src/main/java/cn/linghang/mywust/core/request/factory/undergrade/global/BkjxAllCourseRequestFactory.java
  61. 57
      mywust-core/src/main/java/cn/linghang/mywust/core/request/service/auth/GraduateLogin.java
  62. 27
      mywust-core/src/main/java/cn/linghang/mywust/core/request/service/auth/LibraryLogin.java
  63. 36
      mywust-core/src/main/java/cn/linghang/mywust/core/request/service/auth/PhysicsLogin.java
  64. 60
      mywust-core/src/main/java/cn/linghang/mywust/core/request/service/auth/UndergraduateLogin.java
  65. 16
      mywust-core/src/main/java/cn/linghang/mywust/core/request/service/auth/UnionLogin.java
  66. 9
      mywust-core/src/main/java/cn/linghang/mywust/core/request/service/captcha/solver/CaptchaSolver.java
  67. 18
      mywust-core/src/main/java/cn/linghang/mywust/core/request/service/captcha/solver/DdddOcrCaptchaSolver.java
  68. 22
      mywust-core/src/main/java/cn/linghang/mywust/core/request/service/captcha/solver/LinghangOcrServiceCaptchaSolver.java
  69. 18
      mywust-core/src/main/java/cn/linghang/mywust/core/request/service/graduate/GraduateApiServiceBase.java
  70. 16
      mywust-core/src/main/java/cn/linghang/mywust/core/request/service/graduate/GraduateCourseTableApiService.java
  71. 16
      mywust-core/src/main/java/cn/linghang/mywust/core/request/service/graduate/GraduateScoreApiService.java
  72. 16
      mywust-core/src/main/java/cn/linghang/mywust/core/request/service/graduate/GraduateStudentInfoApiService.java
  73. 16
      mywust-core/src/main/java/cn/linghang/mywust/core/request/service/graduate/GraduateTrainingPlanApiService.java
  74. 66
      mywust-core/src/main/java/cn/linghang/mywust/core/request/service/library/LibraryApiService.java
  75. 20
      mywust-core/src/main/java/cn/linghang/mywust/core/request/service/library/LibraryApiServiceBase.java
  76. 8
      mywust-core/src/main/java/cn/linghang/mywust/core/request/service/physics/PhysicsApiServiceBase.java
  77. 16
      mywust-core/src/main/java/cn/linghang/mywust/core/request/service/physics/PhysicsCourseApiService.java
  78. 22
      mywust-core/src/main/java/cn/linghang/mywust/core/request/service/physics/PhysicsScoreApiService.java
  79. 27
      mywust-core/src/main/java/cn/linghang/mywust/core/request/service/undergraduate/UndergradApiServiceBase.java
  80. 16
      mywust-core/src/main/java/cn/linghang/mywust/core/request/service/undergraduate/UndergradCourseTableApiService.java
  81. 20
      mywust-core/src/main/java/cn/linghang/mywust/core/request/service/undergraduate/UndergradCreditStatusApiService.java
  82. 14
      mywust-core/src/main/java/cn/linghang/mywust/core/request/service/undergraduate/UndergradExamDelayApiService.java
  83. 16
      mywust-core/src/main/java/cn/linghang/mywust/core/request/service/undergraduate/UndergradScoreApiService.java
  84. 16
      mywust-core/src/main/java/cn/linghang/mywust/core/request/service/undergraduate/UndergradStudentInfoApiService.java
  85. 16
      mywust-core/src/main/java/cn/linghang/mywust/core/request/service/undergraduate/UndergradTrainingPlanApiService.java
  86. 18
      mywust-core/src/main/java/cn/linghang/mywust/core/request/service/undergraduate/global/UndergradAllCourseScheduleApiService.java
  87. 24
      mywust-core/src/main/java/cn/linghang/mywust/core/request/service/undergraduate/global/UndergradBuildingIdApiService.java
  88. 18
      mywust-core/src/main/java/cn/linghang/mywust/core/request/service/undergraduate/global/UndergradClassroomCourseApiService.java
  89. 18
      mywust-core/src/main/java/cn/linghang/mywust/core/request/service/undergraduate/global/UndergradTeacherCourseApiService.java
  90. 32
      mywust-core/src/main/java/cn/linghang/mywust/core/util/BkjxUtil.java
  91. 2
      mywust-core/src/main/java/cn/linghang/mywust/core/util/JsoupUtil.java
  92. 2
      mywust-core/src/main/java/cn/linghang/mywust/core/util/PageFormExtractor.java
  93. 7
      mywust-core/src/main/java/cn/wustlinghang/mywust/core/parser/Parser.java
  94. 9
      mywust-core/src/main/java/cn/wustlinghang/mywust/core/request/service/captcha/solver/CaptchaSolver.java
  95. 82
      mywust-core/src/main/java/cn/wustlinghang/mywust/core/request/service/library/BaseLibraryApiService.java
  96. 59
      mywust-core/src/main/java/cn/wustlinghang/mywust/core/request/service/library/BookCoverImageUrlApiService.java
  97. 70
      mywust-core/src/main/java/cn/wustlinghang/mywust/core/request/service/library/BookDetailApiService.java
  98. 39
      mywust-core/src/main/java/cn/wustlinghang/mywust/core/request/service/library/BookHoldingApiService.java
  99. 52
      mywust-core/src/main/java/cn/wustlinghang/mywust/core/request/service/library/CurrentLoanApiService.java
  100. 53
      mywust-core/src/main/java/cn/wustlinghang/mywust/core/request/service/library/LoanHistoryApiService.java
  101. Some files were not shown because too many files have changed in this diff Show More

@ -6,7 +6,7 @@
核心代码来自武科大助手后端爬虫模块,在此基础上进行部分修改以适用于各种平台,因此不会使用重量级的框架,尽量保证仅使用原生java或jvm兼容的语言即可使用,是一个比较~~轻量~~的库 核心代码来自武科大助手后端爬虫模块,在此基础上进行部分修改以适用于各种平台,因此不会使用重量级的框架,尽量保证仅使用原生java或jvm兼容的语言即可使用,是一个比较~~轻量~~的库
由于处在早期阶段,因此项目结构以及外部接口随时可能发生巨大变化,在正式版出来前请勿重度依赖,当前仅作为算法以及处理过程参考使用 由于处在早期阶段,因此项目结构随时可能发生巨大变化,在正式版出来前请勿重度依赖
后续可能会根据需要新增其他语言的实现以提供给其他语言和平台的使用 后续可能会根据需要新增其他语言的实现以提供给其他语言和平台的使用
@ -35,11 +35,6 @@
- 成绩查询 - 成绩查询
- 图书馆 - 图书馆
- 登录 - 登录
- 图书详情查询
- 图书封面Url查询
- 图书馆藏信息查询
- 当前借阅、历史借阅、即将逾期借阅信息查询
- 图书搜索
...and more... ...and more...
</details> </details>
@ -58,18 +53,23 @@ JDK版本:1.8及以上,推荐JDK 11及以上
## 使用说明 ## 使用说明
> 文档?什么文档?不知道不知道
> 以后再说
### 在项目中引用mywust-core ### 在项目中引用mywust-core
在`pom.xml`中引用核心即可: 目前该项目发布在Github Package上,如遇网络问题请自备工具解决
关于如何在自己的项目中引用:
- Maven项目请参阅:[使用 Apache Maven 注册表](https://docs.github.com/zh/packages/working-with-a-github-packages-registry/working-with-the-apache-maven-registry)
- Gradle项目请参阅:[使用 Gradle 注册表](https://docs.github.com/zh/packages/working-with-a-github-packages-registry/working-with-the-gradle-registry)
配置好后,直接在`pom.xml`中引用即可:
```xml ```xml
<dependency> <dependency>
<groupId>cn.wustlinghang.mywust</groupId> <groupId>cn.linghang</groupId>
<artifactId>mywust-core</artifactId> <artifactId>mywust-core</artifactId>
<version>0.0.2-beta</version> <version>0.0.1-fixed</version>
</dependency> </dependency>
``` ```

@ -4,56 +4,17 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<artifactId>mywust</artifactId> <artifactId>mywust</artifactId>
<groupId>cn.wustlinghang.mywust</groupId> <groupId>cn.linghang</groupId>
<version>${revision}</version> <version>${revision}</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>mywust-common</artifactId> <artifactId>mywust-common</artifactId>
<name>${project.artifactId}</name>
<description>The API encapsulations of WUST's official web service. Module `${project.artifactId}`</description>
<url>https://github.com/LingHangStudio/mywust</url>
<scm>
<url>https://github.com/LingHangStudio/mywust</url>
<connection>scm:git:https://github.com/LingHangStudio/mywust.git</connection>
<developerConnection>scm:git:https://github.com/LingHangStudio/mywust.git</developerConnection>
<tag>${project.parent.version}</tag>
</scm>
<developers>
<developer>
<id>lensfrex</id>
<name>lensfrex</name>
<email>lensferno@outlook.com</email>
<url>https://github.com/lensferno</url>
<organization>wustlinghang</organization>
<organizationUrl>https://github.com/LingHangStudio</organizationUrl>
<timezone>+8</timezone>
</developer>
</developers>
<licenses>
<license>
<name>MIT License</name>
<url>https://mit-license.org/</url>
</license>
</licenses>
<properties> <properties>
<maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jackson-annotations.version>2.15.2</jackson-annotations.version>
</properties> </properties>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson-annotations.version}</version>
</dependency>
</dependencies>
</project> </project>

@ -1,5 +1,6 @@
package cn.wustlinghang.mywust.captcha; package cn.linghang.mywust.captcha;
import lombok.Data;
import lombok.Getter; import lombok.Getter;
/** /**

@ -1,4 +1,4 @@
package cn.wustlinghang.mywust.captcha; package cn.linghang.mywust.captcha;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;

@ -1,4 +1,4 @@
package cn.wustlinghang.mywust.data.global; package cn.linghang.mywust.data.global;
import java.util.StringJoiner; import java.util.StringJoiner;

@ -1,4 +1,4 @@
package cn.wustlinghang.mywust.data.global; package cn.linghang.mywust.data.global;
import java.util.StringJoiner; import java.util.StringJoiner;

@ -1,4 +1,4 @@
package cn.wustlinghang.mywust.data.global; package cn.linghang.mywust.data.global;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;

@ -1,4 +1,4 @@
package cn.wustlinghang.mywust.data.global; package cn.linghang.mywust.data.global;
import java.util.StringJoiner; import java.util.StringJoiner;

@ -1,4 +1,4 @@
package cn.wustlinghang.mywust.data.global; package cn.linghang.mywust.data.global;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;

@ -1,4 +1,4 @@
package cn.wustlinghang.mywust.data.global; package cn.linghang.mywust.data.global;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;

@ -1,4 +1,4 @@
package cn.wustlinghang.mywust.data.global; package cn.linghang.mywust.data.global;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;

@ -1,6 +1,6 @@
package cn.wustlinghang.mywust.data.physics; package cn.linghang.mywust.data.physics;
import cn.wustlinghang.mywust.data.global.Course; import cn.linghang.mywust.data.global.Course;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;

@ -1,4 +1,4 @@
package cn.wustlinghang.mywust.data.undergrad; package cn.linghang.mywust.data.undergrad;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;

@ -1,4 +1,4 @@
package cn.wustlinghang.mywust.exception; package cn.linghang.mywust.exception;
public class ApiException extends BasicException { public class ApiException extends BasicException {
private final Code code; private final Code code;
@ -99,16 +99,6 @@ public class ApiException extends BasicException {
*/ */
UNI_LOGIN_NEED_TFA(100107, "统一认证登录: 用户账号需要TFA二步验证"), UNI_LOGIN_NEED_TFA(100107, "统一认证登录: 用户账号需要TFA二步验证"),
/**
* 专属选课时间段账号被禁用
*/
UNDERGRAD_BANNED_IN_EXCLUSIVE_TIME(100108, "本科生登录:专属选课时间段账号被禁用"),
/**
* 用户名信息不存在新生信息未录入或者老生删档
*/
UNDERGRAD_USERINFO_NOT_EXISTS(100109, "本科生登录:用户名信息(新生信息未录入或者老生删档)"),
// -------------------------------- // --------------------------------
// 共有异常码:cookie无效 // 共有异常码:cookie无效
@ -138,11 +128,6 @@ public class ApiException extends BasicException {
*/ */
PHYSICS_PASSWORD_WRONG(130100, "物理实验系统登录: 密码错误"), PHYSICS_PASSWORD_WRONG(130100, "物理实验系统登录: 密码错误"),
/**
* 物理实验系统用户不存在于当前学期
*/
PHYSICS_NOT_CURRENT_TERM(130101, "物理实验系统登录: 当前用户不存在于当前学期"),
// -------------------------------- // --------------------------------
// 研究生API异常代码 // 研究生API异常代码
@ -151,10 +136,6 @@ public class ApiException extends BasicException {
*/ */
GRADUATE_PASSWORD_WRONG(140100, "研究生登录: 密码错误"), GRADUATE_PASSWORD_WRONG(140100, "研究生登录: 密码错误"),
/**
* 研究生验证码错误
*/
GRADUATE_CAPTCHA_WRONG(140101, "研究生登录: 验证码错误"),
// -------------------------------- // --------------------------------
// 图书馆API异常代码 // 图书馆API异常代码

@ -1,4 +1,4 @@
package cn.wustlinghang.mywust.exception; package cn.linghang.mywust.exception;
public class BasicException extends Exception { public class BasicException extends Exception {
public BasicException() { public BasicException() {

@ -1,4 +1,4 @@
package cn.wustlinghang.mywust.exception; package cn.linghang.mywust.exception;
import java.util.StringJoiner; import java.util.StringJoiner;

@ -1,20 +0,0 @@
package cn.wustlinghang.mywust.data.library;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PagingResult<T> {
private int currentPage;
private int pageSize;
private int totalPage;
private int totalResult;
private T data;
}

@ -1,61 +0,0 @@
package cn.wustlinghang.mywust.data.library.origin;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
* 响应回来的书籍信息借阅历史当前借阅即将逾期等的书目字段
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class BaseLoanBook {
protected String bibId;
protected String title;
protected String author;
/**
* 借书时间
*/
protected String loanDate;
protected String location;
protected String barCode;
/**
* 图书属性信息
*/
@JsonProperty("bibAttrs")
protected BookAttribute bookAttribute;
/**
* 图书属性
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public static class BookAttribute {
protected String isbn;
protected String publisher;
@JsonProperty("pub_year")
protected String publishYear;
protected String price;
/**
* 索书号
*/
@JsonProperty("callno")
protected String callNumber;
/**
* 书类编号
*/
@JsonProperty("classno")
protected String classNumber;
}
}

@ -1,67 +0,0 @@
package cn.wustlinghang.mywust.data.library.origin;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class BookSearchRequest {
private List<Object> filterFieldList = new ArrayList<>();
private String collapseField = "groupId";
private String sortType = "desc";
private String indexName = "idx.opac";
private String sortField = "relevance";
private List<QueryFieldListItem> queryFieldList = new ArrayList<>(1);
private int pageSize;
private int page;
public BookSearchRequest(String keyWord, int pageSize, int page) {
this.pageSize = pageSize;
this.page = page;
this.queryFieldList.add(new QueryFieldListItem(keyWord));
}
@Data
public static class QueryFieldListItem {
private String field = "all";
private String operator = "*";
private int logic = 0;
private List<String> values = new ArrayList<>(1);
public QueryFieldListItem(String keyWord) {
values.add(keyWord);
}
}
public static class Builder {
private int pageSize;
private int page;
private String keyword;
private Builder() {
}
public Builder pageSize(int pageSize) {
this.pageSize = pageSize;
return this;
}
public Builder page(int page) {
this.page = page;
return this;
}
public Builder keyword(String keyword) {
this.keyword = keyword;
return this;
}
public BookSearchRequest build() {
return new BookSearchRequest(keyword, pageSize, page);
}
}
}

@ -1,80 +0,0 @@
package cn.wustlinghang.mywust.data.library.origin;
import cn.wustlinghang.mywust.data.library.parsed.BookHolding;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.List;
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class BookSearchResult {
private String bibId;
private String title;
private String author;
@JsonProperty("abstract")
private String summary;
private String publisher;
private List<String> holdingTypes;
@JsonProperty("callno")
private List<String> callNumber;
/**
* 文献类型
*/
private String docType;
private String groupId;
private String isbn;
/**
* 图书馆系统中的图书编号
*/
private String bibNo;
/**
* 图书总数
*/
private int itemCount;
/**
* 在借数量
*/
private int circCount;
@JsonProperty("pub_year")
private String pubYear;
@JsonProperty("classno")
private String classNumber;
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
private List<BookHolding> holdings;
}
/*
bibId: 图书馆系统中的图书ID用于唯一标识一本图书
holdingTypes: 图书的持有类型此处为print表示该图书以纸质形式持有
author: 作者此处为Walter Savitch著表示该图书的作者是Walter Savitch
callno: 索书号此处为["TP312JA/E26=4/1","TP312JA/E26=4/2"]表示该图书的索书号是TP312JA/E26=4/1和TP312JA/E26=4/2
docType: 文献类型此处为doc.02表示该图书的文献类型为doc.02
groupId: 分组ID此处为1e24652f1d98f0586dc6468136f8eba6可能是用于图书分类的一个标识
isbn: ISBN号此处为7115152888 (v. 1)表示该图书的ISBN号是7115152888其中(v. 1)可能表示版本号
bibNo: 图书馆系统中的图书编号此处为1800067256
title: 书名此处为Java : an introduction to problem solving & programming = Java : 程序设计与问题解决/ Walter Savitch著.表示该图书的书名是Java : 程序设计与问题解决作者是Walter Savitch
itemCount: 图书总数此处为8表示该图书馆系统中该图书的总数
circCount: 图书当前在借数量此处也为8表示该图书当前在借数量为8
pub_year: 出版年份此处为2006.表示该图书的出版年份是2006年
classno: 分类号此处为TP312JA可能是用于图书分类的一个标识
publisher: 出版商此处为Posts & Telecom Press表示该图书的出版商是Posts & Telecom Press
holdings: 持有情况此处为空字符串可能是用于记录该图书的其他持有情况
_id: 记录ID此处为544237可能是用于记录该图书的唯一标识
*/

@ -1,12 +0,0 @@
package cn.wustlinghang.mywust.data.library.origin;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
@JsonIgnoreProperties(ignoreUnknown = true)
public class CurrentLoanBook extends BaseLoanBook {
private String dueDate;
}

@ -1,12 +0,0 @@
package cn.wustlinghang.mywust.data.library.origin;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
@JsonIgnoreProperties(ignoreUnknown = true)
public class HistoryLoanBook extends BaseLoanBook {
private String returnDate;
}

@ -1,51 +0,0 @@
package cn.wustlinghang.mywust.data.library.parsed;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Map;
/**
* 书籍详情
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class BookDetail {
private String title;
private String author;
private String isbn;
/**
* 作者介绍
*/
private String authorDescribe;
/**
* 目录
*/
private String catalog;
/**
* 封面url
*/
private String coverUrl;
/**
* 图书简要
*/
private String summary;
/**
* 图书介绍
*/
private String introduction;
/**
* 书籍详细信息因为图书馆系统奇葩的中文不定key因此将这些信息放入key-value对中需要者自取
*/
Map<String, String> extraInfoMap;
}

@ -1,56 +0,0 @@
package cn.wustlinghang.mywust.data.library.parsed;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
* 馆藏信息单个
*/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class BookHolding {
@JsonProperty("callNo")
private String callNumber;
/**
* 馆藏总数
*/
private int itemsCount;
/**
* 可借数
*/
private int itemsAvailable;
/**
* 条形码
*/
private String barCode;
/**
* 所属馆藏地
*/
private String location;
/**
* 临时馆藏地
*/
private String tempLocation;
/**
* 卷年期
*/
@JsonProperty("vol")
private String volume;
/**
* 馆名总馆等等
*/
private String library;
/**
* 状态文本
*/
private String status;
}

@ -1,69 +0,0 @@
package cn.wustlinghang.mywust.data.library.parsed;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.List;
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class BookSearchResult {
private String bibId;
private List<String> holdingTypes;
private String author;
private List<String> callNumber;
/**
* 文献类型
*/
private String docType;
private String groupId;
private String isbn;
/**
* 图书馆系统中的图书编号
*/
private String bibNo;
private String title;
/**
* 图书总数
*/
private int itemCount;
/**
* 在借数量
*/
private int circCount;
private String pubYear;
private String classNumber;
private String publisher;
private List<BookHolding> holdings;
}
/*
bibId: 图书馆系统中的图书ID用于唯一标识一本图书
holdingTypes: 图书的持有类型此处为print表示该图书以纸质形式持有
author: 作者此处为Walter Savitch著表示该图书的作者是Walter Savitch
callno: 索书号此处为["TP312JA/E26=4/1","TP312JA/E26=4/2"]表示该图书的索书号是TP312JA/E26=4/1和TP312JA/E26=4/2
docType: 文献类型此处为doc.02表示该图书的文献类型为doc.02
groupId: 分组ID此处为1e24652f1d98f0586dc6468136f8eba6可能是用于图书分类的一个标识
isbn: ISBN号此处为7115152888 (v. 1)表示该图书的ISBN号是7115152888其中(v. 1)可能表示版本号
bibNo: 图书馆系统中的图书编号此处为1800067256
title: 书名此处为Java : an introduction to problem solving & programming = Java : 程序设计与问题解决/ Walter Savitch著.表示该图书的书名是Java : 程序设计与问题解决作者是Walter Savitch
itemCount: 图书总数此处为8表示该图书馆系统中该图书的总数
circCount: 图书当前在借数量此处也为8表示该图书当前在借数量为8
pub_year: 出版年份此处为2006.表示该图书的出版年份是2006年
classno: 分类号此处为TP312JA可能是用于图书分类的一个标识
publisher: 出版商此处为Posts & Telecom Press表示该图书的出版商是Posts & Telecom Press
holdings: 持有情况此处为空字符串可能是用于记录该图书的其他持有情况
_id: 记录ID此处为544237可能是用于记录该图书的唯一标识
*/

@ -4,52 +4,21 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<artifactId>mywust</artifactId> <artifactId>mywust</artifactId>
<groupId>cn.wustlinghang.mywust</groupId> <groupId>cn.linghang</groupId>
<version>${revision}</version> <version>${revision}</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>mywust-core</artifactId> <artifactId>mywust-core</artifactId>
<name>${project.artifactId}</name>
<description>The API encapsulations of WUST's official web service. Module `${project.artifactId}`</description>
<url>https://github.com/LingHangStudio/mywust</url>
<scm>
<url>https://github.com/LingHangStudio/mywust</url>
<connection>scm:git:https://github.com/LingHangStudio/mywust.git</connection>
<developerConnection>scm:git:https://github.com/LingHangStudio/mywust.git</developerConnection>
<tag>${project.parent.version}</tag>
</scm>
<developers>
<developer>
<id>lensfrex</id>
<name>lensfrex</name>
<email>lensferno@outlook.com</email>
<url>https://github.com/lensferno</url>
<organization>wustlinghang</organization>
<organizationUrl>https://github.com/LingHangStudio</organizationUrl>
<timezone>+8</timezone>
</developer>
</developers>
<licenses>
<license>
<name>MIT License</name>
<url>https://mit-license.org/</url>
</license>
</licenses>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>cn.wustlinghang.mywust</groupId> <groupId>cn.linghang</groupId>
<artifactId>mywust-network</artifactId> <artifactId>mywust-network</artifactId>
<version>${project.parent.version}</version> <version>${project.parent.version}</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>cn.wustlinghang.mywust</groupId> <groupId>cn.linghang</groupId>
<artifactId>mywust-util</artifactId> <artifactId>mywust-util</artifactId>
<version>${project.parent.version}</version> <version>${project.parent.version}</version>
</dependency> </dependency>
@ -68,7 +37,7 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>cn.wustlinghang.mywust</groupId> <groupId>cn.linghang</groupId>
<artifactId>mywust-common</artifactId> <artifactId>mywust-common</artifactId>
<version>${project.parent.version}</version> <version>${project.parent.version}</version>
<scope>compile</scope> <scope>compile</scope>
@ -76,13 +45,13 @@
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId> <artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version> <version>2.14.0-rc1</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId> <artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version> <version>2.14.0-rc1</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
@ -100,7 +69,6 @@
<slf4j.version>2.0.3</slf4j.version> <slf4j.version>2.0.3</slf4j.version>
<jsoup.version>1.15.3</jsoup.version> <jsoup.version>1.15.3</jsoup.version>
<hutool.version>5.8.22</hutool.version> <hutool.version>5.8.12</hutool.version>
<jackson.version>2.15.2</jackson.version>
</properties> </properties>
</project> </project>

@ -1,4 +1,4 @@
package cn.wustlinghang.mywust.core.api; package cn.linghang.mywust.core.api;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;

@ -1,4 +1,4 @@
package cn.wustlinghang.mywust.core.api; package cn.linghang.mywust.core.api;
public class GraduateUrls { public class GraduateUrls {
public static final String GRADUATE_CAPTCHA_API = "http://59.68.177.189/pyxx/PageTemplate/NsoftPage/yzm/createyzm.aspx"; public static final String GRADUATE_CAPTCHA_API = "http://59.68.177.189/pyxx/PageTemplate/NsoftPage/yzm/createyzm.aspx";

@ -1,23 +1,19 @@
package cn.wustlinghang.mywust.core.api; package cn.linghang.mywust.core.api;
public class LibraryUrls { public class LibraryUrls {
public static final String LIBRARY_SESSION_COOKIE_API = "https://libsys.wust.edu.cn/meta-local/opac/cas/rosetta?ticket=%s"; public static final String LIBRARY_SESSION_COOKIE_API = "https://libsys.wust.edu.cn/meta-local/opac/cas/rosetta?ticket=%s";
public static final String LIBRARY_INDEX_URL = "https://libsys.wust.edu.cn/meta-local/opac/cas/rosetta"; public static final String LIBRARY_INDEX_URL = "https://libsys.wust.edu.cn/meta-local/opac/cas/rosetta";
// 用违章记录信息api地址作为测试url(大部分人应该没有违章吧 :) public static final String LIBRARY_COOKIE_TEST_URL = "https://libsys.wust.edu.cn/meta-local/opac/users/info";
public static final String LIBRARY_COOKIE_TEST_URL = "https://libsys.wust.edu.cn/meta-local/opac/users/volts";
public static final String LIBRARY_ACCOUNT_STATUS_API = "https://libsys.wust.edu.cn/meta-local/opac/users/stats"; public static final String LIBRARY_ACCOUNT_STATUS_API = "https://libsys.wust.edu.cn/meta-local/opac/users/stats";
public static final String LIBRARY_CURRENT_LOAN_API = "https://libsys.wust.edu.cn/meta-local/opac/users/loans?page=%d&pageSize=%d"; public static final String LIBRARY_CURRENT_LOAN_API = "https://libsys.wust.edu.cn/meta-local/opac/users/loans?page=1&pageSize=100";
public static final String LIBRARY_LOAN_HISTORY_API = "https://libsys.wust.edu.cn/meta-local/opac/users/loan_hists?page=%d&pageSize=%d"; public static final String LIBRARY_LOAN_HISTORY_API = "https://libsys.wust.edu.cn/meta-local/opac/users/loan_hists?page=1&pageSize=100";
public static final String LIBRARY_OVERDUE_SOON_API = "https://libsys.wust.edu.cn/meta-local/opac/users/overdue_soon?page=%d&pageSize=%d"; public static final String LIBRARY_OVERDUE_SOON_API = "https://libsys.wust.edu.cn/meta-local/opac/users/overdue_soon";
public static final String LIBRARY_BOOK_INFO_API = "https://libsys.wust.edu.cn/meta-local/opac/bibs/%s/infos"; public static final String LIBRARY_BOOK_INFO_API = "https://libsys.wust.edu.cn/meta-local/opac/bibs/%s/infos";
public static final String LIBRARY_BOOK_DOUBAN_INFO_API = "https://libsys.wust.edu.cn/meta-local/opac/third_api/douban/%s/info";
public static final String LIBRARY_BOOK_CONTENT_API = "https://libsys.wust.edu.cn/meta-local/opac/bibs/%s/quoteds/quoted.caj-cd/content";
public static final String LIBRARY_BOOK_HOLDING_API = "https://libsys.wust.edu.cn/meta-local/opac/bibs/%s/holdings";
public static final String LIBRARY_BOOK_COVER_IMAGE_API = "https://libsys.wust.edu.cn/meta-local/opac/search/extend/"; public static final String LIBRARY_BOOK_COVER_IMAGE_API = "https://libsys.wust.edu.cn/meta-local/opac/search/extend/";

@ -1,4 +1,4 @@
package cn.wustlinghang.mywust.core.api; package cn.linghang.mywust.core.api;
public class PhysicsSystemUrls { public class PhysicsSystemUrls {
public static final String PHYSICS_LOGIN_INDEX = "http://wlsy.wust.edu.cn/Page/BI/BI000.aspx"; public static final String PHYSICS_LOGIN_INDEX = "http://wlsy.wust.edu.cn/Page/BI/BI000.aspx";

@ -1,4 +1,4 @@
package cn.wustlinghang.mywust.core.api; package cn.linghang.mywust.core.api;
import lombok.Getter; import lombok.Getter;

@ -1,4 +1,4 @@
package cn.wustlinghang.mywust.core.api; package cn.linghang.mywust.core.api;
public class UnionAuthUrls { public class UnionAuthUrls {
/** /**

@ -1,7 +1,7 @@
package cn.wustlinghang.mywust.core.parser; package cn.linghang.mywust.core.parser;
import cn.wustlinghang.mywust.exception.ParseException; import cn.linghang.mywust.exception.ParseException;
import cn.wustlinghang.mywust.data.global.Classroom; import cn.linghang.mywust.data.global.Classroom;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;

@ -0,0 +1,7 @@
package cn.linghang.mywust.core.parser;
import cn.linghang.mywust.exception.ParseException;
public interface Parser<T> {
public T parse(String html) throws ParseException;
}

@ -1,9 +1,9 @@
package cn.wustlinghang.mywust.core.parser.graduate; package cn.linghang.mywust.core.parser.graduate;
import cn.wustlinghang.mywust.exception.ParseException; import cn.linghang.mywust.exception.ParseException;
import cn.wustlinghang.mywust.core.parser.Parser; import cn.linghang.mywust.core.parser.Parser;
import cn.wustlinghang.mywust.data.global.Classroom; import cn.linghang.mywust.data.global.Classroom;
import cn.wustlinghang.mywust.data.global.Course; import cn.linghang.mywust.data.global.Course;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.nodes.Document; import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;

@ -1,8 +1,8 @@
package cn.wustlinghang.mywust.core.parser.graduate; package cn.linghang.mywust.core.parser.graduate;
import cn.wustlinghang.mywust.exception.ParseException; import cn.linghang.mywust.exception.ParseException;
import cn.wustlinghang.mywust.core.parser.Parser; import cn.linghang.mywust.core.parser.Parser;
import cn.wustlinghang.mywust.data.global.Score; import cn.linghang.mywust.data.global.Score;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.nodes.Document; import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;

@ -1,9 +1,9 @@
package cn.wustlinghang.mywust.core.parser.graduate; package cn.linghang.mywust.core.parser.graduate;
import cn.wustlinghang.mywust.exception.ParseException; import cn.linghang.mywust.exception.ParseException;
import cn.wustlinghang.mywust.core.parser.Parser; import cn.linghang.mywust.core.parser.Parser;
import cn.wustlinghang.mywust.core.util.JsoupUtil; import cn.linghang.mywust.core.util.JsoupUtil;
import cn.wustlinghang.mywust.data.global.StudentInfo; import cn.linghang.mywust.data.global.StudentInfo;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;

@ -1,14 +1,17 @@
package cn.wustlinghang.mywust.core.parser.graduate; package cn.linghang.mywust.core.parser.graduate;
import cn.wustlinghang.mywust.exception.ParseException; import cn.linghang.mywust.exception.ParseException;
import cn.wustlinghang.mywust.core.parser.Parser; import cn.linghang.mywust.core.parser.Parser;
import cn.wustlinghang.mywust.core.util.JsoupUtil; import cn.linghang.mywust.core.util.JsoupUtil;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.nodes.Document; import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;
public class GraduateTrainingPlanPageParser implements Parser<String> { public class GraduateTrainingPlanPageParser implements Parser<String> {
private static final String HTML_PREFIX = "<!DOCTYPE html><html lang=\"zh\"><head><meta charset=\"UTF-8\"><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>培养计划</title></head><body>";
private static final String HTML_SUFFIX = "</body></html>";
@Override @Override
public String parse(String html) throws ParseException { public String parse(String html) throws ParseException {
try { try {
@ -22,7 +25,7 @@ public class GraduateTrainingPlanPageParser implements Parser<String> {
String table = JsoupUtil.getOuterHtml(fullTable.getElementById("_ctl0_MainWork_dgData")); String table = JsoupUtil.getOuterHtml(fullTable.getElementById("_ctl0_MainWork_dgData"));
String foot = JsoupUtil.getOuterHtml(fullTable.getElementById("Table4")); String foot = JsoupUtil.getOuterHtml(fullTable.getElementById("Table4"));
return head + table + foot; return HTML_PREFIX + head + table + foot + HTML_SUFFIX;
}catch (Exception e) { }catch (Exception e) {
// 解析失败就直接返回原网页展示 // 解析失败就直接返回原网页展示
return html; return html;

@ -1,10 +1,10 @@
package cn.wustlinghang.mywust.core.parser.physics; package cn.linghang.mywust.core.parser.physics;
import cn.wustlinghang.mywust.exception.ParseException; import cn.linghang.mywust.exception.ParseException;
import cn.wustlinghang.mywust.core.parser.HuangjiahuClassroomNameParser; import cn.linghang.mywust.core.parser.HuangjiahuClassroomNameParser;
import cn.wustlinghang.mywust.core.parser.Parser; import cn.linghang.mywust.core.parser.Parser;
import cn.wustlinghang.mywust.data.global.Classroom; import cn.linghang.mywust.data.global.Classroom;
import cn.wustlinghang.mywust.data.physics.PhysicsCourse; import cn.linghang.mywust.data.physics.PhysicsCourse;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.select.Elements; import org.jsoup.select.Elements;

@ -1,7 +1,7 @@
package cn.wustlinghang.mywust.core.parser.physics; package cn.linghang.mywust.core.parser.physics;
import cn.wustlinghang.mywust.exception.ParseException; import cn.linghang.mywust.exception.ParseException;
import cn.wustlinghang.mywust.core.parser.Parser; import cn.linghang.mywust.core.parser.Parser;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.nodes.Document; import org.jsoup.nodes.Document;
import org.jsoup.select.Elements; import org.jsoup.select.Elements;

@ -1,8 +1,8 @@
package cn.wustlinghang.mywust.core.parser.physics; package cn.linghang.mywust.core.parser.physics;
import cn.wustlinghang.mywust.exception.ParseException; import cn.linghang.mywust.exception.ParseException;
import cn.wustlinghang.mywust.core.parser.Parser; import cn.linghang.mywust.core.parser.Parser;
import cn.wustlinghang.mywust.core.util.JsoupUtil; import cn.linghang.mywust.core.util.JsoupUtil;
import lombok.Data; import lombok.Data;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.nodes.Document; import org.jsoup.nodes.Document;

@ -1,9 +1,9 @@
package cn.wustlinghang.mywust.core.parser.physics; package cn.linghang.mywust.core.parser.physics;
import cn.wustlinghang.mywust.exception.ParseException; import cn.linghang.mywust.exception.ParseException;
import cn.wustlinghang.mywust.core.parser.Parser; import cn.linghang.mywust.core.parser.Parser;
import cn.wustlinghang.mywust.core.util.JsoupUtil; import cn.linghang.mywust.core.util.JsoupUtil;
import cn.wustlinghang.mywust.data.global.Score; import cn.linghang.mywust.data.global.Score;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;
import org.jsoup.select.Elements; import org.jsoup.select.Elements;

@ -1,11 +1,11 @@
package cn.wustlinghang.mywust.core.parser.undergraduate; package cn.linghang.mywust.core.parser.undergraduate;
import cn.wustlinghang.mywust.exception.ParseException; import cn.linghang.mywust.exception.ParseException;
import cn.wustlinghang.mywust.core.parser.Parser; import cn.linghang.mywust.core.parser.Parser;
import cn.wustlinghang.mywust.core.util.JsoupUtil; import cn.linghang.mywust.core.util.JsoupUtil;
import cn.wustlinghang.mywust.data.global.Classroom; import cn.linghang.mywust.data.global.Classroom;
import cn.wustlinghang.mywust.data.global.Course; import cn.linghang.mywust.data.global.Course;
import cn.wustlinghang.mywust.util.StringUtil; import cn.linghang.mywust.util.StringUtil;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;
import org.jsoup.select.Elements; import org.jsoup.select.Elements;

@ -1,7 +1,7 @@
package cn.wustlinghang.mywust.core.parser.undergraduate; package cn.linghang.mywust.core.parser.undergraduate;
import cn.wustlinghang.mywust.exception.ParseException; import cn.linghang.mywust.exception.ParseException;
import cn.wustlinghang.mywust.core.parser.Parser; import cn.linghang.mywust.core.parser.Parser;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;
import org.jsoup.select.Elements; import org.jsoup.select.Elements;

@ -1,7 +1,7 @@
package cn.wustlinghang.mywust.core.parser.undergraduate; package cn.linghang.mywust.core.parser.undergraduate;
import cn.wustlinghang.mywust.exception.ParseException; import cn.linghang.mywust.exception.ParseException;
import cn.wustlinghang.mywust.core.parser.Parser; import cn.linghang.mywust.core.parser.Parser;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.select.Elements; import org.jsoup.select.Elements;

@ -1,9 +1,9 @@
package cn.wustlinghang.mywust.core.parser.undergraduate; package cn.linghang.mywust.core.parser.undergraduate;
import cn.wustlinghang.mywust.exception.ParseException; import cn.linghang.mywust.exception.ParseException;
import cn.wustlinghang.mywust.core.parser.Parser; import cn.linghang.mywust.core.parser.Parser;
import cn.wustlinghang.mywust.core.util.JsoupUtil; import cn.linghang.mywust.core.util.JsoupUtil;
import cn.wustlinghang.mywust.data.undergrad.ExamDelayApplication; import cn.linghang.mywust.data.undergrad.ExamDelayApplication;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;

@ -1,9 +1,9 @@
package cn.wustlinghang.mywust.core.parser.undergraduate; package cn.linghang.mywust.core.parser.undergraduate;
import cn.wustlinghang.mywust.exception.ParseException; import cn.linghang.mywust.exception.ParseException;
import cn.wustlinghang.mywust.core.parser.Parser; import cn.linghang.mywust.core.parser.Parser;
import cn.wustlinghang.mywust.core.util.JsoupUtil; import cn.linghang.mywust.core.util.JsoupUtil;
import cn.wustlinghang.mywust.data.global.Score; import cn.linghang.mywust.data.global.Score;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;
import org.jsoup.select.Elements; import org.jsoup.select.Elements;

@ -1,9 +1,9 @@
package cn.wustlinghang.mywust.core.parser.undergraduate; package cn.linghang.mywust.core.parser.undergraduate;
import cn.wustlinghang.mywust.exception.ParseException; import cn.linghang.mywust.exception.ParseException;
import cn.wustlinghang.mywust.core.parser.Parser; import cn.linghang.mywust.core.parser.Parser;
import cn.wustlinghang.mywust.core.util.JsoupUtil; import cn.linghang.mywust.core.util.JsoupUtil;
import cn.wustlinghang.mywust.data.global.StudentInfo; import cn.linghang.mywust.data.global.StudentInfo;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.nodes.Document; import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;

@ -1,7 +1,7 @@
package cn.wustlinghang.mywust.core.parser.undergraduate; package cn.linghang.mywust.core.parser.undergraduate;
import cn.wustlinghang.mywust.exception.ParseException; import cn.linghang.mywust.exception.ParseException;
import cn.wustlinghang.mywust.core.parser.Parser; import cn.linghang.mywust.core.parser.Parser;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.select.Elements; import org.jsoup.select.Elements;

@ -1,9 +1,9 @@
package cn.wustlinghang.mywust.core.parser.undergraduate.global; package cn.linghang.mywust.core.parser.undergraduate.global;
import cn.wustlinghang.mywust.exception.ParseException; import cn.linghang.mywust.exception.ParseException;
import cn.wustlinghang.mywust.data.global.Classroom; import cn.linghang.mywust.data.global.Classroom;
import cn.wustlinghang.mywust.data.global.Course; import cn.linghang.mywust.data.global.Course;
import cn.wustlinghang.mywust.util.StringUtil; import cn.linghang.mywust.util.StringUtil;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;
import org.jsoup.select.Elements; import org.jsoup.select.Elements;

@ -1,8 +1,8 @@
package cn.wustlinghang.mywust.core.parser.undergraduate.global; package cn.linghang.mywust.core.parser.undergraduate.global;
import cn.wustlinghang.mywust.exception.ParseException; import cn.linghang.mywust.exception.ParseException;
import cn.wustlinghang.mywust.core.parser.Parser; import cn.linghang.mywust.core.parser.Parser;
import cn.wustlinghang.mywust.data.global.Course; import cn.linghang.mywust.data.global.Course;
import java.util.List; import java.util.List;
import java.util.regex.Pattern; import java.util.regex.Pattern;

@ -1,8 +1,8 @@
package cn.wustlinghang.mywust.core.parser.undergraduate.global; package cn.linghang.mywust.core.parser.undergraduate.global;
import cn.wustlinghang.mywust.exception.ParseException; import cn.linghang.mywust.exception.ParseException;
import cn.wustlinghang.mywust.core.parser.Parser; import cn.linghang.mywust.core.parser.Parser;
import cn.wustlinghang.mywust.data.global.Course; import cn.linghang.mywust.data.global.Course;
import java.util.List; import java.util.List;
import java.util.regex.Pattern; import java.util.regex.Pattern;

@ -1,14 +1,11 @@
package cn.wustlinghang.mywust.network.request; package cn.linghang.mywust.core.request.factory;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.network.entitys.HttpRequest;
import lombok.extern.slf4j.Slf4j;
import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Map; import java.util.Map;
@Slf4j
public class RequestFactory { public class RequestFactory {
protected static final HttpRequest DEFAULT_HTTP_REQUEST = new HttpRequest(); protected static final HttpRequest DEFAULT_HTTP_REQUEST = new HttpRequest();
@ -55,8 +52,7 @@ public class RequestFactory {
public static URL makeUrl(String url) { public static URL makeUrl(String url) {
try { try {
return new URL(url); return new URL(url);
} catch (MalformedURLException e) { } catch (Exception e) {
log.error("[mywust]: Invalid url: {} , {}", url, e.getMessage());
return null; return null;
} }
} }

@ -1,9 +1,9 @@
package cn.wustlinghang.mywust.core.request.factory.auth; package cn.linghang.mywust.core.request.factory.auth;
import cn.wustlinghang.mywust.core.api.UnionAuthUrls; import cn.linghang.mywust.core.api.UnionAuthUrls;
import cn.wustlinghang.mywust.network.request.RequestFactory; import cn.linghang.mywust.core.request.factory.RequestFactory;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.util.StringUtil; import cn.linghang.mywust.util.StringUtil;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.HashMap; import java.util.HashMap;

@ -1,11 +1,11 @@
package cn.wustlinghang.mywust.core.request.factory.graduate; package cn.linghang.mywust.core.request.factory.graduate;
import cn.wustlinghang.mywust.captcha.SolvedImageCaptcha; import cn.linghang.mywust.captcha.SolvedImageCaptcha;
import cn.wustlinghang.mywust.core.api.GraduateUrls; import cn.linghang.mywust.core.api.GraduateUrls;
import cn.wustlinghang.mywust.network.request.RequestFactory; import cn.linghang.mywust.core.request.factory.RequestFactory;
import cn.wustlinghang.mywust.core.util.PageFormExtractor; import cn.linghang.mywust.core.util.PageFormExtractor;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.util.StringUtil; import cn.linghang.mywust.util.StringUtil;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;

@ -1,17 +1,16 @@
package cn.wustlinghang.mywust.core.request.factory.library; package cn.linghang.mywust.core.request.factory.library;
import cn.wustlinghang.mywust.core.api.LibraryUrls; import cn.hutool.core.util.URLUtil;
import cn.wustlinghang.mywust.network.request.RequestFactory; import cn.linghang.mywust.core.api.LibraryUrls;
import cn.wustlinghang.mywust.data.library.origin.BookSearchRequest; import cn.linghang.mywust.core.request.factory.RequestFactory;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.core.request.factory.library.request.SearchRequest;
import cn.linghang.mywust.network.entitys.HttpRequest;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import java.util.List; import java.util.List;
import java.util.StringJoiner; import java.util.StringJoiner;
@Slf4j
public class LibraryRequestFactory extends RequestFactory { public class LibraryRequestFactory extends RequestFactory {
private static final ObjectMapper objectMapper = new ObjectMapper(); private static final ObjectMapper objectMapper = new ObjectMapper();
@ -26,10 +25,10 @@ public class LibraryRequestFactory extends RequestFactory {
} }
public static HttpRequest bookSearchRequest(String keyword, int page, int pageSize) { public static HttpRequest bookSearchRequest(String keyword, int page, int pageSize) {
return bookSearchRequest(new BookSearchRequest(keyword, pageSize, page)); return bookSearchRequest(new SearchRequest(keyword, pageSize, page));
} }
public static HttpRequest bookSearchRequest(BookSearchRequest request) { public static HttpRequest bookSearchRequest(SearchRequest request) {
return makeHttpRequest(LibraryUrls.LIBRARY_SEARCH_API, json(request)) return makeHttpRequest(LibraryUrls.LIBRARY_SEARCH_API, json(request))
.addHeaders("Content-Type", "application/json"); .addHeaders("Content-Type", "application/json");
} }
@ -38,16 +37,16 @@ public class LibraryRequestFactory extends RequestFactory {
return makeHttpRequest(LibraryUrls.LIBRARY_ACCOUNT_STATUS_API, null, cookie); return makeHttpRequest(LibraryUrls.LIBRARY_ACCOUNT_STATUS_API, null, cookie);
} }
public static HttpRequest currentLoanRequest(String cookie, int page, int pageSize) { public static HttpRequest currentLoanRequest(String cookie) {
return makeHttpRequest(String.format(LibraryUrls.LIBRARY_CURRENT_LOAN_API, page, pageSize), null, cookie); return makeHttpRequest(LibraryUrls.LIBRARY_CURRENT_LOAN_API, null, cookie);
} }
public static HttpRequest loanHistoryRequest(String cookie, int page, int pageSize) { public static HttpRequest loanHistoryRequest(String cookie) {
return makeHttpRequest(String.format(LibraryUrls.LIBRARY_LOAN_HISTORY_API, page, pageSize), null, cookie); return makeHttpRequest(LibraryUrls.LIBRARY_LOAN_HISTORY_API, null, cookie);
} }
public static HttpRequest overdueSoonRequest(String cookie, int page, int pageSize) { public static HttpRequest overdueSoonRequest(String cookie) {
return makeHttpRequest(String.format(LibraryUrls.LIBRARY_OVERDUE_SOON_API, page, pageSize), null, cookie); return makeHttpRequest(LibraryUrls.LIBRARY_OVERDUE_SOON_API, null, cookie);
} }
public static HttpRequest bookInfoRequest(String bookId) { public static HttpRequest bookInfoRequest(String bookId) {
@ -55,21 +54,6 @@ public class LibraryRequestFactory extends RequestFactory {
return makeHttpRequest(url, (byte[]) null); return makeHttpRequest(url, (byte[]) null);
} }
public static HttpRequest bookDoubanInfoRequest(String isbn) {
String url = String.format(LibraryUrls.LIBRARY_BOOK_DOUBAN_INFO_API, isbn);
return makeHttpRequest(url, (byte[]) null);
}
public static HttpRequest bookContentRequest(String id) {
String url = String.format(LibraryUrls.LIBRARY_BOOK_CONTENT_API, id);
return makeHttpRequest(url, (byte[]) null);
}
public static HttpRequest bookHoldingRequest(String bookId) {
String url = String.format(LibraryUrls.LIBRARY_BOOK_HOLDING_API, bookId);
return makeHttpRequest(url, (byte[]) null);
}
public static HttpRequest bookCoverImageUrlRequest(List<String> isbn) { public static HttpRequest bookCoverImageUrlRequest(List<String> isbn) {
StringJoiner joiner = new StringJoiner("%2C", LibraryUrls.LIBRARY_BOOK_COVER_IMAGE_API, ""); StringJoiner joiner = new StringJoiner("%2C", LibraryUrls.LIBRARY_BOOK_COVER_IMAGE_API, "");
isbn.forEach(joiner::add); isbn.forEach(joiner::add);
@ -84,8 +68,7 @@ public class LibraryRequestFactory extends RequestFactory {
private static String json(Object object) { private static String json(Object object) {
try { try {
return objectMapper.writeValueAsString(object); return objectMapper.writeValueAsString(object);
} catch (JsonProcessingException e) { } catch (JsonProcessingException ignored) {
log.error("生成json时出现不应出现的异常:", e);
return ""; return "";
} }
} }

@ -0,0 +1,40 @@
package cn.linghang.mywust.core.request.factory.library.request;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
import java.util.StringJoiner;
@Data
public class SearchRequest {
private final List<Object> filterFieldList = new ArrayList<>();
private final String collapseField = "groupId";
private final String sortType = "desc";
private final String indexName = "idx.opac";
private final String sortField = "relevance";
private final List<QueryFieldListItem> queryFieldList = new ArrayList<>(1);
private int pageSize;
private int page;
public SearchRequest(String keyWord, int pageSize, int page) {
this.pageSize = pageSize;
this.page = page;
this.queryFieldList.add(new QueryFieldListItem(keyWord));
}
@Data
public static class QueryFieldListItem {
private final String field = "all";
private final String operator = "*";
private final int logic = 0;
private final List<String> values = new ArrayList<>(1);
public QueryFieldListItem(String keyWord) {
values.add(keyWord);
}
}
}

@ -1,10 +1,10 @@
package cn.wustlinghang.mywust.core.request.factory.physics; package cn.linghang.mywust.core.request.factory.physics;
import cn.wustlinghang.mywust.core.api.PhysicsSystemUrls; import cn.linghang.mywust.core.api.PhysicsSystemUrls;
import cn.wustlinghang.mywust.network.request.RequestFactory; import cn.linghang.mywust.core.request.factory.RequestFactory;
import cn.wustlinghang.mywust.core.util.PageFormExtractor; import cn.linghang.mywust.core.util.PageFormExtractor;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.util.StringUtil; import cn.linghang.mywust.util.StringUtil;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -31,10 +31,6 @@ public class PhysicsSystemRequestFactory extends RequestFactory {
return makeHttpRequest(redirect, null, cookies); return makeHttpRequest(redirect, null, cookies);
} }
public static HttpRequest physicsSystemIndexRequest(String cookies) {
return makeHttpRequest(PhysicsSystemUrls.PHYSICS_SYSTEM_INDEX_URL, null, cookies);
}
public static HttpRequest physicsCourseRequest(String cookies) { public static HttpRequest physicsCourseRequest(String cookies) {
return makeHttpRequest(PhysicsSystemUrls.PHYSICS_COURSE_API, null, cookies); return makeHttpRequest(PhysicsSystemUrls.PHYSICS_COURSE_API, null, cookies);
} }

@ -1,16 +1,17 @@
package cn.wustlinghang.mywust.core.request.factory.undergrade; package cn.linghang.mywust.core.request.factory.undergrade;
import cn.wustlinghang.mywust.core.api.UndergradUrls; import cn.linghang.mywust.core.api.UndergradUrls;
import cn.wustlinghang.mywust.network.request.RequestFactory; import cn.linghang.mywust.core.request.factory.RequestFactory;
import cn.wustlinghang.mywust.data.global.Campus; import cn.linghang.mywust.data.global.Campus;
import cn.wustlinghang.mywust.network.entitys.FormBodyBuilder; import cn.linghang.mywust.network.entitys.FormBodyBuilder;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.util.StringUtil; import cn.linghang.mywust.util.StringUtil;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.TreeMap;
public class BkjxRequestFactory extends RequestFactory { public class BkjxRequestFactory extends RequestFactory {
public static HttpRequest sessionCookieRequest(String serviceTicket) { public static HttpRequest sessionCookieRequest(String serviceTicket) {

@ -1,11 +1,11 @@
package cn.wustlinghang.mywust.core.request.factory.undergrade.global; package cn.linghang.mywust.core.request.factory.undergrade.global;
import cn.wustlinghang.mywust.core.api.ConstantParams; import cn.linghang.mywust.core.api.ConstantParams;
import cn.wustlinghang.mywust.core.api.UndergradUrls; import cn.linghang.mywust.core.api.UndergradUrls;
import cn.wustlinghang.mywust.network.request.RequestFactory; import cn.linghang.mywust.core.request.factory.RequestFactory;
import cn.wustlinghang.mywust.core.request.factory.undergrade.BkjxRequestFactory; import cn.linghang.mywust.core.request.factory.undergrade.BkjxRequestFactory;
import cn.wustlinghang.mywust.network.entitys.FormBodyBuilder; import cn.linghang.mywust.network.entitys.FormBodyBuilder;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.network.entitys.HttpRequest;
public class BkjxAllCourseRequestFactory extends BkjxRequestFactory { public class BkjxAllCourseRequestFactory extends BkjxRequestFactory {
public static HttpRequest classroomCoursePageRequest(String cookies, String term, String timeMode, String collegeId, String campusId, String buildingId, String classroomName) { public static HttpRequest classroomCoursePageRequest(String cookies, String term, String timeMode, String collegeId, String campusId, String buildingId, String classroomName) {
@ -54,7 +54,7 @@ public class BkjxAllCourseRequestFactory extends BkjxRequestFactory {
.add("kbjcmsid", timeMode == null ? ConstantParams.DEFAULT_TIME_MODEL : timeMode) .add("kbjcmsid", timeMode == null ? ConstantParams.DEFAULT_TIME_MODEL : timeMode)
// 上课学院,虽然能获取到,但是不符合预期的功能,得到的结果是这个学院上的课,而不是这个学院开的课 // 上课学院,虽然能获取到,但是不符合预期的功能,得到的结果是这个学院上的课,而不是这个学院开的课
.add("skyx", "") .add("skyx", "")
// 开课学院应该在这里指定,但是直接用学院id是获取不到的,只能用学院下级的id来获取,相关参数详见cn.wustlinghang.mywust.core.api.ConstantParams // 开课学院应该在这里指定,但是直接用学院id是获取不到的,只能用学院下级的id来获取,相关参数详见cn.linghang.mywust.core.api.ConstantParams
.add("kkyx", subCollegeId) .add("kkyx", subCollegeId)
.add("kcmc", courseName) .add("kcmc", courseName)
.add("zzdKcSX", "") .add("zzdKcSX", "")

@ -1,17 +1,16 @@
package cn.wustlinghang.mywust.core.request.service.auth; package cn.linghang.mywust.core.request.service.auth;
import cn.wustlinghang.mywust.captcha.SolvedImageCaptcha; import cn.linghang.mywust.captcha.SolvedImageCaptcha;
import cn.wustlinghang.mywust.captcha.UnsolvedImageCaptcha; import cn.linghang.mywust.captcha.UnsolvedImageCaptcha;
import cn.wustlinghang.mywust.core.api.GraduateUrls; import cn.linghang.mywust.core.api.GraduateUrls;
import cn.wustlinghang.mywust.exception.ApiException; import cn.linghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.network.request.RequestFactory; import cn.linghang.mywust.core.request.factory.RequestFactory;
import cn.wustlinghang.mywust.core.request.factory.graduate.GraduateRequestFactory; import cn.linghang.mywust.core.request.factory.graduate.GraduateRequestFactory;
import cn.wustlinghang.mywust.core.request.service.captcha.solver.CaptchaSolver; import cn.linghang.mywust.core.request.service.captcha.solver.CaptchaSolver;
import cn.wustlinghang.mywust.network.RequestClientOption; import cn.linghang.mywust.network.RequestClientOption;
import cn.wustlinghang.mywust.network.Requester; import cn.linghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.network.entitys.HttpResponse; import cn.linghang.mywust.network.entitys.HttpResponse;
import lombok.extern.slf4j.Slf4j;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import java.awt.*; import java.awt.*;
@ -20,7 +19,6 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
@Slf4j
public class GraduateLogin { public class GraduateLogin {
private final Requester requester; private final Requester requester;
@ -51,43 +49,18 @@ public class GraduateLogin {
SolvedImageCaptcha solvedImageCaptcha = captchaSolver.solve(unsolvedImageCaptcha); SolvedImageCaptcha solvedImageCaptcha = captchaSolver.solve(unsolvedImageCaptcha);
// 进行登录 // 进行登录
String loginIndexHtml = loginIndexResponse.getStringBody(); HttpRequest loginRequest = GraduateRequestFactory.loginRequest(username, password, loginIndexResponse.getStringBody(), solvedImageCaptcha);
HttpRequest loginRequest = GraduateRequestFactory.loginRequest(username, password, loginIndexHtml, solvedImageCaptcha);
HttpResponse loginResponse = requester.post(loginRequest, option); HttpResponse loginResponse = requester.post(loginRequest, option);
// 登陆成功,应该会是302跳转,不是的话多半是认证错误 // 登陆成功,应该会是302跳转,不是的话多半是认证错误
if (loginResponse.getStatusCode() != HttpResponse.HTTP_REDIRECT_302) { if (loginResponse.getStatusCode() != HttpResponse.HTTP_REDIRECT_302) {
String responseHtml = loginResponse.getStringBody(); throw new ApiException(ApiException.Code.GRADUATE_PASSWORD_WRONG);
if (responseHtml.contains("验证码错误")) {
throw new ApiException(ApiException.Code.GRADUATE_CAPTCHA_WRONG);
} else if (responseHtml.contains("密码错误") || responseHtml.contains("用户名不存在")) {
throw new ApiException(ApiException.Code.GRADUATE_PASSWORD_WRONG);
} else {
throw new ApiException(ApiException.Code.UNKNOWN_EXCEPTION);
}
} }
// 使用首页第一次访问得到的cookie来作为登录cookie // 使用首页第一次访问得到的cookie来作为登录cookie
return loginCookie; return loginCookie;
} }
public String getLoginCookie(String username, String password, int maxRetryTimes, RequestClientOption option)
throws IOException, ApiException {
for (int i = 0; i < maxRetryTimes; i++) {
try {
return getLoginCookie(username, password, option);
} catch (ApiException e) {
if (e.getCode() != ApiException.Code.GRADUATE_CAPTCHA_WRONG) {
throw e;
} else {
log.info("[mywust]: Retrying login for {} time(s)", i);
}
}
}
return "";
}
public void checkCookies(String cookie, RequestClientOption option) throws ApiException, IOException { public void checkCookies(String cookie, RequestClientOption option) throws ApiException, IOException {
HttpRequest request = RequestFactory.makeHttpRequest(GraduateUrls.GRADUATE_INDEX_TEST_API, null, cookie); HttpRequest request = RequestFactory.makeHttpRequest(GraduateUrls.GRADUATE_INDEX_TEST_API, null, cookie);
HttpResponse response = requester.get(request, option); HttpResponse response = requester.get(request, option);

@ -1,13 +1,13 @@
package cn.wustlinghang.mywust.core.request.service.auth; package cn.linghang.mywust.core.request.service.auth;
import cn.wustlinghang.mywust.core.api.LibraryUrls; import cn.linghang.mywust.core.api.LibraryUrls;
import cn.wustlinghang.mywust.core.api.UnionAuthUrls; import cn.linghang.mywust.core.api.UnionAuthUrls;
import cn.wustlinghang.mywust.core.request.factory.library.LibraryRequestFactory; import cn.linghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ApiException; import cn.linghang.mywust.core.request.factory.library.LibraryRequestFactory;
import cn.wustlinghang.mywust.network.RequestClientOption; import cn.linghang.mywust.network.RequestClientOption;
import cn.wustlinghang.mywust.network.Requester; import cn.linghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.network.entitys.HttpResponse; import cn.linghang.mywust.network.entitys.HttpResponse;
import java.io.IOException; import java.io.IOException;
@ -30,15 +30,10 @@ public class LibraryLogin {
HttpResponse sessionResponse = requester.get(sessionRequest, requestOption); HttpResponse sessionResponse = requester.get(sessionRequest, requestOption);
String cookies = sessionResponse.getCookies(); String cookies = sessionResponse.getCookies();
// 请求一次首页,这次获得的cookie才是真正的cookie // 请求一次首页
HttpRequest indexRequest = LibraryRequestFactory.indexRequest(); HttpRequest indexRequest = LibraryRequestFactory.indexRequest();
indexRequest.setCookies(cookies); indexRequest.setCookies(cookies);
HttpResponse indexResponse = requester.get(indexRequest, requestOption); requester.get(indexRequest, requestOption);
cookies = indexResponse.getCookies() != null ? indexResponse.getCookies() : cookies;
if (!checkCookie(cookies)) {
throw new ApiException(ApiException.Code.COOKIE_INVALID);
}
return cookies; return cookies;
} }

@ -1,13 +1,13 @@
package cn.wustlinghang.mywust.core.request.service.auth; package cn.linghang.mywust.core.request.service.auth;
import cn.wustlinghang.mywust.core.parser.physics.PhysicsIndexPageParser; import cn.linghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.core.request.factory.physics.PhysicsSystemRequestFactory; import cn.linghang.mywust.exception.ParseException;
import cn.wustlinghang.mywust.exception.ApiException; import cn.linghang.mywust.core.parser.physics.PhysicsIndexPageParser;
import cn.wustlinghang.mywust.exception.ParseException; import cn.linghang.mywust.core.request.factory.physics.PhysicsSystemRequestFactory;
import cn.wustlinghang.mywust.network.RequestClientOption; import cn.linghang.mywust.network.RequestClientOption;
import cn.wustlinghang.mywust.network.Requester; import cn.linghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.network.entitys.HttpResponse; import cn.linghang.mywust.network.entitys.HttpResponse;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -34,14 +34,7 @@ public class PhysicsLogin {
HttpRequest loginCookieRequest = PhysicsSystemRequestFactory.loginCookiesRequest(username, password, loginIndex); HttpRequest loginCookieRequest = PhysicsSystemRequestFactory.loginCookiesRequest(username, password, loginIndex);
HttpResponse loginCookieResponse = requester.post(loginCookieRequest, requestClientOption); HttpResponse loginCookieResponse = requester.post(loginCookieRequest, requestClientOption);
if (loginCookieResponse.getStatusCode() != HttpResponse.HTTP_REDIRECT_302) { if (loginCookieResponse.getStatusCode() != HttpResponse.HTTP_REDIRECT_302) {
String responseHtml = loginCookieResponse.getStringBody(); throw new ApiException(ApiException.Code.PHYSICS_PASSWORD_WRONG);
if (responseHtml.contains("该用户不存在于当前学期")){
throw new ApiException(ApiException.Code.PHYSICS_NOT_CURRENT_TERM);
} else if (responseHtml.contains("用户名或者密码有误")) {
throw new ApiException(ApiException.Code.PHYSICS_PASSWORD_WRONG);
} else {
throw new ApiException(ApiException.Code.UNKNOWN_EXCEPTION);
}
} }
String loginCookies = loginCookieResponse.getCookies(); String loginCookies = loginCookieResponse.getCookies();
@ -62,7 +55,7 @@ public class PhysicsLogin {
String redirect = physicsIndexPageParser.parse(indexHtml); String redirect = physicsIndexPageParser.parse(indexHtml);
HttpRequest systemIndexRequest = PhysicsSystemRequestFactory.physicsSystemIndexRequest(redirect, loginCookies); HttpRequest systemIndexRequest = PhysicsSystemRequestFactory.physicsSystemIndexRequest(redirect, loginCookies);
requestClientOption.setFollowUrlRedirect(true); requestClientOption.setFallowUrlRedirect(true);
HttpResponse response = requester.get(systemIndexRequest, requestClientOption); HttpResponse response = requester.get(systemIndexRequest, requestClientOption);
if (response.getStatusCode() != HttpResponse.HTTP_OK) { if (response.getStatusCode() != HttpResponse.HTTP_OK) {
throw new ApiException(ApiException.Code.COOKIE_INVALID); throw new ApiException(ApiException.Code.COOKIE_INVALID);
@ -70,11 +63,4 @@ public class PhysicsLogin {
return loginCookies; return loginCookies;
} }
public boolean checkCookie(String cookie, RequestClientOption option) throws IOException {
HttpRequest testRequest = PhysicsSystemRequestFactory.physicsSystemIndexRequest(cookie);
HttpResponse testResponse = requester.get(testRequest, option);
return testResponse.getStatusCode() != HttpResponse.HTTP_REDIRECT_302;
}
} }

@ -1,14 +1,14 @@
package cn.wustlinghang.mywust.core.request.service.auth; package cn.linghang.mywust.core.request.service.auth;
import cn.wustlinghang.mywust.core.api.UndergradUrls; import cn.linghang.mywust.core.api.UndergradUrls;
import cn.wustlinghang.mywust.core.api.UnionAuthUrls; import cn.linghang.mywust.core.api.UnionAuthUrls;
import cn.wustlinghang.mywust.exception.ApiException; import cn.linghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.core.request.factory.undergrade.BkjxRequestFactory; import cn.linghang.mywust.core.request.factory.undergrade.BkjxRequestFactory;
import cn.wustlinghang.mywust.network.RequestClientOption; import cn.linghang.mywust.network.RequestClientOption;
import cn.wustlinghang.mywust.network.Requester; import cn.linghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.network.entitys.HttpResponse; import cn.linghang.mywust.network.entitys.HttpResponse;
import cn.wustlinghang.mywust.util.PasswordEncoder; import cn.linghang.mywust.util.PasswordEncoder;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -84,46 +84,36 @@ public class UndergraduateLogin {
} }
private void checkCookie(String cookies, RequestClientOption requestOption) throws ApiException, IOException { private void checkCookie(String cookies, RequestClientOption requestOption) throws ApiException, IOException {
if (!roughCheckCookie(cookies)) { if (roughCheckCookieFail(cookies)) {
log.error("[mywust]: Cookie粗查不通过:{}", cookies); log.error("[mywust]: Cookie粗查不通过:{}", cookies);
throw new ApiException(ApiException.Code.UNKNOWN_EXCEPTION, "登录获取的Cookie无效"); throw new ApiException(ApiException.Code.UNKNOWN_EXCEPTION, "登录获取的Cookie无效");
} }
// 检查Cookie是否真正可用,同时请求一次任意接口使后续接口能够正确响应 // 检查Cookie是否真正可用,同时请求一次任意接口使后续接口能够正确响应
// 拿到Cookie后调用的第一个接口有时候会产生302/301跳转到主页,需要再次调用才能正确响应 // 拿到Cookie后调用的第一个接口有时候会产生302/301跳转到主页,需要再次调用才能正确响应
if (!testCookie(cookies, requestOption)) { if (checkCookiesFail(cookies, requestOption)) {
log.warn("[mywust]: Cookie检查不通过:{}", cookies); log.warn("[mywust]: Cookie检查不通过:{}", cookies);
} }
} }
private boolean roughCheckCookie(String cookies) { private boolean roughCheckCookieFail(String cookies) {
return cookies != null && cookies.contains("JSESSIONID") && cookies.contains("SERVERID"); return cookies == null || !cookies.contains("JSESSIONID") || !cookies.contains("SERVERID");
} }
public boolean testCookie(String cookies, RequestClientOption option) throws IOException, ApiException { private static final int COOKIES_ERROR_RESPONSE_LENGTH =
("<script languge='javascript'>window.location.href='https://auth.wust.edu.cn/lyuapServer/login?service=http%3A%2F%2Fbkjx.wust.edu.cn%2Fjsxsd%2Fframework%2FblankPage.jsp'</script>")
.length();
public boolean checkCookiesFail(String cookies, RequestClientOption option) throws IOException {
HttpRequest testRequest = BkjxRequestFactory.makeHttpRequest(UndergradUrls.BKJX_TEST_API, null, cookies); HttpRequest testRequest = BkjxRequestFactory.makeHttpRequest(UndergradUrls.BKJX_TEST_API, null, cookies);
HttpResponse testResponse = requester.get(testRequest, option); HttpResponse testResponse = requester.get(testRequest, option);
// 空白页返回的是很短的几个换行符,优先判断响应长度,暂时定为8 // 判断响应长度是否为这么多个字,登录跳转响应长度
if (testResponse.getBody().length < 8) { // 这种办法虽然在极端情况下可能会出错(而且还挺蠢的),但是是最快的办法中比较准确的了
return true; return Math.abs(COOKIES_ERROR_RESPONSE_LENGTH - testResponse.getBody().length) <= 8;
}
String test = testResponse.getStringBody();
if (test.contains("script")) {
return false;
} else if (test.contains("禁用")) {
// 选课时间段
throw new ApiException(ApiException.Code.UNDERGRAD_BANNED_IN_EXCLUSIVE_TIME);
} else if (test.contains("不存在")) {
// 新生信息未录入/老生被删号
throw new ApiException(ApiException.Code.UNDERGRAD_USERINFO_NOT_EXISTS);
}
return true;
} }
public boolean testCookie(String cookies) throws IOException, ApiException { public boolean checkCookiesFail(String cookies) throws IOException {
return this.testCookie(cookies, null); return this.checkCookiesFail(cookies, null);
} }
} }

@ -1,12 +1,12 @@
package cn.wustlinghang.mywust.core.request.service.auth; package cn.linghang.mywust.core.request.service.auth;
import cn.wustlinghang.mywust.exception.ApiException; import cn.linghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.core.request.factory.auth.UnionAuthRequestFactory; import cn.linghang.mywust.core.request.factory.auth.UnionAuthRequestFactory;
import cn.wustlinghang.mywust.network.RequestClientOption; import cn.linghang.mywust.network.RequestClientOption;
import cn.wustlinghang.mywust.network.Requester; import cn.linghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.network.entitys.HttpResponse; import cn.linghang.mywust.network.entitys.HttpResponse;
import cn.wustlinghang.mywust.util.PasswordEncoder; import cn.linghang.mywust.util.PasswordEncoder;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;

@ -0,0 +1,9 @@
package cn.linghang.mywust.core.request.service.captcha.solver;
import cn.linghang.mywust.captcha.SolvedImageCaptcha;
import cn.linghang.mywust.captcha.UnsolvedImageCaptcha;
import cn.linghang.mywust.exception.ApiException;
public interface CaptchaSolver {
SolvedImageCaptcha solve(UnsolvedImageCaptcha unsolvedImageCaptcha) throws ApiException;
}

@ -1,12 +1,12 @@
package cn.wustlinghang.mywust.core.request.service.captcha.solver; package cn.linghang.mywust.core.request.service.captcha.solver;
import cn.wustlinghang.mywust.captcha.SolvedImageCaptcha; import cn.linghang.mywust.captcha.SolvedImageCaptcha;
import cn.wustlinghang.mywust.captcha.UnsolvedImageCaptcha; import cn.linghang.mywust.captcha.UnsolvedImageCaptcha;
import cn.wustlinghang.mywust.exception.ApiException; import cn.linghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.network.request.RequestFactory; import cn.linghang.mywust.core.request.factory.RequestFactory;
import cn.wustlinghang.mywust.network.Requester; import cn.linghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.network.entitys.HttpResponse; import cn.linghang.mywust.network.entitys.HttpResponse;
import java.io.IOException; import java.io.IOException;
import java.util.Base64; import java.util.Base64;

@ -1,14 +1,14 @@
package cn.wustlinghang.mywust.core.request.service.captcha.solver; package cn.linghang.mywust.core.request.service.captcha.solver;
import cn.wustlinghang.mywust.captcha.SolvedImageCaptcha; import cn.linghang.mywust.captcha.SolvedImageCaptcha;
import cn.wustlinghang.mywust.captcha.UnsolvedImageCaptcha; import cn.linghang.mywust.captcha.UnsolvedImageCaptcha;
import cn.wustlinghang.mywust.exception.ApiException; import cn.linghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.network.request.RequestFactory; import cn.linghang.mywust.core.request.factory.RequestFactory;
import cn.wustlinghang.mywust.network.RequestClientOption; import cn.linghang.mywust.network.RequestClientOption;
import cn.wustlinghang.mywust.network.Requester; import cn.linghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.network.entitys.HttpResponse; import cn.linghang.mywust.network.entitys.HttpResponse;
import cn.wustlinghang.mywust.util.StringUtil; import cn.linghang.mywust.util.StringUtil;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;

@ -1,12 +1,12 @@
package cn.wustlinghang.mywust.core.request.service.graduate; package cn.linghang.mywust.core.request.service.graduate;
import cn.wustlinghang.mywust.core.api.GraduateUrls; import cn.linghang.mywust.core.api.GraduateUrls;
import cn.wustlinghang.mywust.exception.ApiException; import cn.linghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.network.request.RequestFactory; import cn.linghang.mywust.core.request.factory.RequestFactory;
import cn.wustlinghang.mywust.network.RequestClientOption; import cn.linghang.mywust.network.RequestClientOption;
import cn.wustlinghang.mywust.network.Requester; import cn.linghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.network.entitys.HttpResponse; import cn.linghang.mywust.network.entitys.HttpResponse;
import java.io.IOException; import java.io.IOException;

@ -1,11 +1,11 @@
package cn.wustlinghang.mywust.core.request.service.graduate; package cn.linghang.mywust.core.request.service.graduate;
import cn.wustlinghang.mywust.exception.ApiException; import cn.linghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.core.request.factory.graduate.GraduateRequestFactory; import cn.linghang.mywust.core.request.factory.graduate.GraduateRequestFactory;
import cn.wustlinghang.mywust.network.RequestClientOption; import cn.linghang.mywust.network.RequestClientOption;
import cn.wustlinghang.mywust.network.Requester; import cn.linghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.network.entitys.HttpResponse; import cn.linghang.mywust.network.entitys.HttpResponse;
import java.io.IOException; import java.io.IOException;
@ -23,6 +23,6 @@ public class GraduateCourseTableApiService extends GraduateApiServiceBase {
HttpResponse response = requester.get(request, option); HttpResponse response = requester.get(request, option);
super.checkResponse(response); super.checkResponse(response);
return response.getStringBody(); return new String(response.getBody());
} }
} }

@ -1,11 +1,11 @@
package cn.wustlinghang.mywust.core.request.service.graduate; package cn.linghang.mywust.core.request.service.graduate;
import cn.wustlinghang.mywust.exception.ApiException; import cn.linghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.core.request.factory.graduate.GraduateRequestFactory; import cn.linghang.mywust.core.request.factory.graduate.GraduateRequestFactory;
import cn.wustlinghang.mywust.network.RequestClientOption; import cn.linghang.mywust.network.RequestClientOption;
import cn.wustlinghang.mywust.network.Requester; import cn.linghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.network.entitys.HttpResponse; import cn.linghang.mywust.network.entitys.HttpResponse;
import java.io.IOException; import java.io.IOException;
@ -22,6 +22,6 @@ public class GraduateScoreApiService extends GraduateApiServiceBase {
HttpResponse response = requester.get(request, option); HttpResponse response = requester.get(request, option);
super.checkResponse(response); super.checkResponse(response);
return response.getStringBody(); return new String(response.getBody());
} }
} }

@ -1,11 +1,11 @@
package cn.wustlinghang.mywust.core.request.service.graduate; package cn.linghang.mywust.core.request.service.graduate;
import cn.wustlinghang.mywust.exception.ApiException; import cn.linghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.core.request.factory.graduate.GraduateRequestFactory; import cn.linghang.mywust.core.request.factory.graduate.GraduateRequestFactory;
import cn.wustlinghang.mywust.network.RequestClientOption; import cn.linghang.mywust.network.RequestClientOption;
import cn.wustlinghang.mywust.network.Requester; import cn.linghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.network.entitys.HttpResponse; import cn.linghang.mywust.network.entitys.HttpResponse;
import java.io.IOException; import java.io.IOException;
@ -22,6 +22,6 @@ public class GraduateStudentInfoApiService extends GraduateApiServiceBase {
HttpResponse response = requester.get(request, option); HttpResponse response = requester.get(request, option);
super.checkResponse(response); super.checkResponse(response);
return response.getStringBody(); return new String(response.getBody());
} }
} }

@ -1,11 +1,11 @@
package cn.wustlinghang.mywust.core.request.service.graduate; package cn.linghang.mywust.core.request.service.graduate;
import cn.wustlinghang.mywust.exception.ApiException; import cn.linghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.core.request.factory.graduate.GraduateRequestFactory; import cn.linghang.mywust.core.request.factory.graduate.GraduateRequestFactory;
import cn.wustlinghang.mywust.network.RequestClientOption; import cn.linghang.mywust.network.RequestClientOption;
import cn.wustlinghang.mywust.network.Requester; import cn.linghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.network.entitys.HttpResponse; import cn.linghang.mywust.network.entitys.HttpResponse;
import java.io.IOException; import java.io.IOException;
@ -22,6 +22,6 @@ public class GraduateTrainingPlanApiService extends GraduateApiServiceBase {
HttpResponse response = requester.get(request, option); HttpResponse response = requester.get(request, option);
super.checkResponse(response); super.checkResponse(response);
return response.getStringBody(); return new String(response.getBody());
} }
} }

@ -0,0 +1,66 @@
package cn.linghang.mywust.core.request.service.library;
import cn.linghang.mywust.exception.ApiException;
import cn.linghang.mywust.core.request.factory.library.LibraryRequestFactory;
import cn.linghang.mywust.network.Requester;
import cn.linghang.mywust.network.entitys.HttpRequest;
import cn.linghang.mywust.network.entitys.HttpResponse;
import java.io.IOException;
/**
* 图书馆相关接口由于返回的数据都是json特别好解析所以这里的数据获取到了之后可以直接拿来用自己来解析
*/
public class LibraryApiService extends LibraryApiServiceBase {
public LibraryApiService(Requester requester) {
super(requester);
}
public String search(String keyword, int page, int pageSize) throws ApiException, IOException {
HttpRequest request = LibraryRequestFactory.bookSearchRequest(keyword, page, pageSize);
HttpResponse response = requester.post(request);
checkResponse(response);
return response.getStringBody();
}
public String getBookDetail(String bookId) throws ApiException, IOException {
HttpRequest request = LibraryRequestFactory.bookInfoRequest(bookId);
HttpResponse response = requester.get(request);
checkResponse(response);
return response.getStringBody();
}
public String getBookCoverImageUrl(String isbn) throws ApiException, IOException {
HttpRequest request = LibraryRequestFactory.bookCoverImageUrlRequest(isbn);
HttpResponse response = requester.get(request);
checkResponse(response);
return response.getStringBody();
}
public String getOverdueSoon(String cookie) throws ApiException, IOException {
HttpRequest request = LibraryRequestFactory.overdueSoonRequest(cookie);
HttpResponse response = requester.get(request);
checkResponse(response);
return response.getStringBody();
}
public String getCurrentLoan(String cookie) throws ApiException, IOException {
HttpRequest request = LibraryRequestFactory.currentLoanRequest(cookie);
HttpResponse response = requester.get(request);
checkResponse(response);
return response.getStringBody();
}
public String getLoanHistory(String cookie) throws ApiException, IOException {
HttpRequest request = LibraryRequestFactory.loanHistoryRequest(cookie);
HttpResponse response = requester.get(request);
checkResponse(response);
return response.getStringBody();
}
}

@ -0,0 +1,20 @@
package cn.linghang.mywust.core.request.service.library;
import cn.linghang.mywust.exception.ApiException;
import cn.linghang.mywust.network.Requester;
import cn.linghang.mywust.network.entitys.HttpResponse;
public abstract class LibraryApiServiceBase {
protected final Requester requester;
public LibraryApiServiceBase(Requester requester) {
this.requester = requester;
}
public void checkResponse(HttpResponse response) throws ApiException {
// 检查响应是否正确
if (response.getStatusCode() != 200) {
throw new ApiException(ApiException.Code.COOKIE_INVALID);
}
}
}

@ -1,8 +1,8 @@
package cn.wustlinghang.mywust.core.request.service.physics; package cn.linghang.mywust.core.request.service.physics;
import cn.wustlinghang.mywust.exception.ApiException; import cn.linghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.network.Requester; import cn.linghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpResponse; import cn.linghang.mywust.network.entitys.HttpResponse;
public abstract class PhysicsApiServiceBase { public abstract class PhysicsApiServiceBase {
protected final Requester requester; protected final Requester requester;

@ -1,11 +1,11 @@
package cn.wustlinghang.mywust.core.request.service.physics; package cn.linghang.mywust.core.request.service.physics;
import cn.wustlinghang.mywust.exception.ApiException; import cn.linghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.core.request.factory.physics.PhysicsSystemRequestFactory; import cn.linghang.mywust.core.request.factory.physics.PhysicsSystemRequestFactory;
import cn.wustlinghang.mywust.network.RequestClientOption; import cn.linghang.mywust.network.RequestClientOption;
import cn.wustlinghang.mywust.network.Requester; import cn.linghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.network.entitys.HttpResponse; import cn.linghang.mywust.network.entitys.HttpResponse;
import java.io.IOException; import java.io.IOException;
@ -15,7 +15,7 @@ public class PhysicsCourseApiService extends PhysicsApiServiceBase {
} }
public String getPage(String cookie, RequestClientOption requestClientOption) throws IOException, ApiException { public String getPage(String cookie, RequestClientOption requestClientOption) throws IOException, ApiException {
requestClientOption.setFollowUrlRedirect(false); requestClientOption.setFallowUrlRedirect(false);
// 直接请求真正的课表页 // 直接请求真正的课表页
HttpRequest coursePageRequest = PhysicsSystemRequestFactory.physicsCourseRequest(cookie); HttpRequest coursePageRequest = PhysicsSystemRequestFactory.physicsCourseRequest(cookie);

@ -1,14 +1,14 @@
package cn.wustlinghang.mywust.core.request.service.physics; package cn.linghang.mywust.core.request.service.physics;
import cn.wustlinghang.mywust.exception.ApiException; import cn.linghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException; import cn.linghang.mywust.exception.ParseException;
import cn.wustlinghang.mywust.core.parser.physics.PhysicsScoreListPageParser; import cn.linghang.mywust.core.parser.physics.PhysicsScoreListPageParser;
import cn.wustlinghang.mywust.core.request.factory.physics.PhysicsSystemRequestFactory; import cn.linghang.mywust.core.request.factory.physics.PhysicsSystemRequestFactory;
import cn.wustlinghang.mywust.core.util.PageFormExtractor; import cn.linghang.mywust.core.util.PageFormExtractor;
import cn.wustlinghang.mywust.network.RequestClientOption; import cn.linghang.mywust.network.RequestClientOption;
import cn.wustlinghang.mywust.network.Requester; import cn.linghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.network.entitys.HttpResponse; import cn.linghang.mywust.network.entitys.HttpResponse;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;

@ -1,13 +1,13 @@
package cn.wustlinghang.mywust.core.request.service.undergraduate; package cn.linghang.mywust.core.request.service.undergraduate;
import cn.wustlinghang.mywust.core.api.UndergradUrls; import cn.linghang.mywust.core.api.UndergradUrls;
import cn.wustlinghang.mywust.core.util.BkjxUtil; import cn.linghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ApiException; import cn.linghang.mywust.core.request.factory.RequestFactory;
import cn.wustlinghang.mywust.network.RequestClientOption; import cn.linghang.mywust.core.util.BkjxUtil;
import cn.wustlinghang.mywust.network.Requester; import cn.linghang.mywust.network.RequestClientOption;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpResponse; import cn.linghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.network.request.RequestFactory; import cn.linghang.mywust.network.entitys.HttpResponse;
import java.io.IOException; import java.io.IOException;
import java.util.Map; import java.util.Map;
@ -21,13 +21,11 @@ public abstract class UndergradApiServiceBase {
public void checkResponse(HttpResponse response) throws ApiException { public void checkResponse(HttpResponse response) throws ApiException {
// 检查响应是否正确 // 检查响应是否正确
boolean cookieInvalid = response.getBody() == null || if (response.getBody() == null ||
response.getStatusCode() != HttpResponse.HTTP_OK || response.getStatusCode() != HttpResponse.HTTP_OK ||
BkjxUtil.needLogin(response.getBody()); BkjxUtil.hasLoginFinger(response.getBody())) {
if (cookieInvalid) {
throw new ApiException(ApiException.Code.COOKIE_INVALID); throw new ApiException(ApiException.Code.COOKIE_INVALID);
} else if (BkjxUtil.isBannedResponse(response)) {
throw new ApiException(ApiException.Code.UNDERGRAD_BANNED_IN_EXCLUSIVE_TIME);
} }
} }
@ -43,6 +41,5 @@ public abstract class UndergradApiServiceBase {
} }
public abstract String getPage(String cookie, Map<String, String> params, RequestClientOption option) throws ApiException, IOException; public abstract String getPage(String cookie, Map<String, String> params, RequestClientOption option) throws ApiException, IOException;
public abstract String getPage(String cookie, Map<String, String> params) throws ApiException, IOException; public abstract String getPage(String cookie, Map<String, String> params) throws ApiException, IOException;
} }

@ -1,11 +1,11 @@
package cn.wustlinghang.mywust.core.request.service.undergraduate; package cn.linghang.mywust.core.request.service.undergraduate;
import cn.wustlinghang.mywust.exception.ApiException; import cn.linghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.core.request.factory.undergrade.BkjxRequestFactory; import cn.linghang.mywust.core.request.factory.undergrade.BkjxRequestFactory;
import cn.wustlinghang.mywust.network.RequestClientOption; import cn.linghang.mywust.network.RequestClientOption;
import cn.wustlinghang.mywust.network.Requester; import cn.linghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.network.entitys.HttpResponse; import cn.linghang.mywust.network.entitys.HttpResponse;
import java.io.IOException; import java.io.IOException;
import java.util.Map; import java.util.Map;
@ -40,7 +40,7 @@ public class UndergradCourseTableApiService extends UndergradApiServiceBase {
super.checkResponse(response); super.checkResponse(response);
return response.getStringBody(); return new String(response.getBody());
} }
public String getPage(String term, String cookies) throws IOException, ApiException { public String getPage(String term, String cookies) throws IOException, ApiException {

@ -1,13 +1,13 @@
package cn.wustlinghang.mywust.core.request.service.undergraduate; package cn.linghang.mywust.core.request.service.undergraduate;
import cn.wustlinghang.mywust.exception.ApiException; import cn.linghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException; import cn.linghang.mywust.exception.ParseException;
import cn.wustlinghang.mywust.core.parser.undergraduate.UndergradCreditStatusIndexParser; import cn.linghang.mywust.core.parser.undergraduate.UndergradCreditStatusIndexParser;
import cn.wustlinghang.mywust.core.request.factory.undergrade.BkjxRequestFactory; import cn.linghang.mywust.core.request.factory.undergrade.BkjxRequestFactory;
import cn.wustlinghang.mywust.network.RequestClientOption; import cn.linghang.mywust.network.RequestClientOption;
import cn.wustlinghang.mywust.network.Requester; import cn.linghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.network.entitys.HttpResponse; import cn.linghang.mywust.network.entitys.HttpResponse;
import java.io.IOException; import java.io.IOException;
import java.util.Map; import java.util.Map;

@ -1,11 +1,11 @@
package cn.wustlinghang.mywust.core.request.service.undergraduate; package cn.linghang.mywust.core.request.service.undergraduate;
import cn.wustlinghang.mywust.exception.ApiException; import cn.linghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.core.request.factory.undergrade.BkjxRequestFactory; import cn.linghang.mywust.core.request.factory.undergrade.BkjxRequestFactory;
import cn.wustlinghang.mywust.network.RequestClientOption; import cn.linghang.mywust.network.RequestClientOption;
import cn.wustlinghang.mywust.network.Requester; import cn.linghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.network.entitys.HttpResponse; import cn.linghang.mywust.network.entitys.HttpResponse;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;

@ -1,11 +1,11 @@
package cn.wustlinghang.mywust.core.request.service.undergraduate; package cn.linghang.mywust.core.request.service.undergraduate;
import cn.wustlinghang.mywust.exception.ApiException; import cn.linghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.core.request.factory.undergrade.BkjxRequestFactory; import cn.linghang.mywust.core.request.factory.undergrade.BkjxRequestFactory;
import cn.wustlinghang.mywust.network.RequestClientOption; import cn.linghang.mywust.network.RequestClientOption;
import cn.wustlinghang.mywust.network.Requester; import cn.linghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.network.entitys.HttpResponse; import cn.linghang.mywust.network.entitys.HttpResponse;
import java.io.IOException; import java.io.IOException;
import java.util.Map; import java.util.Map;
@ -32,7 +32,7 @@ public class UndergradScoreApiService extends UndergradApiServiceBase {
super.checkResponse(response); super.checkResponse(response);
return response.getStringBody(); return new String(response.getBody());
} }
public String getPage(String cookies) throws IOException, ApiException { public String getPage(String cookies) throws IOException, ApiException {

@ -1,11 +1,11 @@
package cn.wustlinghang.mywust.core.request.service.undergraduate; package cn.linghang.mywust.core.request.service.undergraduate;
import cn.wustlinghang.mywust.exception.ApiException; import cn.linghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.core.request.factory.undergrade.BkjxRequestFactory; import cn.linghang.mywust.core.request.factory.undergrade.BkjxRequestFactory;
import cn.wustlinghang.mywust.network.RequestClientOption; import cn.linghang.mywust.network.RequestClientOption;
import cn.wustlinghang.mywust.network.Requester; import cn.linghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.network.entitys.HttpResponse; import cn.linghang.mywust.network.entitys.HttpResponse;
import java.io.IOException; import java.io.IOException;
import java.util.Map; import java.util.Map;
@ -32,7 +32,7 @@ public class UndergradStudentInfoApiService extends UndergradApiServiceBase {
super.checkResponse(response); super.checkResponse(response);
return response.getStringBody(); return new String(response.getBody());
} }
public String getPage(String cookies) throws IOException, ApiException { public String getPage(String cookies) throws IOException, ApiException {

@ -1,11 +1,11 @@
package cn.wustlinghang.mywust.core.request.service.undergraduate; package cn.linghang.mywust.core.request.service.undergraduate;
import cn.wustlinghang.mywust.exception.ApiException; import cn.linghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.core.request.factory.undergrade.BkjxRequestFactory; import cn.linghang.mywust.core.request.factory.undergrade.BkjxRequestFactory;
import cn.wustlinghang.mywust.network.RequestClientOption; import cn.linghang.mywust.network.RequestClientOption;
import cn.wustlinghang.mywust.network.Requester; import cn.linghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.network.entitys.HttpResponse; import cn.linghang.mywust.network.entitys.HttpResponse;
import java.io.IOException; import java.io.IOException;
import java.util.Map; import java.util.Map;
@ -32,7 +32,7 @@ public class UndergradTrainingPlanApiService extends UndergradApiServiceBase {
super.checkResponse(response); super.checkResponse(response);
return response.getStringBody(); return new String(response.getBody());
} }
public String getPage(String cookies) throws IOException, ApiException { public String getPage(String cookies) throws IOException, ApiException {

@ -1,12 +1,12 @@
package cn.wustlinghang.mywust.core.request.service.undergraduate.global; package cn.linghang.mywust.core.request.service.undergraduate.global;
import cn.wustlinghang.mywust.exception.ApiException; import cn.linghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.core.request.factory.undergrade.global.BkjxAllCourseRequestFactory; import cn.linghang.mywust.core.request.factory.undergrade.global.BkjxAllCourseRequestFactory;
import cn.wustlinghang.mywust.core.request.service.undergraduate.UndergradApiServiceBase; import cn.linghang.mywust.core.request.service.undergraduate.UndergradApiServiceBase;
import cn.wustlinghang.mywust.network.RequestClientOption; import cn.linghang.mywust.network.RequestClientOption;
import cn.wustlinghang.mywust.network.Requester; import cn.linghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.network.entitys.HttpResponse; import cn.linghang.mywust.network.entitys.HttpResponse;
import java.io.IOException; import java.io.IOException;
import java.util.Map; import java.util.Map;

@ -1,15 +1,15 @@
package cn.wustlinghang.mywust.core.request.service.undergraduate.global; package cn.linghang.mywust.core.request.service.undergraduate.global;
import cn.wustlinghang.mywust.core.api.ConstantParams; import cn.linghang.mywust.core.api.ConstantParams;
import cn.wustlinghang.mywust.exception.ApiException; import cn.linghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.core.request.factory.undergrade.BkjxRequestFactory; import cn.linghang.mywust.core.request.factory.undergrade.BkjxRequestFactory;
import cn.wustlinghang.mywust.core.request.service.undergraduate.UndergradApiServiceBase; import cn.linghang.mywust.core.request.service.undergraduate.UndergradApiServiceBase;
import cn.wustlinghang.mywust.data.global.Building; import cn.linghang.mywust.data.global.Building;
import cn.wustlinghang.mywust.data.global.Campus; import cn.linghang.mywust.data.global.Campus;
import cn.wustlinghang.mywust.network.RequestClientOption; import cn.linghang.mywust.network.RequestClientOption;
import cn.wustlinghang.mywust.network.Requester; import cn.linghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.network.entitys.HttpResponse; import cn.linghang.mywust.network.entitys.HttpResponse;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;

@ -1,12 +1,12 @@
package cn.wustlinghang.mywust.core.request.service.undergraduate.global; package cn.linghang.mywust.core.request.service.undergraduate.global;
import cn.wustlinghang.mywust.exception.ApiException; import cn.linghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.core.request.factory.undergrade.global.BkjxAllCourseRequestFactory; import cn.linghang.mywust.core.request.factory.undergrade.global.BkjxAllCourseRequestFactory;
import cn.wustlinghang.mywust.core.request.service.undergraduate.UndergradApiServiceBase; import cn.linghang.mywust.core.request.service.undergraduate.UndergradApiServiceBase;
import cn.wustlinghang.mywust.network.RequestClientOption; import cn.linghang.mywust.network.RequestClientOption;
import cn.wustlinghang.mywust.network.Requester; import cn.linghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.network.entitys.HttpResponse; import cn.linghang.mywust.network.entitys.HttpResponse;
import java.io.IOException; import java.io.IOException;
import java.util.Map; import java.util.Map;

@ -1,12 +1,12 @@
package cn.wustlinghang.mywust.core.request.service.undergraduate.global; package cn.linghang.mywust.core.request.service.undergraduate.global;
import cn.wustlinghang.mywust.exception.ApiException; import cn.linghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.core.request.factory.undergrade.global.BkjxAllCourseRequestFactory; import cn.linghang.mywust.core.request.factory.undergrade.global.BkjxAllCourseRequestFactory;
import cn.wustlinghang.mywust.core.request.service.undergraduate.UndergradApiServiceBase; import cn.linghang.mywust.core.request.service.undergraduate.UndergradApiServiceBase;
import cn.wustlinghang.mywust.network.RequestClientOption; import cn.linghang.mywust.network.RequestClientOption;
import cn.wustlinghang.mywust.network.Requester; import cn.linghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpRequest; import cn.linghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.network.entitys.HttpResponse; import cn.linghang.mywust.network.entitys.HttpResponse;
import java.io.IOException; import java.io.IOException;
import java.util.Map; import java.util.Map;

@ -0,0 +1,32 @@
package cn.linghang.mywust.core.util;
import java.nio.charset.StandardCharsets;
/**
* 专属于bkjx本科教学系统服务的工具类
*/
public class BkjxUtil {
// 在“Bkjx”系统里边如果收到的响应开头是这个的话多半是cookie无效了,需要重新登录获取cookie
private static final byte[] LOGIN_MESSAGE_RESPONSE_FINGER = "<script".getBytes(StandardCharsets.UTF_8);
/**
* <p>通过粗暴地比较响应字节前几个字符是否为登录跳转特征字符判断是否需要重新登录</p>
* <p>对于null对象一律认为不需要</p>
*
* @param response 响应的字节
* @return 是否需要重新登录
*/
public static boolean hasLoginFinger(byte[] response) {
if (response == null) {
return false;
}
for (int i = 0; i < LOGIN_MESSAGE_RESPONSE_FINGER.length; i++) {
if (LOGIN_MESSAGE_RESPONSE_FINGER[i] != response[i]) {
return false;
}
}
return true;
}
}

@ -1,4 +1,4 @@
package cn.wustlinghang.mywust.core.util; package cn.linghang.mywust.core.util;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;
import org.jsoup.select.Elements; import org.jsoup.select.Elements;

@ -1,4 +1,4 @@
package cn.wustlinghang.mywust.core.util; package cn.linghang.mywust.core.util;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.nodes.Document; import org.jsoup.nodes.Document;

@ -1,7 +0,0 @@
package cn.wustlinghang.mywust.core.parser;
import cn.wustlinghang.mywust.exception.ParseException;
public interface Parser<T> {
public T parse(String html) throws ParseException;
}

@ -1,9 +0,0 @@
package cn.wustlinghang.mywust.core.request.service.captcha.solver;
import cn.wustlinghang.mywust.captcha.SolvedImageCaptcha;
import cn.wustlinghang.mywust.captcha.UnsolvedImageCaptcha;
import cn.wustlinghang.mywust.exception.ApiException;
public interface CaptchaSolver {
SolvedImageCaptcha solve(UnsolvedImageCaptcha unsolvedImageCaptcha) throws ApiException;
}

@ -1,82 +0,0 @@
package cn.wustlinghang.mywust.core.request.service.library;
import cn.wustlinghang.mywust.data.library.origin.BaseLoanBook;
import cn.wustlinghang.mywust.data.library.origin.BookSearchResult;
import cn.wustlinghang.mywust.data.library.origin.CurrentLoanBook;
import cn.wustlinghang.mywust.data.library.origin.HistoryLoanBook;
import cn.wustlinghang.mywust.data.library.parsed.BookHolding;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpResponse;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StringDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import java.io.IOException;
import java.util.List;
public abstract class BaseLibraryApiService {
protected static final ObjectMapper objectMapper = new ObjectMapper();
static {
objectMapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
SimpleModule module = new SimpleModule();
module.addDeserializer(String.class, new SpecialStringDeserializer());
objectMapper.registerModule(module);
}
protected static final JavaType loanBookListType =
objectMapper.getTypeFactory().constructParametricType(List.class, BaseLoanBook.class);
protected static final JavaType historyLoanBookListType =
objectMapper.getTypeFactory().constructParametricType(List.class, HistoryLoanBook.class);
protected static final JavaType currentLoanBookListType =
objectMapper.getTypeFactory().constructParametricType(List.class, CurrentLoanBook.class);
protected static final JavaType bookSearchResultListType =
objectMapper.getTypeFactory().constructParametricType(List.class, BookSearchResult.class);
protected static final JavaType bookHoldingListType =
objectMapper.getTypeFactory().constructParametricType(List.class, BookHolding.class);
protected final Requester requester;
public BaseLibraryApiService(Requester requester) {
this.requester = requester;
}
public void checkResponse(HttpResponse response) throws ApiException {
// 检查响应是否正确
if (response.getStatusCode() != 200) {
throw new ApiException(ApiException.Code.COOKIE_INVALID);
}
}
}
/**
* <p>继承自原版StringDeserializer特殊定制的字符串反序列化器</p>
* <p>测试时偶然发现的图书馆搜索api返回的json中`pub_year``abstract`等一些本应该是字符串值的字段有概率会出现为空数组的奇葩情况...</p>
* <p>想了半天也没想明白那系统究竟是怎么在字符串里蹦出`[]`...</p>
*/
class SpecialStringDeserializer extends StringDeserializer {
@Override
public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
// The critical path: ensure we handle the common case first.
if (p.hasToken(JsonToken.VALUE_STRING)) {
return p.getText();
}
// [databind#381]
if (p.hasToken(JsonToken.START_ARRAY)) {
// 仅修改了这行
return p.getValueAsString("");
}
return _parseString(p, ctxt, this);
}
}

@ -1,59 +0,0 @@
package cn.wustlinghang.mywust.core.request.service.library;
import cn.wustlinghang.mywust.core.request.factory.library.LibraryRequestFactory;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.network.entitys.HttpResponse;
import com.fasterxml.jackson.databind.JsonNode;
import java.io.IOException;
import java.util.*;
public class BookCoverImageUrlApiService extends BaseLibraryApiService {
public BookCoverImageUrlApiService(Requester requester) {
super(requester);
}
public List<String> getBookCoverImageUrl(String isbn) throws ApiException, IOException {
HttpRequest request = LibraryRequestFactory.bookCoverImageUrlRequest(isbn);
HttpResponse response = requester.get(request);
checkResponse(response);
// 因为只查了一本书,所以path(isbn)直接一步到位就行了
JsonNode imageResultJson = objectMapper.readTree(response.getBody()).path("data").path(isbn);
List<String> covers = new ArrayList<>(imageResultJson.size());
for (JsonNode resultItemJson : imageResultJson) {
covers.add(resultItemJson.path("imageUrl").asText()
.replaceAll("^//", "http://")
);
}
return covers;
}
public Map<String, List<String>> getBookCoverImageUrl(List<String> isbnList) throws ApiException, IOException {
HttpRequest request = LibraryRequestFactory.bookCoverImageUrlRequest(isbnList);
HttpResponse response = requester.get(request);
checkResponse(response);
JsonNode data = objectMapper.readTree(response.getBody()).path("data");
Map<String, List<String>> result = new HashMap<>(data.size());
// 遍历data下每本书
Iterator<Map.Entry<String, JsonNode>> it = data.fields();
while (it.hasNext()) {
Map.Entry<String, JsonNode> bookItemJson = it.next();
List<String> covers = new ArrayList<>(bookItemJson.getValue().size());
for (JsonNode resultItemJson : bookItemJson.getValue()) {
covers.add(resultItemJson.path("imageUrl").asText()
.replaceAll("^//", "http://")
);
}
result.put(bookItemJson.getKey(), covers);
}
return result;
}
}

@ -1,70 +0,0 @@
package cn.wustlinghang.mywust.core.request.service.library;
import cn.wustlinghang.mywust.core.request.factory.library.LibraryRequestFactory;
import cn.wustlinghang.mywust.data.library.parsed.BookDetail;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.network.entitys.HttpResponse;
import cn.wustlinghang.mywust.util.StringUtil;
import com.fasterxml.jackson.databind.JsonNode;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class BookDetailApiService extends BaseLibraryApiService {
public BookDetailApiService(Requester requester) {
super(requester);
}
public BookDetail getBookDetail(String bookId) throws ApiException, IOException {
HttpRequest infoRequest = LibraryRequestFactory.bookInfoRequest(bookId);
HttpResponse infoResponse = requester.get(infoRequest);
checkResponse(infoResponse);
JsonNode data = objectMapper.readTree(infoResponse.getBody())
.path("data").path("map");
JsonNode baseInfo = data.path("baseInfo").path("map");
JsonNode detailInfo = data.path("detailInfo").path("map");
Map<String, String> extraInfoMap = new HashMap<>(detailInfo.size());
Iterator<Map.Entry<String, JsonNode>> it = detailInfo.fields();
while (it.hasNext()) {
Map.Entry<String, JsonNode> field = it.next();
extraInfoMap.put(field.getKey(), StringUtil.cleanHtml(field.getValue().asText("无")));
}
String isbn = baseInfo.get("isbn").asText("无");
String author = baseInfo.path("author").asText("无");
String title = baseInfo.path("title").asText("无");
HttpRequest doubanInfoRequest = LibraryRequestFactory.bookDoubanInfoRequest(isbn);
HttpResponse doubanInfoResponse = requester.get(doubanInfoRequest);
checkResponse(doubanInfoResponse);
JsonNode doubanInfo = objectMapper.readTree(doubanInfoResponse.getBody()).path("data");
String authorDescribe = doubanInfo.path("authorInfo").asText("无");
String catalog = doubanInfo.path("catalog").asText("无");
String summary = doubanInfo.path("content").asText("无");
String introduction = doubanInfo.path("intro").asText(summary);
String coverUrl = doubanInfo.path("imageUrl").asText("")
.replaceAll("^//", "http://");
return BookDetail.builder()
.isbn(isbn)
.author(author)
.title(title)
.extraInfoMap(extraInfoMap)
.authorDescribe(StringUtil.cleanHtml(authorDescribe))
.catalog(StringUtil.cleanHtml(catalog))
.summary(StringUtil.cleanHtml(summary))
.introduction(StringUtil.cleanHtml(introduction))
.coverUrl(coverUrl)
.build();
}
}

@ -1,39 +0,0 @@
package cn.wustlinghang.mywust.core.request.service.library;
import cn.wustlinghang.mywust.core.request.factory.library.LibraryRequestFactory;
import cn.wustlinghang.mywust.data.library.parsed.BookHolding;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.network.entitys.HttpResponse;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.databind.JsonNode;
import java.io.IOException;
import java.util.List;
public class BookHoldingApiService extends BaseLibraryApiService {
public BookHoldingApiService(Requester requester) {
super(requester);
}
public List<BookHolding> getHoldingList(String id)
throws ApiException, IOException, ParseException {
HttpRequest loanRequest = LibraryRequestFactory.bookHoldingRequest(id);
HttpResponse loanResponse = requester.get(loanRequest);
checkResponse(loanResponse);
try {
JsonNode data = objectMapper.readTree(loanResponse.getBody()).path("data");
// 这里的holding是个string值,需要独立解析(坑人)
JsonNode holdings = data.path("holdings");
return objectMapper.readValue(holdings.asText("[]"), bookHoldingListType);
} catch (JacksonException e) {
throw new ParseException(e.getMessage(), "");
}
}
}

@ -1,52 +0,0 @@
package cn.wustlinghang.mywust.core.request.service.library;
import cn.wustlinghang.mywust.core.request.factory.library.LibraryRequestFactory;
import cn.wustlinghang.mywust.data.library.PagingResult;
import cn.wustlinghang.mywust.data.library.origin.CurrentLoanBook;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.network.entitys.HttpResponse;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.databind.JsonNode;
import java.io.IOException;
import java.util.List;
public class CurrentLoanApiService extends BaseLibraryApiService {
public CurrentLoanApiService(Requester requester) {
super(requester);
}
public PagingResult<List<CurrentLoanBook>> getCurrentLoan(String cookie, int page, int pageSize)
throws ApiException, IOException, ParseException {
HttpRequest loanRequest = LibraryRequestFactory.currentLoanRequest(cookie, page, pageSize);
HttpResponse loanResponse = requester.get(loanRequest);
checkResponse(loanResponse);
try {
JsonNode data = objectMapper.readTree(loanResponse.getBody()).path("data");
// 获取,计算分页数据
pageSize = data.path("pageSize").asInt(pageSize);
int currentPage = data.path("currentPage").asInt(page);
int totalResult = data.path("total").asInt(0);
int totalPage = data.path("totalPage").asInt(0);
JsonNode itemsJson = data.path("items");
List<CurrentLoanBook> books = objectMapper.treeToValue(itemsJson, currentLoanBookListType);
return PagingResult.<List<CurrentLoanBook>>builder()
.currentPage(currentPage)
.totalResult(totalResult)
.pageSize(pageSize)
.totalPage(totalPage)
.data(books)
.build();
} catch (JacksonException e) {
throw new ParseException(e.getMessage(), "");
}
}
}

@ -1,53 +0,0 @@
package cn.wustlinghang.mywust.core.request.service.library;
import cn.wustlinghang.mywust.core.request.factory.library.LibraryRequestFactory;
import cn.wustlinghang.mywust.data.library.PagingResult;
import cn.wustlinghang.mywust.data.library.origin.HistoryLoanBook;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.entitys.HttpRequest;
import cn.wustlinghang.mywust.network.entitys.HttpResponse;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.databind.JsonNode;
import java.io.IOException;
import java.util.List;
public class LoanHistoryApiService extends BaseLibraryApiService {
public LoanHistoryApiService(Requester requester) {
super(requester);
}
public PagingResult<List<HistoryLoanBook>> getLoanHistory(String cookie, int page, int pageSize)
throws ApiException, IOException, ParseException {
HttpRequest request = LibraryRequestFactory.loanHistoryRequest(cookie, page, pageSize);
HttpResponse response = requester.get(request);
checkResponse(response);
try {
JsonNode data = objectMapper.readTree(response.getBody()).path("data");
// 获取,计算分页数据
pageSize = data.path("pageSize").asInt(pageSize);
int currentPage = data.path("currentPage").asInt(page);
int totalResult = data.path("total").asInt(0);
int totalPage = data.path("totalPage").asInt(0);
JsonNode itemsJson = data.path("items");
List<HistoryLoanBook> books = objectMapper.treeToValue(itemsJson, historyLoanBookListType);
return PagingResult.<List<HistoryLoanBook>>builder()
.currentPage(currentPage)
.totalResult(totalResult)
.pageSize(pageSize)
.totalPage(totalPage)
.data(books)
.build();
} catch (JacksonException e) {
throw new ParseException(e.getMessage(), "");
}
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save