lensfrex 1 year ago
parent 65e94fae91
commit 4974bb14f1
Signed by: lensfrex
GPG Key ID: 0F69A0A2FBEE98A0
  1. 11
      common/src/main/java/cn/wustlinghang/wusthelper/rpc/exception/RpcException.java
  2. 52
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/json/CourseTableApi.java
  3. 54
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/json/CreditStatusApi.java
  4. 50
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/json/ScoreApi.java
  5. 47
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/json/StudentInfoApi.java
  6. 47
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/json/TrainingPlanApi.java
  7. 14
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/json/handler/ApiExceptionHandler.java
  8. 32
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/services/LoginService.java
  9. 60
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/services/ParseService.java
  10. 62
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/services/RequestAgentService.java
  11. 16
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/Main.java
  12. 10
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/CookieApi.java
  13. 52
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/CourseTableApi.java
  14. 49
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/CreditStatusApi.java
  15. 48
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/ExamActivitiesApi.java
  16. 52
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/ExamDelayApplicationApi.java
  17. 50
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/ScoreApi.java
  18. 50
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/StudentInfoApi.java
  19. 48
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/TrainingPlanApi.java
  20. 12
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/handler/BaseExceptionHandler.java
  21. 4
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/handler/DefaultExceptionHandler.java
  22. 4
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/handler/IOExceptionHandler.java
  23. 4
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/handler/ParseExceptionHandler.java
  24. 17
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/handler/RpcExceptionHandler.java
  25. 4
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/handler/ValidationExceptionHandler.java
  26. 26
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/handler/WebApplicationExceptionHandler.java
  27. 6
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/interceptor/ResponseWrapperInterceptor.java
  28. 2
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/bean/JacksonBean.java
  29. 2
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/bean/MywustParserBeans.java
  30. 2
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/bean/MywustRequestAgentBeans.java
  31. 73
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/exception/UndergradRpcException.java
  32. 78
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/services/LoginService.java
  33. 132
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/services/ParseService.java
  34. 166
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/services/RequestAgentService.java
  35. 52
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/json/CourseTableApi.java
  36. 54
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/json/CreditStatusApi.java
  37. 50
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/json/ScoreApi.java
  38. 47
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/json/StudentInfoApi.java
  39. 47
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/json/TrainingPlanApi.java
  40. 14
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/json/handler/ApiExceptionHandler.java
  41. 32
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/services/LoginService.java
  42. 60
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/services/ParseService.java
  43. 62
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/services/RequestAgentService.java
  44. 16
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/Main.java
  45. 10
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/CookieApi.java
  46. 52
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/CourseTableApi.java
  47. 49
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/CreditStatusApi.java
  48. 48
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/ExamActivitiesApi.java
  49. 52
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/ExamDelayApplicationApi.java
  50. 50
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/ScoreApi.java
  51. 50
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/StudentInfoApi.java
  52. 48
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/TrainingPlanApi.java
  53. 14
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/handler/BaseExceptionHandler.java
  54. 4
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/handler/DefaultExceptionHandler.java
  55. 4
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/handler/IOExceptionHandler.java
  56. 4
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/handler/ParseExceptionHandler.java
  57. 17
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/handler/RpcExceptionHandler.java
  58. 4
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/handler/ValidationExceptionHandler.java
  59. 26
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/handler/WebApplicationExceptionHandler.java
  60. 6
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/interceptor/ResponseWrapperInterceptor.java
  61. 2
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/bean/JacksonBean.java
  62. 2
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/bean/MywustParserBeans.java
  63. 2
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/bean/MywustRequestAgentBeans.java
  64. 73
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/exception/UndergradRpcException.java
  65. 78
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/services/LoginService.java
  66. 132
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/services/ParseService.java
  67. 166
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/services/RequestAgentService.java
  68. 52
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/json/CourseTableApi.java
  69. 54
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/json/CreditStatusApi.java
  70. 50
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/json/ScoreApi.java
  71. 47
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/json/StudentInfoApi.java
  72. 47
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/json/TrainingPlanApi.java
  73. 14
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/json/handler/ApiExceptionHandler.java
  74. 32
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/services/LoginService.java
  75. 60
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/services/ParseService.java
  76. 62
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/services/RequestAgentService.java
  77. 16
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/Main.java
  78. 10
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/CookieApi.java
  79. 52
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/CourseTableApi.java
  80. 49
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/CreditStatusApi.java
  81. 48
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/ExamActivitiesApi.java
  82. 52
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/ExamDelayApplicationApi.java
  83. 50
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/ScoreApi.java
  84. 50
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/StudentInfoApi.java
  85. 48
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/TrainingPlanApi.java
  86. 14
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/handler/BaseExceptionHandler.java
  87. 4
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/handler/DefaultExceptionHandler.java
  88. 4
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/handler/IOExceptionHandler.java
  89. 4
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/handler/ParseExceptionHandler.java
  90. 17
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/handler/RpcExceptionHandler.java
  91. 4
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/handler/ValidationExceptionHandler.java
  92. 26
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/handler/WebApplicationExceptionHandler.java
  93. 6
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/interceptor/ResponseWrapperInterceptor.java
  94. 2
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/bean/JacksonBean.java
  95. 2
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/bean/MywustParserBeans.java
  96. 2
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/bean/MywustRequestAgentBeans.java
  97. 73
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/exception/UndergradRpcException.java
  98. 78
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/services/LoginService.java
  99. 132
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/services/ParseService.java
  100. 166
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/services/RequestAgentService.java
  101. Some files were not shown because too many files have changed in this diff Show More

@ -3,6 +3,9 @@ package cn.wustlinghang.wusthelper.rpc.exception;
public class RpcException extends RuntimeException {
protected final int code;
private static final int MODULE_CODE_OFFSET = 100_0000;
private static final int TYPE_CODE_OFFSET = 1_0000;
public RpcException(int code, String message) {
super(message);
this.code = code;
@ -13,11 +16,11 @@ public class RpcException extends RuntimeException {
}
public RpcException(int module, int type, int exceptionCode) {
this((module * 1000_0000) + (type * 1_0000) + (exceptionCode));
this((module * MODULE_CODE_OFFSET) + (type * TYPE_CODE_OFFSET) + (exceptionCode));
}
public RpcException(int module, int type, int exceptionCode, String message) {
this((module * 1000_0000) + (type * 1_0000) + (exceptionCode), message);
this((module * MODULE_CODE_OFFSET) + (type * TYPE_CODE_OFFSET) + (exceptionCode), message);
}
public int getCode() {
@ -27,4 +30,8 @@ public class RpcException extends RuntimeException {
public static RpcException ApiNotImplement() {
return new RpcException(-1, "接口未实现");
}
public static int toIntCode(int module, int type, int exceptionCode) {
return (module * MODULE_CODE_OFFSET) + (type * TYPE_CODE_OFFSET) + (exceptionCode);
}
}

@ -1,52 +0,0 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.json;
import cn.wustlinghang.mywust.core.parser.undergraduate.UndergradCourseTableParser;
import cn.wustlinghang.mywust.core.request.service.undergraduate.UndergradCourseTableApiService;
import cn.wustlinghang.mywust.data.global.Course;
import cn.wustlinghang.mywust.data.global.StudentInfo;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.rpc.response.RpcResponse;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
import java.util.List;
@Path("/course_table")
@ApplicationScoped
public class CourseTableApi {
private final UndergradCourseTableApiService studentInfoApiService;
private final UndergradCourseTableParser studentInfoPageParser;
public CourseTableApi(UndergradCourseTableApiService studentInfoApiService,
UndergradCourseTableParser studentInfoPageParser) {
this.studentInfoApiService = studentInfoApiService;
this.studentInfoPageParser = studentInfoPageParser;
}
@GET
@Path("/")
public List<Course> get(@QueryParam("cookie") @NotNull String cookie, @QueryParam("term") String term)
throws IOException, ApiException, ParseException {
String html = studentInfoApiService.getPage(term, cookie);
return this.parse(html);
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie, @QueryParam("term") String term)
throws IOException, ApiException {
return studentInfoApiService.getPage(term, cookie);
}
@POST
@Path("/parse")
public List<Course> parse(String html) throws ParseException {
return studentInfoPageParser.parse(html);
}
}

@ -1,54 +0,0 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.json;
import cn.wustlinghang.mywust.core.parser.undergraduate.UndergradCreditStatusParser;
import cn.wustlinghang.mywust.core.request.service.undergraduate.UndergradCreditStatusApiService;
import cn.wustlinghang.mywust.data.global.StudentInfo;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.mywust.network.RequestClientOption;
import cn.wustlinghang.wusthelper.rpc.response.RpcResponse;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
@Path("/credit_status")
@ApplicationScoped
public class CreditStatusApi {
private final UndergradCreditStatusApiService creditStatusApiService;
private final UndergradCreditStatusParser creditStatusParser;
private final RequestClientOption option;
public CreditStatusApi(UndergradCreditStatusApiService creditStatusApiService,
UndergradCreditStatusParser creditStatusParser,
RequestClientOption option) {
this.creditStatusApiService = creditStatusApiService;
this.creditStatusParser = creditStatusParser;
this.option = option;
}
@GET
@Path("/")
public String get(String cookie) throws IOException, ApiException, ParseException {
String html = creditStatusApiService.getPage(cookie, option, false);
return this.parse(html);
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie)
throws IOException, ApiException {
return creditStatusApiService.getPage(cookie, option, false);
}
@POST
@Path("/parse")
public String parse(String html) throws ParseException {
return creditStatusParser.parse(html);
}
}

@ -1,50 +0,0 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.json;
import cn.wustlinghang.mywust.core.parser.undergraduate.UndergradScoreParser;
import cn.wustlinghang.mywust.core.request.service.undergraduate.UndergradScoreApiService;
import cn.wustlinghang.mywust.data.global.Score;
import cn.wustlinghang.mywust.data.global.StudentInfo;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.rpc.response.RpcResponse;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
import java.util.List;
@Path("/score")
@ApplicationScoped
public class ScoreApi {
private final UndergradScoreApiService scoreApiService;
private final UndergradScoreParser scoreParser;
public ScoreApi(UndergradScoreApiService scoreApiService, UndergradScoreParser scoreParser) {
this.scoreApiService = scoreApiService;
this.scoreParser = scoreParser;
}
@GET
@Path("/")
public List<Score> get(String cookie) throws IOException, ApiException, ParseException {
String html = scoreApiService.getPage(cookie);
return this.parse(html);
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie)
throws IOException, ApiException {
return scoreApiService.getPage(cookie);
}
@POST
@Path("/parse")
public List<Score> parse(String html) throws ParseException {
return scoreParser.parse(html);
}
}

@ -1,47 +0,0 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.json;
import cn.wustlinghang.mywust.core.parser.undergraduate.UndergradStudentInfoPageParser;
import cn.wustlinghang.mywust.core.request.service.undergraduate.UndergradStudentInfoApiService;
import cn.wustlinghang.mywust.data.global.StudentInfo;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
@Path("/student_info")
@ApplicationScoped
public class StudentInfoApi {
private final UndergradStudentInfoApiService studentInfoApiService;
private final UndergradStudentInfoPageParser studentInfoPageParser;
public StudentInfoApi(UndergradStudentInfoApiService studentInfoApiService,
UndergradStudentInfoPageParser studentInfoPageParser) {
this.studentInfoApiService = studentInfoApiService;
this.studentInfoPageParser = studentInfoPageParser;
}
@GET
@Path("/")
public StudentInfo get(@QueryParam("cookie") @NotNull String cookie) throws IOException, ApiException, ParseException {
return this.parse(this.agent(cookie));
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie)
throws IOException, ApiException {
return studentInfoApiService.getPage(cookie);
}
@POST
@Path("/parse")
public StudentInfo parse(String html) throws ParseException {
return studentInfoPageParser.parse(html);
}
}

@ -1,47 +0,0 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.json;
import cn.wustlinghang.mywust.core.parser.undergraduate.UndergradTrainingPlanPageParser;
import cn.wustlinghang.mywust.core.request.service.undergraduate.UndergradTrainingPlanApiService;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
@Path("/training_plan")
@ApplicationScoped
public class TrainingPlanApi {
private final UndergradTrainingPlanApiService trainingPlanApiService;
private final UndergradTrainingPlanPageParser trainingPlanPageParser;
public TrainingPlanApi(UndergradTrainingPlanApiService trainingPlanApiService,
UndergradTrainingPlanPageParser trainingPlanPageParser) {
this.trainingPlanApiService = trainingPlanApiService;
this.trainingPlanPageParser = trainingPlanPageParser;
}
@GET
@Path("/")
public String get(String cookie) throws IOException, ApiException, ParseException {
String html = trainingPlanApiService.getPage(cookie);
return this.parse(html);
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie)
throws IOException, ApiException {
return trainingPlanApiService.getPage(cookie);
}
@POST
@Path("/parse")
public String parse(String html) throws ParseException {
return trainingPlanPageParser.parse(html);
}
}

@ -1,14 +0,0 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.json.handler;
import cn.wustlinghang.mywust.exception.ApiException;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
@Provider
public class ApiExceptionHandler extends ExceptionHandlerBase implements ExceptionMapper<ApiException> {
@Override
public Response toResponse(ApiException e) {
return super.toResponse(e.getCodeValue(), e.toString(), "ApiExceptionHandler");
}
}

@ -1,32 +0,0 @@
package cn.wustlinghang.wusthelper.internal.graduate.services;
import cn.wustlinghang.mywust.core.request.service.auth.UndergraduateLogin;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.network.RequestClientOption;
import jakarta.enterprise.context.ApplicationScoped;
import java.io.IOException;
@ApplicationScoped
public class LoginService {
private final RequestClientOption option;
private final UndergraduateLogin undergraduateLogin;
public LoginService(RequestClientOption option,
UndergraduateLogin undergraduateLogin) {
this.option = option;
this.undergraduateLogin = undergraduateLogin;
}
public String login(String username, String password, boolean legacy) throws IOException, ApiException {
if (legacy) {
return undergraduateLogin.getLoginCookieLegacy(username, password, option);
} else {
return undergraduateLogin.getLoginCookie(username, password, option);
}
}
public boolean verify(String cookie) throws IOException {
return !undergraduateLogin.checkCookiesFail(cookie);
}
}

@ -1,60 +0,0 @@
package cn.wustlinghang.wusthelper.internal.graduate.services;
import cn.wustlinghang.mywust.core.parser.undergraduate.*;
import cn.wustlinghang.mywust.data.global.Course;
import cn.wustlinghang.mywust.data.global.Score;
import cn.wustlinghang.mywust.data.global.StudentInfo;
import cn.wustlinghang.mywust.data.undergrad.ExamDelayApplication;
import cn.wustlinghang.mywust.exception.ParseException;
import jakarta.enterprise.context.ApplicationScoped;
import java.util.List;
@ApplicationScoped
public class ParseService {
private final UndergradCourseTableParser courseTableParser;
private final UndergradScoreParser scoreParser;
private final UndergradStudentInfoPageParser studentInfoPageParser;
private final UndergradTrainingPlanPageParser trainingPlanPageParser;
private final UndergradCreditStatusParser creditStatusParser;
private final UndergradExamDelayParser examDelayParser;
public ParseService(UndergradCourseTableParser courseTableParser,
UndergradScoreParser scoreParser,
UndergradStudentInfoPageParser studentInfoPageParser,
UndergradTrainingPlanPageParser trainingPlanPageParser,
UndergradCreditStatusParser creditStatusParser,
UndergradExamDelayParser examDelayParser) {
this.courseTableParser = courseTableParser;
this.scoreParser = scoreParser;
this.studentInfoPageParser = studentInfoPageParser;
this.trainingPlanPageParser = trainingPlanPageParser;
this.creditStatusParser = creditStatusParser;
this.examDelayParser = examDelayParser;
}
public List<Course> parseCourseTable(String data) throws ParseException {
return courseTableParser.parse(data);
}
public List<Score> parseScore(String data) throws ParseException {
return scoreParser.parse(data);
}
public StudentInfo parseStudentInfo(String data) throws ParseException {
return studentInfoPageParser.parse(data);
}
public String parseTrainingPlan(String data) throws ParseException {
return trainingPlanPageParser.parse(data);
}
public String parseCreditStatus(String data) throws ParseException {
return creditStatusParser.parse(data);
}
public List<ExamDelayApplication> parseExamDelayApplications(String data) throws ParseException {
return examDelayParser.parse(data);
}
}

@ -1,62 +0,0 @@
package cn.wustlinghang.wusthelper.internal.graduate.services;
import cn.wustlinghang.mywust.core.request.service.undergraduate.*;
import cn.wustlinghang.mywust.exception.ApiException;
import jakarta.enterprise.context.ApplicationScoped;
import java.io.IOException;
@ApplicationScoped
public class RequestAgentService {
private final UndergradCourseTableApiService courseTableApiService;
private final UndergradScoreApiService scoreApiService;
private final UndergradStudentInfoApiService studentInfoApiService;
private final UndergradTrainingPlanApiService trainingPlanApiService;
private final UndergradCreditStatusApiService creditStatusApiService;
private final UndergradExamDelayApiService examDelayApiService;
public RequestAgentService(UndergradCourseTableApiService courseTableApiService,
UndergradScoreApiService scoreApiService,
UndergradStudentInfoApiService studentInfoApiService,
UndergradTrainingPlanApiService trainingPlanApiService,
UndergradCreditStatusApiService creditStatusApiService,
UndergradExamDelayApiService examDelayApiService) {
this.courseTableApiService = courseTableApiService;
this.scoreApiService = scoreApiService;
this.studentInfoApiService = studentInfoApiService;
this.trainingPlanApiService = trainingPlanApiService;
this.creditStatusApiService = creditStatusApiService;
this.examDelayApiService = examDelayApiService;
}
public String getStudentInfoPage(String cookie) throws IOException, ApiException {
return studentInfoApiService.getPage(cookie);
}
public String getCourseTable(String cookie, String term) throws IOException, ApiException {
return courseTableApiService.getPage(term, cookie);
}
public String getScore(String cookie) throws IOException, ApiException {
return scoreApiService.getPage(cookie);
}
public String getTrainingPlan(String cookie) throws IOException, ApiException {
return trainingPlanApiService.getPage(cookie);
}
public String getCreditStatus(String cookie) throws IOException, ApiException {
return creditStatusApiService.getPage(cookie, null, false);
}
public UndergradExamDelayApiService.ExamActivity[] getExamActivities(String cookie, String term)
throws IOException, ApiException {
return examDelayApiService.getActivities(term, cookie);
}
public String getExamDelayApplications(String cookie, String term, String activityId)
throws IOException, ApiException {
return examDelayApiService.getPage(term, activityId, cookie);
}
}

@ -0,0 +1,16 @@
package cn.wustlinghang.wusthelper.internal.undergrad;
import io.quarkus.runtime.Startup;
import jakarta.annotation.PostConstruct;
import jakarta.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Startup
@Singleton
public class Main {
@PostConstruct
public void run() {
log.info("Undergrad service started.");
}
}

@ -1,7 +1,7 @@
package cn.wustlinghang.wusthelper.internal.library.api.json;
package cn.wustlinghang.wusthelper.internal.undergrad.api.json;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.wusthelper.internal.library.services.LoginService;
import cn.wustlinghang.wusthelper.internal.undergrad.services.LoginService;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
@ -20,13 +20,13 @@ public class CookieApi {
@GET
@Path("/")
public String login(@QueryParam("username") @NotNull String username,
@QueryParam("password") @NotNull String password) throws IOException, ApiException {
@QueryParam("password") @NotNull String password) throws RpcException {
return loginService.login(username, password, false);
}
@GET
@Path("/verify")
public Boolean verify(@QueryParam("cookie") @NotNull String cookie) throws IOException {
public Boolean verify(@QueryParam("cookie") @NotNull String cookie) throws RpcException {
return loginService.verify(cookie);
}
}

@ -0,0 +1,52 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.json;
import cn.wustlinghang.mywust.data.global.Course;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.internal.undergrad.services.ParseService;
import cn.wustlinghang.wusthelper.internal.undergrad.services.RequestAgentService;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
import java.util.List;
@Path("/course_table")
@ApplicationScoped
public class CourseTableApi {
private final RequestAgentService agentService;
private final ParseService parseService;
public CourseTableApi(RequestAgentService agentService,
ParseService parseService) {
this.agentService = agentService;
this.parseService = parseService;
}
@GET
@Path("/")
public List<Course> get(@QueryParam("cookie") @NotNull String cookie,
@QueryParam("term") String term)
throws RpcException {
return this.parse(this.agent(cookie, term));
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie,
@QueryParam("term") String term)
throws RpcException {
return agentService.getCourseTable(cookie, term);
}
@POST
@Path("/parse")
public List<Course> parse(String html) throws RpcException {
return parseService.parseCourseTable(html);
}
}

@ -0,0 +1,49 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.json;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.internal.undergrad.services.ParseService;
import cn.wustlinghang.wusthelper.internal.undergrad.services.RequestAgentService;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
@Path("/credit_status")
@ApplicationScoped
public class CreditStatusApi {
private final RequestAgentService agentService;
private final ParseService parseService;
public CreditStatusApi(RequestAgentService agentService,
ParseService parseService) {
this.agentService = agentService;
this.parseService = parseService;
}
@GET
@Path("/")
public String get(@QueryParam("cookie") @NotNull String cookie)
throws RpcException {
String html = this.agent(cookie);
return this.parse(html);
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie)
throws RpcException {
return agentService.getCreditStatus(cookie);
}
@POST
@Path("/parse")
public String parse(String html) throws RpcException {
return parseService.parseCreditStatus(html);
}
}

@ -0,0 +1,48 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.json;
import cn.wustlinghang.mywust.core.request.service.undergraduate.UndergradExamDelayApiService;
import cn.wustlinghang.mywust.data.global.Score;
import cn.wustlinghang.wusthelper.internal.undergrad.services.RequestAgentService;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.util.List;
@Path("/exam_activities")
@ApplicationScoped
public class ExamActivitiesApi {
private final RequestAgentService agentService;
public ExamActivitiesApi(RequestAgentService agentService) {
this.agentService = agentService;
}
@GET
@Path("/")
public UndergradExamDelayApiService.ExamActivity[] get(
@QueryParam("cookie") @NotNull String cookie,
@QueryParam("term") @NotNull String term)
throws RpcException {
return this.agent(cookie, term);
}
@GET
@Path("/agent")
public UndergradExamDelayApiService.ExamActivity[] agent(
@QueryParam("cookie") @NotNull String cookie,
@QueryParam("term") @NotNull String term)
throws RpcException {
return agentService.getExamActivities(cookie, term);
}
@POST
@Path("/parse")
public List<Score> parse(String html) throws RpcException {
throw RpcException.ApiNotImplement();
}
}

@ -0,0 +1,52 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.json;
import cn.wustlinghang.mywust.data.undergrad.ExamDelayApplication;
import cn.wustlinghang.wusthelper.internal.undergrad.services.ParseService;
import cn.wustlinghang.wusthelper.internal.undergrad.services.RequestAgentService;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.util.List;
@Path("/exam_delay_application")
@ApplicationScoped
public class ExamDelayApplicationApi {
private final RequestAgentService agentService;
private final ParseService parseService;
public ExamDelayApplicationApi(RequestAgentService agentService,
ParseService parseService) {
this.agentService = agentService;
this.parseService = parseService;
}
@GET
@Path("/")
public List<ExamDelayApplication> get(
@QueryParam("cookie") @NotNull String cookie,
@QueryParam("term") @NotNull String term,
@QueryParam("activity_id") @NotNull String activityId)
throws RpcException {
return this.parse(this.agent(cookie, term, activityId));
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie,
@QueryParam("term") @NotNull String term,
@QueryParam("activity_id") @NotNull String activityId)
throws RpcException {
return agentService.getExamDelayApplications(cookie, term, activityId);
}
@POST
@Path("/parse")
public List<ExamDelayApplication> parse(String html) throws RpcException {
return parseService.parseExamDelayApplications(html);
}
}

@ -0,0 +1,50 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.json;
import cn.wustlinghang.mywust.data.global.Score;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.internal.undergrad.services.ParseService;
import cn.wustlinghang.wusthelper.internal.undergrad.services.RequestAgentService;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
import java.util.List;
@Path("/score")
@ApplicationScoped
public class ScoreApi {
private final RequestAgentService agentService;
private final ParseService parseService;
public ScoreApi(RequestAgentService agentService,
ParseService parseService) {
this.agentService = agentService;
this.parseService = parseService;
}
@GET
@Path("/")
public List<Score> get(@QueryParam("cookie") @NotNull String cookie)
throws RpcException {
return this.parse(this.agent(cookie));
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie)
throws RpcException {
return agentService.getScore(cookie);
}
@POST
@Path("/parse")
public List<Score> parse(String html) throws RpcException {
return parseService.parseScore(html);
}
}

@ -0,0 +1,50 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.json;
import cn.wustlinghang.mywust.data.global.StudentInfo;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.internal.undergrad.exception.UndergradRpcException;
import cn.wustlinghang.wusthelper.internal.undergrad.services.ParseService;
import cn.wustlinghang.wusthelper.internal.undergrad.services.RequestAgentService;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
@Path("/student_info")
@ApplicationScoped
public class StudentInfoApi {
private final RequestAgentService agentService;
private final ParseService parseService;
public StudentInfoApi(RequestAgentService agentService,
ParseService parseService) {
this.agentService = agentService;
this.parseService = parseService;
}
@GET
@Path("/")
public StudentInfo get(@QueryParam("cookie") @NotNull String cookie)
throws RpcException {
return this.parse(this.agent(cookie));
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie)
throws RpcException {
return agentService.getStudentInfoPage(cookie);
}
@POST
@Path("/parse")
public StudentInfo parse(String html) throws RpcException {
return parseService.parseStudentInfo(html);
}
}

@ -0,0 +1,48 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.json;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.internal.undergrad.services.ParseService;
import cn.wustlinghang.wusthelper.internal.undergrad.services.RequestAgentService;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
@Path("/training_plan")
@ApplicationScoped
public class TrainingPlanApi {
private final RequestAgentService agentService;
private final ParseService parseService;
public TrainingPlanApi(RequestAgentService agentService,
ParseService parseService) {
this.agentService = agentService;
this.parseService = parseService;
}
@GET
@Path("/")
public String get(@QueryParam("cookie") @NotNull String cookie)
throws RpcException {
return this.parse(this.agent(cookie));
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie)
throws RpcException {
return agentService.getTrainingPlan(cookie);
}
@POST
@Path("/parse")
public String parse(String html) throws RpcException {
return parseService.parseTrainingPlan(html);
}
}

@ -7,7 +7,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
public abstract class ExceptionHandlerBase {
public abstract class BaseExceptionHandler {
public static final String EXCEPTION_HEADER_KEY = "X-exception-handler";
private static final ObjectMapper objectMapper = new ObjectMapper();
@ -17,6 +17,14 @@ public abstract class ExceptionHandlerBase {
}
public Response toResponse(int code, String msg, String handlerName) {
return toResponse(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), code, msg, handlerName);
}
public Response toResponse(int status, int code, String msg, String handlerName) {
return toResponse(Response.Status.fromStatusCode(status), code, msg, handlerName);
}
public Response toResponse(Response.Status status, int code, String msg, String handlerName) {
Object response;
try {
response = objectMapper.writeValueAsString(RpcResponse.error(code, msg));
@ -24,7 +32,7 @@ public abstract class ExceptionHandlerBase {
response = RpcResponse.error(ResponseCode.SERVER_INTERNAL_ERROR);
}
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
return Response.status(status)
.entity(response)
.header(EXCEPTION_HEADER_KEY, handlerName)
.type(MediaType.APPLICATION_JSON)

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.physics.api.json.handler;
package cn.wustlinghang.wusthelper.internal.undergrad.api.json.handler;
import cn.wustlinghang.wusthelper.rpc.response.ResponseCode;
import jakarta.ws.rs.core.Response;
@ -8,7 +8,7 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
@Provider
public class DefaultExceptionHandler extends ExceptionHandlerBase implements ExceptionMapper<Exception> {
public class DefaultExceptionHandler extends BaseExceptionHandler implements ExceptionMapper<Exception> {
@Override
public Response toResponse(Exception e) {
log.error("未知异常:", e);

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.json.handler;
package cn.wustlinghang.wusthelper.internal.undergrad.api.json.handler;
import cn.wustlinghang.wusthelper.rpc.response.ResponseCode;
import jakarta.ws.rs.core.Response;
@ -10,7 +10,7 @@ import java.io.IOException;
@Slf4j
@Provider
public class IOExceptionHandler extends ExceptionHandlerBase implements ExceptionMapper<IOException> {
public class IOExceptionHandler extends BaseExceptionHandler implements ExceptionMapper<IOException> {
@Override
public Response toResponse(IOException e) {
log.error("IO异常:", e);

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.library.api.json.handler;
package cn.wustlinghang.wusthelper.internal.undergrad.api.json.handler;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.rpc.response.ResponseCode;
@ -9,7 +9,7 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
@Provider
public class ParseExceptionHandler extends ExceptionHandlerBase implements ExceptionMapper<ParseException> {
public class ParseExceptionHandler extends BaseExceptionHandler implements ExceptionMapper<ParseException> {
@Override
public Response toResponse(ParseException e) {
log.error("解析异常:", e);

@ -0,0 +1,17 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.json.handler;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
@Provider
public class RpcExceptionHandler extends BaseExceptionHandler implements ExceptionMapper<RpcException> {
@Override
public Response toResponse(RpcException e) {
return super.toResponse(
e.getCode(),
e.toString(),
"RpcExceptionHandler");
}
}

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.library.api.json.handler;
package cn.wustlinghang.wusthelper.internal.undergrad.api.json.handler;
import cn.wustlinghang.wusthelper.rpc.response.ResponseCode;
import jakarta.validation.ValidationException;
@ -9,7 +9,7 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
@Provider
public class ValidationExceptionHandler extends ExceptionHandlerBase
public class ValidationExceptionHandler extends BaseExceptionHandler
implements ExceptionMapper<ValidationException> {
@Override
public Response toResponse(ValidationException e) {

@ -0,0 +1,26 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.json.handler;
import cn.wustlinghang.wusthelper.internal.undergrad.exception.UndergradRpcException;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
@Provider
public class WebApplicationExceptionHandler extends BaseExceptionHandler implements ExceptionMapper<WebApplicationException> {
@Override
public Response toResponse(WebApplicationException e) {
return super.toResponse(
e.getResponse().getStatus(),
RpcException.toIntCode(
UndergradRpcException.UNDERGRAD_MODULE,
UndergradRpcException.SubModuleCode.COMMON.ordinal(),
UndergradRpcException.TypeCode.OTHER_EXCEPTION.ordinal() * 100
+ UndergradRpcException.ErrorCode.REQUEST_INVALID.ordinal()
),
e.getMessage(),
"WebApplicationExceptionHandler"
);
}
}

@ -1,6 +1,6 @@
package cn.wustlinghang.wusthelper.internal.physics.api.json.interceptor;
package cn.wustlinghang.wusthelper.internal.undergrad.api.json.interceptor;
import cn.wustlinghang.wusthelper.internal.physics.api.json.handler.ExceptionHandlerBase;
import cn.wustlinghang.wusthelper.internal.undergrad.api.json.handler.BaseExceptionHandler;
import cn.wustlinghang.wusthelper.rpc.response.RpcResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.ws.rs.WebApplicationException;
@ -22,7 +22,7 @@ public class ResponseWrapperInterceptor implements WriterInterceptor {
@Override
public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
boolean hasException = context.getHeaders().get(ExceptionHandlerBase.EXCEPTION_HEADER_KEY) != null;
boolean hasException = context.getHeaders().get(BaseExceptionHandler.EXCEPTION_HEADER_KEY) != null;
if (!hasException) {
Object data = context.getEntity();
RpcResponse<Object> wrappedResponse = RpcResponse.success(data);

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.physics.bean;
package cn.wustlinghang.wusthelper.internal.undergrad.bean;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.enterprise.context.ApplicationScoped;

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.physics.bean;
package cn.wustlinghang.wusthelper.internal.undergrad.bean;
import cn.wustlinghang.mywust.core.parser.undergraduate.*;
import jakarta.enterprise.context.ApplicationScoped;

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.library.bean;
package cn.wustlinghang.wusthelper.internal.undergrad.bean;
import cn.wustlinghang.mywust.core.request.service.auth.UndergraduateLogin;
import cn.wustlinghang.mywust.core.request.service.undergraduate.*;

@ -0,0 +1,73 @@
package cn.wustlinghang.wusthelper.internal.undergrad.exception;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import java.util.StringJoiner;
public class UndergradRpcException extends RpcException {
public static final int UNDERGRAD_MODULE = 1;
public UndergradRpcException(TypeCode typeCode,
SubModuleCode subModuleCode,
ErrorCode errorCode) {
super(UNDERGRAD_MODULE,
typeCode.ordinal(),
subModuleCode.ordinal() * 100 + errorCode.ordinal(),
new StringJoiner("-")
.add("UNDERGRAD")
.add(typeCode.name())
.add(subModuleCode.name())
.add(errorCode.name())
.toString()
);
}
/**
* 异常类型编码
*/
public enum TypeCode {
// 网络异常类型
NETWORK_EXCEPTION,
// 参数异常类型
PARAM_EXCEPTION,
// 权限认证异常类型
AUTH_EXCEPTION,
// 网页解析异常类型
PARSE_EXCEPTION,
// 其他的异常类型
OTHER_EXCEPTION
}
/**
* 子模块编码
*/
public enum SubModuleCode {
COMMON, AUTH, COURSE_TABLE, CREDIT_STATUS, SCORE,
STUDENT_INFO, TRAINING_PLAN, EXAM_ACTIVITIES, EXAM_DELAY_APPLICATION
}
/**
* 具体错误编码
*/
public enum ErrorCode {
REQUEST_INVALID,
PARAM_INVALID,
COOKIE_INVALID,
NETWORK_ERROR,
PARSE_ERROR,
// 需要评教
NEED_EVALUATE,
AUTH_PASSWORD_WRONG,
// 用户不存在
AUTH_USER_NOT_EXISTS,
// 封号
AUTH_USER_BANNED,
// 用户账号禁用
AUTH_USER_DISABLED,
// 用户账号需要更改
AUTH_NEED_CHANGE_PASSWORD,
AUTH_UNKNOWN_ERROR
}
}

@ -0,0 +1,78 @@
package cn.wustlinghang.wusthelper.internal.undergrad.services;
import cn.wustlinghang.mywust.core.request.service.auth.UndergraduateLogin;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.network.RequestClientOption;
import cn.wustlinghang.wusthelper.internal.undergrad.exception.UndergradRpcException;
import jakarta.enterprise.context.ApplicationScoped;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
@Slf4j
@ApplicationScoped
public class LoginService {
private final RequestClientOption option;
private final UndergraduateLogin undergraduateLogin;
public LoginService(RequestClientOption option,
UndergraduateLogin undergraduateLogin) {
this.option = option;
this.undergraduateLogin = undergraduateLogin;
}
public String login(String username, String password, boolean legacy) throws UndergradRpcException {
try {
if (legacy) {
return undergraduateLogin.getLoginCookieLegacy(username, password, option);
} else {
return undergraduateLogin.getLoginCookie(username, password, option);
}
} catch (ApiException e) {
throw wrapApiException(e);
} catch (IOException e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
UndergradRpcException.SubModuleCode.AUTH,
UndergradRpcException.ErrorCode.NETWORK_ERROR
);
}
}
public boolean verify(String cookie) throws UndergradRpcException {
try {
return !undergraduateLogin.checkCookiesFail(cookie);
} catch (IOException e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
UndergradRpcException.SubModuleCode.AUTH,
UndergradRpcException.ErrorCode.NETWORK_ERROR
);
}
}
private UndergradRpcException wrapApiException(ApiException e) {
UndergradRpcException.ErrorCode errorCode = switch (e.getCode()) {
case NETWORK_EXCEPTION -> UndergradRpcException.ErrorCode.NETWORK_ERROR;
case UNI_LOGIN_PASSWORD_WRONG -> UndergradRpcException.ErrorCode.AUTH_PASSWORD_WRONG;
case UNI_LOGIN_USER_NOT_EXISTS -> UndergradRpcException.ErrorCode.AUTH_USER_NOT_EXISTS;
case UNI_LOGIN_USER_BANNED -> UndergradRpcException.ErrorCode.AUTH_USER_BANNED;
case UNI_LOGIN_USER_DISABLED -> UndergradRpcException.ErrorCode.AUTH_USER_DISABLED;
case UNI_LOGIN_NEED_CHANGE_PASSWORD -> UndergradRpcException.ErrorCode.AUTH_NEED_CHANGE_PASSWORD;
case UNI_LOGIN_USER_NOT_ONLY -> UndergradRpcException.ErrorCode.AUTH_UNKNOWN_ERROR;
case UNI_LOGIN_NO_REGISTER -> UndergradRpcException.ErrorCode.AUTH_UNKNOWN_ERROR;
case UNI_LOGIN_NEED_TFA -> UndergradRpcException.ErrorCode.AUTH_UNKNOWN_ERROR;
default -> {
log.error("本科生:登录代理请求异常,异常未处理");
log.error("异常:", e);
yield UndergradRpcException.ErrorCode.AUTH_UNKNOWN_ERROR;
}
};
return new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
UndergradRpcException.SubModuleCode.AUTH,
errorCode
);
}
}

@ -0,0 +1,132 @@
package cn.wustlinghang.wusthelper.internal.undergrad.services;
import cn.wustlinghang.mywust.core.parser.undergraduate.*;
import cn.wustlinghang.mywust.data.global.Course;
import cn.wustlinghang.mywust.data.global.Score;
import cn.wustlinghang.mywust.data.global.StudentInfo;
import cn.wustlinghang.mywust.data.undergrad.ExamDelayApplication;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.internal.undergrad.exception.UndergradRpcException;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.enterprise.context.ApplicationScoped;
import java.util.List;
@ApplicationScoped
public class ParseService {
private final UndergradCourseTableParser courseTableParser;
private final UndergradScoreParser scoreParser;
private final UndergradStudentInfoPageParser studentInfoPageParser;
private final UndergradTrainingPlanPageParser trainingPlanPageParser;
private final UndergradCreditStatusParser creditStatusParser;
private final UndergradExamDelayParser examDelayParser;
public ParseService(UndergradCourseTableParser courseTableParser,
UndergradScoreParser scoreParser,
UndergradStudentInfoPageParser studentInfoPageParser,
UndergradTrainingPlanPageParser trainingPlanPageParser,
UndergradCreditStatusParser creditStatusParser,
UndergradExamDelayParser examDelayParser) {
this.courseTableParser = courseTableParser;
this.scoreParser = scoreParser;
this.studentInfoPageParser = studentInfoPageParser;
this.trainingPlanPageParser = trainingPlanPageParser;
this.creditStatusParser = creditStatusParser;
this.examDelayParser = examDelayParser;
}
public List<Course> parseCourseTable(String data) throws UndergradRpcException {
try {
if (data.contains("评教")) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.PARSE_EXCEPTION,
UndergradRpcException.SubModuleCode.COURSE_TABLE,
UndergradRpcException.ErrorCode.NEED_EVALUATE
);
}
return courseTableParser.parse(data);
} catch (UndergradRpcException e) {
throw e;
} catch (Exception e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.PARSE_EXCEPTION,
UndergradRpcException.SubModuleCode.COURSE_TABLE,
UndergradRpcException.ErrorCode.PARSE_ERROR
);
}
}
public List<Score> parseScore(String data) throws RpcException {
try {
if (data.contains("评教")) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.PARSE_EXCEPTION,
UndergradRpcException.SubModuleCode.SCORE,
UndergradRpcException.ErrorCode.NEED_EVALUATE
);
}
return scoreParser.parse(data);
} catch (UndergradRpcException e) {
throw e;
} catch (Exception e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.PARSE_EXCEPTION,
UndergradRpcException.SubModuleCode.SCORE,
UndergradRpcException.ErrorCode.PARSE_ERROR
);
}
}
public StudentInfo parseStudentInfo(String data) throws RpcException {
try {
return studentInfoPageParser.parse(data);
} catch (Exception e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.PARSE_EXCEPTION,
UndergradRpcException.SubModuleCode.STUDENT_INFO,
UndergradRpcException.ErrorCode.PARSE_ERROR
);
}
}
public String parseTrainingPlan(String data) throws RpcException {
try {
return trainingPlanPageParser.parse(data);
} catch (Exception e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.PARSE_EXCEPTION,
UndergradRpcException.SubModuleCode.TRAINING_PLAN,
UndergradRpcException.ErrorCode.PARSE_ERROR
);
}
}
public String parseCreditStatus(String data) throws RpcException {
try {
return creditStatusParser.parse(data);
} catch (Exception e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.PARSE_EXCEPTION,
UndergradRpcException.SubModuleCode.CREDIT_STATUS,
UndergradRpcException.ErrorCode.PARSE_ERROR
);
}
}
public List<ExamDelayApplication> parseExamDelayApplications(String data) throws RpcException {
try {
return examDelayParser.parse(data);
} catch (Exception e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.PARSE_EXCEPTION,
UndergradRpcException.SubModuleCode.EXAM_DELAY_APPLICATION,
UndergradRpcException.ErrorCode.PARSE_ERROR
);
}
}
}

@ -0,0 +1,166 @@
package cn.wustlinghang.wusthelper.internal.undergrad.services;
import cn.wustlinghang.mywust.core.request.service.undergraduate.*;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.network.RequestClientOption;
import cn.wustlinghang.wusthelper.internal.undergrad.exception.UndergradRpcException;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.enterprise.context.ApplicationScoped;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
@Slf4j
@ApplicationScoped
public class RequestAgentService {
private final UndergradCourseTableApiService courseTableApiService;
private final UndergradScoreApiService scoreApiService;
private final UndergradStudentInfoApiService studentInfoApiService;
private final UndergradTrainingPlanApiService trainingPlanApiService;
private final UndergradCreditStatusApiService creditStatusApiService;
private final UndergradExamDelayApiService examDelayApiService;
private final RequestClientOption requestClientOption;
public RequestAgentService(UndergradCourseTableApiService courseTableApiService,
UndergradScoreApiService scoreApiService,
UndergradStudentInfoApiService studentInfoApiService,
UndergradTrainingPlanApiService trainingPlanApiService,
UndergradCreditStatusApiService creditStatusApiService,
UndergradExamDelayApiService examDelayApiService,
RequestClientOption requestClientOption) {
this.courseTableApiService = courseTableApiService;
this.scoreApiService = scoreApiService;
this.studentInfoApiService = studentInfoApiService;
this.trainingPlanApiService = trainingPlanApiService;
this.creditStatusApiService = creditStatusApiService;
this.examDelayApiService = examDelayApiService;
this.requestClientOption = requestClientOption;
}
public String getStudentInfoPage(String cookie) throws RpcException {
try {
return studentInfoApiService.getPage(cookie);
} catch (ApiException e) {
throw wrapApiException(e, UndergradRpcException.SubModuleCode.STUDENT_INFO);
} catch (IOException e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
UndergradRpcException.SubModuleCode.STUDENT_INFO,
UndergradRpcException.ErrorCode.NETWORK_ERROR
);
}
}
public String getCourseTable(String cookie, String term) throws RpcException {
try {
return courseTableApiService.getPage(term, cookie);
} catch (ApiException e) {
throw wrapApiException(e, UndergradRpcException.SubModuleCode.COURSE_TABLE);
} catch (IOException e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
UndergradRpcException.SubModuleCode.COURSE_TABLE,
UndergradRpcException.ErrorCode.NETWORK_ERROR
);
}
}
public String getScore(String cookie) throws RpcException {
try {
return scoreApiService.getPage(cookie);
} catch (ApiException e) {
throw wrapApiException(e, UndergradRpcException.SubModuleCode.SCORE);
} catch (IOException e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
UndergradRpcException.SubModuleCode.SCORE,
UndergradRpcException.ErrorCode.NETWORK_ERROR
);
}
}
public String getTrainingPlan(String cookie) throws RpcException {
try {
return trainingPlanApiService.getPage(cookie);
} catch (ApiException e) {
throw wrapApiException(e, UndergradRpcException.SubModuleCode.TRAINING_PLAN);
} catch (IOException e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
UndergradRpcException.SubModuleCode.TRAINING_PLAN,
UndergradRpcException.ErrorCode.NETWORK_ERROR
);
}
}
public String getCreditStatus(String cookie) throws RpcException {
try {
return creditStatusApiService.getPage(cookie, requestClientOption, false);
} catch (ApiException e) {
throw wrapApiException(e, UndergradRpcException.SubModuleCode.CREDIT_STATUS);
} catch (IOException e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
UndergradRpcException.SubModuleCode.CREDIT_STATUS,
UndergradRpcException.ErrorCode.NETWORK_ERROR
);
}
}
public UndergradExamDelayApiService.ExamActivity[] getExamActivities(String cookie, String term)
throws RpcException {
try {
return examDelayApiService.getActivities(term, cookie);
} catch (ApiException e) {
throw wrapApiException(e, UndergradRpcException.SubModuleCode.EXAM_ACTIVITIES);
} catch (IOException e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
UndergradRpcException.SubModuleCode.EXAM_ACTIVITIES,
UndergradRpcException.ErrorCode.NETWORK_ERROR
);
}
}
public String getExamDelayApplications(String cookie, String term, String activityId)
throws RpcException {
try {
return examDelayApiService.getPage(term, activityId, cookie);
} catch (ApiException e) {
throw wrapApiException(e, UndergradRpcException.SubModuleCode.EXAM_DELAY_APPLICATION);
} catch (IOException e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
UndergradRpcException.SubModuleCode.EXAM_DELAY_APPLICATION,
UndergradRpcException.ErrorCode.NETWORK_ERROR
);
}
}
private UndergradRpcException wrapApiException(ApiException e, UndergradRpcException.SubModuleCode subModuleCode) {
return switch (e.getCode()) {
case NETWORK_EXCEPTION -> new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
subModuleCode,
UndergradRpcException.ErrorCode.NETWORK_ERROR
);
case COOKIE_INVALID -> new UndergradRpcException(
UndergradRpcException.TypeCode.AUTH_EXCEPTION,
subModuleCode,
UndergradRpcException.ErrorCode.COOKIE_INVALID
);
default -> {
log.error("本科生:{}代理请求异常,异常未处理", subModuleCode.name());
log.error("异常:", e);
yield new UndergradRpcException(
UndergradRpcException.TypeCode.AUTH_EXCEPTION,
subModuleCode,
UndergradRpcException.ErrorCode.COOKIE_INVALID
);
}
};
}
}

@ -1,52 +0,0 @@
package cn.wustlinghang.wusthelper.internal.library.api.json;
import cn.wustlinghang.mywust.core.parser.undergraduate.UndergradCourseTableParser;
import cn.wustlinghang.mywust.core.request.service.undergraduate.UndergradCourseTableApiService;
import cn.wustlinghang.mywust.data.global.Course;
import cn.wustlinghang.mywust.data.global.StudentInfo;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.rpc.response.RpcResponse;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
import java.util.List;
@Path("/course_table")
@ApplicationScoped
public class CourseTableApi {
private final UndergradCourseTableApiService studentInfoApiService;
private final UndergradCourseTableParser studentInfoPageParser;
public CourseTableApi(UndergradCourseTableApiService studentInfoApiService,
UndergradCourseTableParser studentInfoPageParser) {
this.studentInfoApiService = studentInfoApiService;
this.studentInfoPageParser = studentInfoPageParser;
}
@GET
@Path("/")
public List<Course> get(@QueryParam("cookie") @NotNull String cookie, @QueryParam("term") String term)
throws IOException, ApiException, ParseException {
String html = studentInfoApiService.getPage(term, cookie);
return this.parse(html);
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie, @QueryParam("term") String term)
throws IOException, ApiException {
return studentInfoApiService.getPage(term, cookie);
}
@POST
@Path("/parse")
public List<Course> parse(String html) throws ParseException {
return studentInfoPageParser.parse(html);
}
}

@ -1,54 +0,0 @@
package cn.wustlinghang.wusthelper.internal.library.api.json;
import cn.wustlinghang.mywust.core.parser.undergraduate.UndergradCreditStatusParser;
import cn.wustlinghang.mywust.core.request.service.undergraduate.UndergradCreditStatusApiService;
import cn.wustlinghang.mywust.data.global.StudentInfo;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.mywust.network.RequestClientOption;
import cn.wustlinghang.wusthelper.rpc.response.RpcResponse;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
@Path("/credit_status")
@ApplicationScoped
public class CreditStatusApi {
private final UndergradCreditStatusApiService creditStatusApiService;
private final UndergradCreditStatusParser creditStatusParser;
private final RequestClientOption option;
public CreditStatusApi(UndergradCreditStatusApiService creditStatusApiService,
UndergradCreditStatusParser creditStatusParser,
RequestClientOption option) {
this.creditStatusApiService = creditStatusApiService;
this.creditStatusParser = creditStatusParser;
this.option = option;
}
@GET
@Path("/")
public String get(String cookie) throws IOException, ApiException, ParseException {
String html = creditStatusApiService.getPage(cookie, option, false);
return this.parse(html);
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie)
throws IOException, ApiException {
return creditStatusApiService.getPage(cookie, option, false);
}
@POST
@Path("/parse")
public String parse(String html) throws ParseException {
return creditStatusParser.parse(html);
}
}

@ -1,50 +0,0 @@
package cn.wustlinghang.wusthelper.internal.library.api.json;
import cn.wustlinghang.mywust.core.parser.undergraduate.UndergradScoreParser;
import cn.wustlinghang.mywust.core.request.service.undergraduate.UndergradScoreApiService;
import cn.wustlinghang.mywust.data.global.Score;
import cn.wustlinghang.mywust.data.global.StudentInfo;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.rpc.response.RpcResponse;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
import java.util.List;
@Path("/score")
@ApplicationScoped
public class ScoreApi {
private final UndergradScoreApiService scoreApiService;
private final UndergradScoreParser scoreParser;
public ScoreApi(UndergradScoreApiService scoreApiService, UndergradScoreParser scoreParser) {
this.scoreApiService = scoreApiService;
this.scoreParser = scoreParser;
}
@GET
@Path("/")
public List<Score> get(String cookie) throws IOException, ApiException, ParseException {
String html = scoreApiService.getPage(cookie);
return this.parse(html);
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie)
throws IOException, ApiException {
return scoreApiService.getPage(cookie);
}
@POST
@Path("/parse")
public List<Score> parse(String html) throws ParseException {
return scoreParser.parse(html);
}
}

@ -1,47 +0,0 @@
package cn.wustlinghang.wusthelper.internal.library.api.json;
import cn.wustlinghang.mywust.core.parser.undergraduate.UndergradStudentInfoPageParser;
import cn.wustlinghang.mywust.core.request.service.undergraduate.UndergradStudentInfoApiService;
import cn.wustlinghang.mywust.data.global.StudentInfo;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
@Path("/student_info")
@ApplicationScoped
public class StudentInfoApi {
private final UndergradStudentInfoApiService studentInfoApiService;
private final UndergradStudentInfoPageParser studentInfoPageParser;
public StudentInfoApi(UndergradStudentInfoApiService studentInfoApiService,
UndergradStudentInfoPageParser studentInfoPageParser) {
this.studentInfoApiService = studentInfoApiService;
this.studentInfoPageParser = studentInfoPageParser;
}
@GET
@Path("/")
public StudentInfo get(@QueryParam("cookie") @NotNull String cookie) throws IOException, ApiException, ParseException {
return this.parse(this.agent(cookie));
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie)
throws IOException, ApiException {
return studentInfoApiService.getPage(cookie);
}
@POST
@Path("/parse")
public StudentInfo parse(String html) throws ParseException {
return studentInfoPageParser.parse(html);
}
}

@ -1,47 +0,0 @@
package cn.wustlinghang.wusthelper.internal.library.api.json;
import cn.wustlinghang.mywust.core.parser.undergraduate.UndergradTrainingPlanPageParser;
import cn.wustlinghang.mywust.core.request.service.undergraduate.UndergradTrainingPlanApiService;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
@Path("/training_plan")
@ApplicationScoped
public class TrainingPlanApi {
private final UndergradTrainingPlanApiService trainingPlanApiService;
private final UndergradTrainingPlanPageParser trainingPlanPageParser;
public TrainingPlanApi(UndergradTrainingPlanApiService trainingPlanApiService,
UndergradTrainingPlanPageParser trainingPlanPageParser) {
this.trainingPlanApiService = trainingPlanApiService;
this.trainingPlanPageParser = trainingPlanPageParser;
}
@GET
@Path("/")
public String get(String cookie) throws IOException, ApiException, ParseException {
String html = trainingPlanApiService.getPage(cookie);
return this.parse(html);
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie)
throws IOException, ApiException {
return trainingPlanApiService.getPage(cookie);
}
@POST
@Path("/parse")
public String parse(String html) throws ParseException {
return trainingPlanPageParser.parse(html);
}
}

@ -1,14 +0,0 @@
package cn.wustlinghang.wusthelper.internal.library.api.json.handler;
import cn.wustlinghang.mywust.exception.ApiException;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
@Provider
public class ApiExceptionHandler extends ExceptionHandlerBase implements ExceptionMapper<ApiException> {
@Override
public Response toResponse(ApiException e) {
return super.toResponse(e.getCodeValue(), e.toString(), "ApiExceptionHandler");
}
}

@ -1,32 +0,0 @@
package cn.wustlinghang.wusthelper.internal.library.services;
import cn.wustlinghang.mywust.core.request.service.auth.UndergraduateLogin;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.network.RequestClientOption;
import jakarta.enterprise.context.ApplicationScoped;
import java.io.IOException;
@ApplicationScoped
public class LoginService {
private final RequestClientOption option;
private final UndergraduateLogin undergraduateLogin;
public LoginService(RequestClientOption option,
UndergraduateLogin undergraduateLogin) {
this.option = option;
this.undergraduateLogin = undergraduateLogin;
}
public String login(String username, String password, boolean legacy) throws IOException, ApiException {
if (legacy) {
return undergraduateLogin.getLoginCookieLegacy(username, password, option);
} else {
return undergraduateLogin.getLoginCookie(username, password, option);
}
}
public boolean verify(String cookie) throws IOException {
return !undergraduateLogin.checkCookiesFail(cookie);
}
}

@ -1,60 +0,0 @@
package cn.wustlinghang.wusthelper.internal.library.services;
import cn.wustlinghang.mywust.core.parser.undergraduate.*;
import cn.wustlinghang.mywust.data.global.Course;
import cn.wustlinghang.mywust.data.global.Score;
import cn.wustlinghang.mywust.data.global.StudentInfo;
import cn.wustlinghang.mywust.data.undergrad.ExamDelayApplication;
import cn.wustlinghang.mywust.exception.ParseException;
import jakarta.enterprise.context.ApplicationScoped;
import java.util.List;
@ApplicationScoped
public class ParseService {
private final UndergradCourseTableParser courseTableParser;
private final UndergradScoreParser scoreParser;
private final UndergradStudentInfoPageParser studentInfoPageParser;
private final UndergradTrainingPlanPageParser trainingPlanPageParser;
private final UndergradCreditStatusParser creditStatusParser;
private final UndergradExamDelayParser examDelayParser;
public ParseService(UndergradCourseTableParser courseTableParser,
UndergradScoreParser scoreParser,
UndergradStudentInfoPageParser studentInfoPageParser,
UndergradTrainingPlanPageParser trainingPlanPageParser,
UndergradCreditStatusParser creditStatusParser,
UndergradExamDelayParser examDelayParser) {
this.courseTableParser = courseTableParser;
this.scoreParser = scoreParser;
this.studentInfoPageParser = studentInfoPageParser;
this.trainingPlanPageParser = trainingPlanPageParser;
this.creditStatusParser = creditStatusParser;
this.examDelayParser = examDelayParser;
}
public List<Course> parseCourseTable(String data) throws ParseException {
return courseTableParser.parse(data);
}
public List<Score> parseScore(String data) throws ParseException {
return scoreParser.parse(data);
}
public StudentInfo parseStudentInfo(String data) throws ParseException {
return studentInfoPageParser.parse(data);
}
public String parseTrainingPlan(String data) throws ParseException {
return trainingPlanPageParser.parse(data);
}
public String parseCreditStatus(String data) throws ParseException {
return creditStatusParser.parse(data);
}
public List<ExamDelayApplication> parseExamDelayApplications(String data) throws ParseException {
return examDelayParser.parse(data);
}
}

@ -1,62 +0,0 @@
package cn.wustlinghang.wusthelper.internal.library.services;
import cn.wustlinghang.mywust.core.request.service.undergraduate.*;
import cn.wustlinghang.mywust.exception.ApiException;
import jakarta.enterprise.context.ApplicationScoped;
import java.io.IOException;
@ApplicationScoped
public class RequestAgentService {
private final UndergradCourseTableApiService courseTableApiService;
private final UndergradScoreApiService scoreApiService;
private final UndergradStudentInfoApiService studentInfoApiService;
private final UndergradTrainingPlanApiService trainingPlanApiService;
private final UndergradCreditStatusApiService creditStatusApiService;
private final UndergradExamDelayApiService examDelayApiService;
public RequestAgentService(UndergradCourseTableApiService courseTableApiService,
UndergradScoreApiService scoreApiService,
UndergradStudentInfoApiService studentInfoApiService,
UndergradTrainingPlanApiService trainingPlanApiService,
UndergradCreditStatusApiService creditStatusApiService,
UndergradExamDelayApiService examDelayApiService) {
this.courseTableApiService = courseTableApiService;
this.scoreApiService = scoreApiService;
this.studentInfoApiService = studentInfoApiService;
this.trainingPlanApiService = trainingPlanApiService;
this.creditStatusApiService = creditStatusApiService;
this.examDelayApiService = examDelayApiService;
}
public String getStudentInfoPage(String cookie) throws IOException, ApiException {
return studentInfoApiService.getPage(cookie);
}
public String getCourseTable(String cookie, String term) throws IOException, ApiException {
return courseTableApiService.getPage(term, cookie);
}
public String getScore(String cookie) throws IOException, ApiException {
return scoreApiService.getPage(cookie);
}
public String getTrainingPlan(String cookie) throws IOException, ApiException {
return trainingPlanApiService.getPage(cookie);
}
public String getCreditStatus(String cookie) throws IOException, ApiException {
return creditStatusApiService.getPage(cookie, null, false);
}
public UndergradExamDelayApiService.ExamActivity[] getExamActivities(String cookie, String term)
throws IOException, ApiException {
return examDelayApiService.getActivities(term, cookie);
}
public String getExamDelayApplications(String cookie, String term, String activityId)
throws IOException, ApiException {
return examDelayApiService.getPage(term, activityId, cookie);
}
}

@ -0,0 +1,16 @@
package cn.wustlinghang.wusthelper.internal.undergrad;
import io.quarkus.runtime.Startup;
import jakarta.annotation.PostConstruct;
import jakarta.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Startup
@Singleton
public class Main {
@PostConstruct
public void run() {
log.info("Undergrad service started.");
}
}

@ -1,7 +1,7 @@
package cn.wustlinghang.wusthelper.internal.physics.api.json;
package cn.wustlinghang.wusthelper.internal.undergrad.api.json;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.wusthelper.internal.physics.services.LoginService;
import cn.wustlinghang.wusthelper.internal.undergrad.services.LoginService;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
@ -20,13 +20,13 @@ public class CookieApi {
@GET
@Path("/")
public String login(@QueryParam("username") @NotNull String username,
@QueryParam("password") @NotNull String password) throws IOException, ApiException {
@QueryParam("password") @NotNull String password) throws RpcException {
return loginService.login(username, password, false);
}
@GET
@Path("/verify")
public Boolean verify(@QueryParam("cookie") @NotNull String cookie) throws IOException {
public Boolean verify(@QueryParam("cookie") @NotNull String cookie) throws RpcException {
return loginService.verify(cookie);
}
}

@ -0,0 +1,52 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.json;
import cn.wustlinghang.mywust.data.global.Course;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.internal.undergrad.services.ParseService;
import cn.wustlinghang.wusthelper.internal.undergrad.services.RequestAgentService;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
import java.util.List;
@Path("/course_table")
@ApplicationScoped
public class CourseTableApi {
private final RequestAgentService agentService;
private final ParseService parseService;
public CourseTableApi(RequestAgentService agentService,
ParseService parseService) {
this.agentService = agentService;
this.parseService = parseService;
}
@GET
@Path("/")
public List<Course> get(@QueryParam("cookie") @NotNull String cookie,
@QueryParam("term") String term)
throws RpcException {
return this.parse(this.agent(cookie, term));
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie,
@QueryParam("term") String term)
throws RpcException {
return agentService.getCourseTable(cookie, term);
}
@POST
@Path("/parse")
public List<Course> parse(String html) throws RpcException {
return parseService.parseCourseTable(html);
}
}

@ -0,0 +1,49 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.json;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.internal.undergrad.services.ParseService;
import cn.wustlinghang.wusthelper.internal.undergrad.services.RequestAgentService;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
@Path("/credit_status")
@ApplicationScoped
public class CreditStatusApi {
private final RequestAgentService agentService;
private final ParseService parseService;
public CreditStatusApi(RequestAgentService agentService,
ParseService parseService) {
this.agentService = agentService;
this.parseService = parseService;
}
@GET
@Path("/")
public String get(@QueryParam("cookie") @NotNull String cookie)
throws RpcException {
String html = this.agent(cookie);
return this.parse(html);
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie)
throws RpcException {
return agentService.getCreditStatus(cookie);
}
@POST
@Path("/parse")
public String parse(String html) throws RpcException {
return parseService.parseCreditStatus(html);
}
}

@ -0,0 +1,48 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.json;
import cn.wustlinghang.mywust.core.request.service.undergraduate.UndergradExamDelayApiService;
import cn.wustlinghang.mywust.data.global.Score;
import cn.wustlinghang.wusthelper.internal.undergrad.services.RequestAgentService;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.util.List;
@Path("/exam_activities")
@ApplicationScoped
public class ExamActivitiesApi {
private final RequestAgentService agentService;
public ExamActivitiesApi(RequestAgentService agentService) {
this.agentService = agentService;
}
@GET
@Path("/")
public UndergradExamDelayApiService.ExamActivity[] get(
@QueryParam("cookie") @NotNull String cookie,
@QueryParam("term") @NotNull String term)
throws RpcException {
return this.agent(cookie, term);
}
@GET
@Path("/agent")
public UndergradExamDelayApiService.ExamActivity[] agent(
@QueryParam("cookie") @NotNull String cookie,
@QueryParam("term") @NotNull String term)
throws RpcException {
return agentService.getExamActivities(cookie, term);
}
@POST
@Path("/parse")
public List<Score> parse(String html) throws RpcException {
throw RpcException.ApiNotImplement();
}
}

@ -0,0 +1,52 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.json;
import cn.wustlinghang.mywust.data.undergrad.ExamDelayApplication;
import cn.wustlinghang.wusthelper.internal.undergrad.services.ParseService;
import cn.wustlinghang.wusthelper.internal.undergrad.services.RequestAgentService;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.util.List;
@Path("/exam_delay_application")
@ApplicationScoped
public class ExamDelayApplicationApi {
private final RequestAgentService agentService;
private final ParseService parseService;
public ExamDelayApplicationApi(RequestAgentService agentService,
ParseService parseService) {
this.agentService = agentService;
this.parseService = parseService;
}
@GET
@Path("/")
public List<ExamDelayApplication> get(
@QueryParam("cookie") @NotNull String cookie,
@QueryParam("term") @NotNull String term,
@QueryParam("activity_id") @NotNull String activityId)
throws RpcException {
return this.parse(this.agent(cookie, term, activityId));
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie,
@QueryParam("term") @NotNull String term,
@QueryParam("activity_id") @NotNull String activityId)
throws RpcException {
return agentService.getExamDelayApplications(cookie, term, activityId);
}
@POST
@Path("/parse")
public List<ExamDelayApplication> parse(String html) throws RpcException {
return parseService.parseExamDelayApplications(html);
}
}

@ -0,0 +1,50 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.json;
import cn.wustlinghang.mywust.data.global.Score;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.internal.undergrad.services.ParseService;
import cn.wustlinghang.wusthelper.internal.undergrad.services.RequestAgentService;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
import java.util.List;
@Path("/score")
@ApplicationScoped
public class ScoreApi {
private final RequestAgentService agentService;
private final ParseService parseService;
public ScoreApi(RequestAgentService agentService,
ParseService parseService) {
this.agentService = agentService;
this.parseService = parseService;
}
@GET
@Path("/")
public List<Score> get(@QueryParam("cookie") @NotNull String cookie)
throws RpcException {
return this.parse(this.agent(cookie));
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie)
throws RpcException {
return agentService.getScore(cookie);
}
@POST
@Path("/parse")
public List<Score> parse(String html) throws RpcException {
return parseService.parseScore(html);
}
}

@ -0,0 +1,50 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.json;
import cn.wustlinghang.mywust.data.global.StudentInfo;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.internal.undergrad.exception.UndergradRpcException;
import cn.wustlinghang.wusthelper.internal.undergrad.services.ParseService;
import cn.wustlinghang.wusthelper.internal.undergrad.services.RequestAgentService;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
@Path("/student_info")
@ApplicationScoped
public class StudentInfoApi {
private final RequestAgentService agentService;
private final ParseService parseService;
public StudentInfoApi(RequestAgentService agentService,
ParseService parseService) {
this.agentService = agentService;
this.parseService = parseService;
}
@GET
@Path("/")
public StudentInfo get(@QueryParam("cookie") @NotNull String cookie)
throws RpcException {
return this.parse(this.agent(cookie));
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie)
throws RpcException {
return agentService.getStudentInfoPage(cookie);
}
@POST
@Path("/parse")
public StudentInfo parse(String html) throws RpcException {
return parseService.parseStudentInfo(html);
}
}

@ -0,0 +1,48 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.json;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.internal.undergrad.services.ParseService;
import cn.wustlinghang.wusthelper.internal.undergrad.services.RequestAgentService;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
@Path("/training_plan")
@ApplicationScoped
public class TrainingPlanApi {
private final RequestAgentService agentService;
private final ParseService parseService;
public TrainingPlanApi(RequestAgentService agentService,
ParseService parseService) {
this.agentService = agentService;
this.parseService = parseService;
}
@GET
@Path("/")
public String get(@QueryParam("cookie") @NotNull String cookie)
throws RpcException {
return this.parse(this.agent(cookie));
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie)
throws RpcException {
return agentService.getTrainingPlan(cookie);
}
@POST
@Path("/parse")
public String parse(String html) throws RpcException {
return parseService.parseTrainingPlan(html);
}
}

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.json.handler;
package cn.wustlinghang.wusthelper.internal.undergrad.api.json.handler;
import cn.wustlinghang.wusthelper.rpc.response.ResponseCode;
import cn.wustlinghang.wusthelper.rpc.response.RpcResponse;
@ -7,7 +7,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
public abstract class ExceptionHandlerBase {
public abstract class BaseExceptionHandler {
public static final String EXCEPTION_HEADER_KEY = "X-exception-handler";
private static final ObjectMapper objectMapper = new ObjectMapper();
@ -17,6 +17,14 @@ public abstract class ExceptionHandlerBase {
}
public Response toResponse(int code, String msg, String handlerName) {
return toResponse(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), code, msg, handlerName);
}
public Response toResponse(int status, int code, String msg, String handlerName) {
return toResponse(Response.Status.fromStatusCode(status), code, msg, handlerName);
}
public Response toResponse(Response.Status status, int code, String msg, String handlerName) {
Object response;
try {
response = objectMapper.writeValueAsString(RpcResponse.error(code, msg));
@ -24,7 +32,7 @@ public abstract class ExceptionHandlerBase {
response = RpcResponse.error(ResponseCode.SERVER_INTERNAL_ERROR);
}
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
return Response.status(status)
.entity(response)
.header(EXCEPTION_HEADER_KEY, handlerName)
.type(MediaType.APPLICATION_JSON)

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.library.api.json.handler;
package cn.wustlinghang.wusthelper.internal.undergrad.api.json.handler;
import cn.wustlinghang.wusthelper.rpc.response.ResponseCode;
import jakarta.ws.rs.core.Response;
@ -8,7 +8,7 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
@Provider
public class DefaultExceptionHandler extends ExceptionHandlerBase implements ExceptionMapper<Exception> {
public class DefaultExceptionHandler extends BaseExceptionHandler implements ExceptionMapper<Exception> {
@Override
public Response toResponse(Exception e) {
log.error("未知异常:", e);

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.physics.api.json.handler;
package cn.wustlinghang.wusthelper.internal.undergrad.api.json.handler;
import cn.wustlinghang.wusthelper.rpc.response.ResponseCode;
import jakarta.ws.rs.core.Response;
@ -10,7 +10,7 @@ import java.io.IOException;
@Slf4j
@Provider
public class IOExceptionHandler extends ExceptionHandlerBase implements ExceptionMapper<IOException> {
public class IOExceptionHandler extends BaseExceptionHandler implements ExceptionMapper<IOException> {
@Override
public Response toResponse(IOException e) {
log.error("IO异常:", e);

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.physics.api.json.handler;
package cn.wustlinghang.wusthelper.internal.undergrad.api.json.handler;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.rpc.response.ResponseCode;
@ -9,7 +9,7 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
@Provider
public class ParseExceptionHandler extends ExceptionHandlerBase implements ExceptionMapper<ParseException> {
public class ParseExceptionHandler extends BaseExceptionHandler implements ExceptionMapper<ParseException> {
@Override
public Response toResponse(ParseException e) {
log.error("解析异常:", e);

@ -0,0 +1,17 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.json.handler;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
@Provider
public class RpcExceptionHandler extends BaseExceptionHandler implements ExceptionMapper<RpcException> {
@Override
public Response toResponse(RpcException e) {
return super.toResponse(
e.getCode(),
e.toString(),
"RpcExceptionHandler");
}
}

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.json.handler;
package cn.wustlinghang.wusthelper.internal.undergrad.api.json.handler;
import cn.wustlinghang.wusthelper.rpc.response.ResponseCode;
import jakarta.validation.ValidationException;
@ -9,7 +9,7 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
@Provider
public class ValidationExceptionHandler extends ExceptionHandlerBase
public class ValidationExceptionHandler extends BaseExceptionHandler
implements ExceptionMapper<ValidationException> {
@Override
public Response toResponse(ValidationException e) {

@ -0,0 +1,26 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.json.handler;
import cn.wustlinghang.wusthelper.internal.undergrad.exception.UndergradRpcException;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
@Provider
public class WebApplicationExceptionHandler extends BaseExceptionHandler implements ExceptionMapper<WebApplicationException> {
@Override
public Response toResponse(WebApplicationException e) {
return super.toResponse(
e.getResponse().getStatus(),
RpcException.toIntCode(
UndergradRpcException.UNDERGRAD_MODULE,
UndergradRpcException.SubModuleCode.COMMON.ordinal(),
UndergradRpcException.TypeCode.OTHER_EXCEPTION.ordinal() * 100
+ UndergradRpcException.ErrorCode.REQUEST_INVALID.ordinal()
),
e.getMessage(),
"WebApplicationExceptionHandler"
);
}
}

@ -1,6 +1,6 @@
package cn.wustlinghang.wusthelper.internal.library.api.json.interceptor;
package cn.wustlinghang.wusthelper.internal.undergrad.api.json.interceptor;
import cn.wustlinghang.wusthelper.internal.library.api.json.handler.ExceptionHandlerBase;
import cn.wustlinghang.wusthelper.internal.undergrad.api.json.handler.BaseExceptionHandler;
import cn.wustlinghang.wusthelper.rpc.response.RpcResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.ws.rs.WebApplicationException;
@ -22,7 +22,7 @@ public class ResponseWrapperInterceptor implements WriterInterceptor {
@Override
public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
boolean hasException = context.getHeaders().get(ExceptionHandlerBase.EXCEPTION_HEADER_KEY) != null;
boolean hasException = context.getHeaders().get(BaseExceptionHandler.EXCEPTION_HEADER_KEY) != null;
if (!hasException) {
Object data = context.getEntity();
RpcResponse<Object> wrappedResponse = RpcResponse.success(data);

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.graduate.bean;
package cn.wustlinghang.wusthelper.internal.undergrad.bean;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.enterprise.context.ApplicationScoped;

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.graduate.bean;
package cn.wustlinghang.wusthelper.internal.undergrad.bean;
import cn.wustlinghang.mywust.core.parser.undergraduate.*;
import jakarta.enterprise.context.ApplicationScoped;

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.physics.bean;
package cn.wustlinghang.wusthelper.internal.undergrad.bean;
import cn.wustlinghang.mywust.core.request.service.auth.UndergraduateLogin;
import cn.wustlinghang.mywust.core.request.service.undergraduate.*;

@ -0,0 +1,73 @@
package cn.wustlinghang.wusthelper.internal.undergrad.exception;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import java.util.StringJoiner;
public class UndergradRpcException extends RpcException {
public static final int UNDERGRAD_MODULE = 1;
public UndergradRpcException(TypeCode typeCode,
SubModuleCode subModuleCode,
ErrorCode errorCode) {
super(UNDERGRAD_MODULE,
typeCode.ordinal(),
subModuleCode.ordinal() * 100 + errorCode.ordinal(),
new StringJoiner("-")
.add("UNDERGRAD")
.add(typeCode.name())
.add(subModuleCode.name())
.add(errorCode.name())
.toString()
);
}
/**
* 异常类型编码
*/
public enum TypeCode {
// 网络异常类型
NETWORK_EXCEPTION,
// 参数异常类型
PARAM_EXCEPTION,
// 权限认证异常类型
AUTH_EXCEPTION,
// 网页解析异常类型
PARSE_EXCEPTION,
// 其他的异常类型
OTHER_EXCEPTION
}
/**
* 子模块编码
*/
public enum SubModuleCode {
COMMON, AUTH, COURSE_TABLE, CREDIT_STATUS, SCORE,
STUDENT_INFO, TRAINING_PLAN, EXAM_ACTIVITIES, EXAM_DELAY_APPLICATION
}
/**
* 具体错误编码
*/
public enum ErrorCode {
REQUEST_INVALID,
PARAM_INVALID,
COOKIE_INVALID,
NETWORK_ERROR,
PARSE_ERROR,
// 需要评教
NEED_EVALUATE,
AUTH_PASSWORD_WRONG,
// 用户不存在
AUTH_USER_NOT_EXISTS,
// 封号
AUTH_USER_BANNED,
// 用户账号禁用
AUTH_USER_DISABLED,
// 用户账号需要更改
AUTH_NEED_CHANGE_PASSWORD,
AUTH_UNKNOWN_ERROR
}
}

@ -0,0 +1,78 @@
package cn.wustlinghang.wusthelper.internal.undergrad.services;
import cn.wustlinghang.mywust.core.request.service.auth.UndergraduateLogin;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.network.RequestClientOption;
import cn.wustlinghang.wusthelper.internal.undergrad.exception.UndergradRpcException;
import jakarta.enterprise.context.ApplicationScoped;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
@Slf4j
@ApplicationScoped
public class LoginService {
private final RequestClientOption option;
private final UndergraduateLogin undergraduateLogin;
public LoginService(RequestClientOption option,
UndergraduateLogin undergraduateLogin) {
this.option = option;
this.undergraduateLogin = undergraduateLogin;
}
public String login(String username, String password, boolean legacy) throws UndergradRpcException {
try {
if (legacy) {
return undergraduateLogin.getLoginCookieLegacy(username, password, option);
} else {
return undergraduateLogin.getLoginCookie(username, password, option);
}
} catch (ApiException e) {
throw wrapApiException(e);
} catch (IOException e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
UndergradRpcException.SubModuleCode.AUTH,
UndergradRpcException.ErrorCode.NETWORK_ERROR
);
}
}
public boolean verify(String cookie) throws UndergradRpcException {
try {
return !undergraduateLogin.checkCookiesFail(cookie);
} catch (IOException e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
UndergradRpcException.SubModuleCode.AUTH,
UndergradRpcException.ErrorCode.NETWORK_ERROR
);
}
}
private UndergradRpcException wrapApiException(ApiException e) {
UndergradRpcException.ErrorCode errorCode = switch (e.getCode()) {
case NETWORK_EXCEPTION -> UndergradRpcException.ErrorCode.NETWORK_ERROR;
case UNI_LOGIN_PASSWORD_WRONG -> UndergradRpcException.ErrorCode.AUTH_PASSWORD_WRONG;
case UNI_LOGIN_USER_NOT_EXISTS -> UndergradRpcException.ErrorCode.AUTH_USER_NOT_EXISTS;
case UNI_LOGIN_USER_BANNED -> UndergradRpcException.ErrorCode.AUTH_USER_BANNED;
case UNI_LOGIN_USER_DISABLED -> UndergradRpcException.ErrorCode.AUTH_USER_DISABLED;
case UNI_LOGIN_NEED_CHANGE_PASSWORD -> UndergradRpcException.ErrorCode.AUTH_NEED_CHANGE_PASSWORD;
case UNI_LOGIN_USER_NOT_ONLY -> UndergradRpcException.ErrorCode.AUTH_UNKNOWN_ERROR;
case UNI_LOGIN_NO_REGISTER -> UndergradRpcException.ErrorCode.AUTH_UNKNOWN_ERROR;
case UNI_LOGIN_NEED_TFA -> UndergradRpcException.ErrorCode.AUTH_UNKNOWN_ERROR;
default -> {
log.error("本科生:登录代理请求异常,异常未处理");
log.error("异常:", e);
yield UndergradRpcException.ErrorCode.AUTH_UNKNOWN_ERROR;
}
};
return new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
UndergradRpcException.SubModuleCode.AUTH,
errorCode
);
}
}

@ -0,0 +1,132 @@
package cn.wustlinghang.wusthelper.internal.undergrad.services;
import cn.wustlinghang.mywust.core.parser.undergraduate.*;
import cn.wustlinghang.mywust.data.global.Course;
import cn.wustlinghang.mywust.data.global.Score;
import cn.wustlinghang.mywust.data.global.StudentInfo;
import cn.wustlinghang.mywust.data.undergrad.ExamDelayApplication;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.internal.undergrad.exception.UndergradRpcException;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.enterprise.context.ApplicationScoped;
import java.util.List;
@ApplicationScoped
public class ParseService {
private final UndergradCourseTableParser courseTableParser;
private final UndergradScoreParser scoreParser;
private final UndergradStudentInfoPageParser studentInfoPageParser;
private final UndergradTrainingPlanPageParser trainingPlanPageParser;
private final UndergradCreditStatusParser creditStatusParser;
private final UndergradExamDelayParser examDelayParser;
public ParseService(UndergradCourseTableParser courseTableParser,
UndergradScoreParser scoreParser,
UndergradStudentInfoPageParser studentInfoPageParser,
UndergradTrainingPlanPageParser trainingPlanPageParser,
UndergradCreditStatusParser creditStatusParser,
UndergradExamDelayParser examDelayParser) {
this.courseTableParser = courseTableParser;
this.scoreParser = scoreParser;
this.studentInfoPageParser = studentInfoPageParser;
this.trainingPlanPageParser = trainingPlanPageParser;
this.creditStatusParser = creditStatusParser;
this.examDelayParser = examDelayParser;
}
public List<Course> parseCourseTable(String data) throws UndergradRpcException {
try {
if (data.contains("评教")) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.PARSE_EXCEPTION,
UndergradRpcException.SubModuleCode.COURSE_TABLE,
UndergradRpcException.ErrorCode.NEED_EVALUATE
);
}
return courseTableParser.parse(data);
} catch (UndergradRpcException e) {
throw e;
} catch (Exception e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.PARSE_EXCEPTION,
UndergradRpcException.SubModuleCode.COURSE_TABLE,
UndergradRpcException.ErrorCode.PARSE_ERROR
);
}
}
public List<Score> parseScore(String data) throws RpcException {
try {
if (data.contains("评教")) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.PARSE_EXCEPTION,
UndergradRpcException.SubModuleCode.SCORE,
UndergradRpcException.ErrorCode.NEED_EVALUATE
);
}
return scoreParser.parse(data);
} catch (UndergradRpcException e) {
throw e;
} catch (Exception e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.PARSE_EXCEPTION,
UndergradRpcException.SubModuleCode.SCORE,
UndergradRpcException.ErrorCode.PARSE_ERROR
);
}
}
public StudentInfo parseStudentInfo(String data) throws RpcException {
try {
return studentInfoPageParser.parse(data);
} catch (Exception e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.PARSE_EXCEPTION,
UndergradRpcException.SubModuleCode.STUDENT_INFO,
UndergradRpcException.ErrorCode.PARSE_ERROR
);
}
}
public String parseTrainingPlan(String data) throws RpcException {
try {
return trainingPlanPageParser.parse(data);
} catch (Exception e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.PARSE_EXCEPTION,
UndergradRpcException.SubModuleCode.TRAINING_PLAN,
UndergradRpcException.ErrorCode.PARSE_ERROR
);
}
}
public String parseCreditStatus(String data) throws RpcException {
try {
return creditStatusParser.parse(data);
} catch (Exception e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.PARSE_EXCEPTION,
UndergradRpcException.SubModuleCode.CREDIT_STATUS,
UndergradRpcException.ErrorCode.PARSE_ERROR
);
}
}
public List<ExamDelayApplication> parseExamDelayApplications(String data) throws RpcException {
try {
return examDelayParser.parse(data);
} catch (Exception e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.PARSE_EXCEPTION,
UndergradRpcException.SubModuleCode.EXAM_DELAY_APPLICATION,
UndergradRpcException.ErrorCode.PARSE_ERROR
);
}
}
}

@ -0,0 +1,166 @@
package cn.wustlinghang.wusthelper.internal.undergrad.services;
import cn.wustlinghang.mywust.core.request.service.undergraduate.*;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.network.RequestClientOption;
import cn.wustlinghang.wusthelper.internal.undergrad.exception.UndergradRpcException;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.enterprise.context.ApplicationScoped;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
@Slf4j
@ApplicationScoped
public class RequestAgentService {
private final UndergradCourseTableApiService courseTableApiService;
private final UndergradScoreApiService scoreApiService;
private final UndergradStudentInfoApiService studentInfoApiService;
private final UndergradTrainingPlanApiService trainingPlanApiService;
private final UndergradCreditStatusApiService creditStatusApiService;
private final UndergradExamDelayApiService examDelayApiService;
private final RequestClientOption requestClientOption;
public RequestAgentService(UndergradCourseTableApiService courseTableApiService,
UndergradScoreApiService scoreApiService,
UndergradStudentInfoApiService studentInfoApiService,
UndergradTrainingPlanApiService trainingPlanApiService,
UndergradCreditStatusApiService creditStatusApiService,
UndergradExamDelayApiService examDelayApiService,
RequestClientOption requestClientOption) {
this.courseTableApiService = courseTableApiService;
this.scoreApiService = scoreApiService;
this.studentInfoApiService = studentInfoApiService;
this.trainingPlanApiService = trainingPlanApiService;
this.creditStatusApiService = creditStatusApiService;
this.examDelayApiService = examDelayApiService;
this.requestClientOption = requestClientOption;
}
public String getStudentInfoPage(String cookie) throws RpcException {
try {
return studentInfoApiService.getPage(cookie);
} catch (ApiException e) {
throw wrapApiException(e, UndergradRpcException.SubModuleCode.STUDENT_INFO);
} catch (IOException e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
UndergradRpcException.SubModuleCode.STUDENT_INFO,
UndergradRpcException.ErrorCode.NETWORK_ERROR
);
}
}
public String getCourseTable(String cookie, String term) throws RpcException {
try {
return courseTableApiService.getPage(term, cookie);
} catch (ApiException e) {
throw wrapApiException(e, UndergradRpcException.SubModuleCode.COURSE_TABLE);
} catch (IOException e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
UndergradRpcException.SubModuleCode.COURSE_TABLE,
UndergradRpcException.ErrorCode.NETWORK_ERROR
);
}
}
public String getScore(String cookie) throws RpcException {
try {
return scoreApiService.getPage(cookie);
} catch (ApiException e) {
throw wrapApiException(e, UndergradRpcException.SubModuleCode.SCORE);
} catch (IOException e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
UndergradRpcException.SubModuleCode.SCORE,
UndergradRpcException.ErrorCode.NETWORK_ERROR
);
}
}
public String getTrainingPlan(String cookie) throws RpcException {
try {
return trainingPlanApiService.getPage(cookie);
} catch (ApiException e) {
throw wrapApiException(e, UndergradRpcException.SubModuleCode.TRAINING_PLAN);
} catch (IOException e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
UndergradRpcException.SubModuleCode.TRAINING_PLAN,
UndergradRpcException.ErrorCode.NETWORK_ERROR
);
}
}
public String getCreditStatus(String cookie) throws RpcException {
try {
return creditStatusApiService.getPage(cookie, requestClientOption, false);
} catch (ApiException e) {
throw wrapApiException(e, UndergradRpcException.SubModuleCode.CREDIT_STATUS);
} catch (IOException e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
UndergradRpcException.SubModuleCode.CREDIT_STATUS,
UndergradRpcException.ErrorCode.NETWORK_ERROR
);
}
}
public UndergradExamDelayApiService.ExamActivity[] getExamActivities(String cookie, String term)
throws RpcException {
try {
return examDelayApiService.getActivities(term, cookie);
} catch (ApiException e) {
throw wrapApiException(e, UndergradRpcException.SubModuleCode.EXAM_ACTIVITIES);
} catch (IOException e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
UndergradRpcException.SubModuleCode.EXAM_ACTIVITIES,
UndergradRpcException.ErrorCode.NETWORK_ERROR
);
}
}
public String getExamDelayApplications(String cookie, String term, String activityId)
throws RpcException {
try {
return examDelayApiService.getPage(term, activityId, cookie);
} catch (ApiException e) {
throw wrapApiException(e, UndergradRpcException.SubModuleCode.EXAM_DELAY_APPLICATION);
} catch (IOException e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
UndergradRpcException.SubModuleCode.EXAM_DELAY_APPLICATION,
UndergradRpcException.ErrorCode.NETWORK_ERROR
);
}
}
private UndergradRpcException wrapApiException(ApiException e, UndergradRpcException.SubModuleCode subModuleCode) {
return switch (e.getCode()) {
case NETWORK_EXCEPTION -> new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
subModuleCode,
UndergradRpcException.ErrorCode.NETWORK_ERROR
);
case COOKIE_INVALID -> new UndergradRpcException(
UndergradRpcException.TypeCode.AUTH_EXCEPTION,
subModuleCode,
UndergradRpcException.ErrorCode.COOKIE_INVALID
);
default -> {
log.error("本科生:{}代理请求异常,异常未处理", subModuleCode.name());
log.error("异常:", e);
yield new UndergradRpcException(
UndergradRpcException.TypeCode.AUTH_EXCEPTION,
subModuleCode,
UndergradRpcException.ErrorCode.COOKIE_INVALID
);
}
};
}
}

@ -1,52 +0,0 @@
package cn.wustlinghang.wusthelper.internal.physics.api.json;
import cn.wustlinghang.mywust.core.parser.undergraduate.UndergradCourseTableParser;
import cn.wustlinghang.mywust.core.request.service.undergraduate.UndergradCourseTableApiService;
import cn.wustlinghang.mywust.data.global.Course;
import cn.wustlinghang.mywust.data.global.StudentInfo;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.rpc.response.RpcResponse;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
import java.util.List;
@Path("/course_table")
@ApplicationScoped
public class CourseTableApi {
private final UndergradCourseTableApiService studentInfoApiService;
private final UndergradCourseTableParser studentInfoPageParser;
public CourseTableApi(UndergradCourseTableApiService studentInfoApiService,
UndergradCourseTableParser studentInfoPageParser) {
this.studentInfoApiService = studentInfoApiService;
this.studentInfoPageParser = studentInfoPageParser;
}
@GET
@Path("/")
public List<Course> get(@QueryParam("cookie") @NotNull String cookie, @QueryParam("term") String term)
throws IOException, ApiException, ParseException {
String html = studentInfoApiService.getPage(term, cookie);
return this.parse(html);
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie, @QueryParam("term") String term)
throws IOException, ApiException {
return studentInfoApiService.getPage(term, cookie);
}
@POST
@Path("/parse")
public List<Course> parse(String html) throws ParseException {
return studentInfoPageParser.parse(html);
}
}

@ -1,54 +0,0 @@
package cn.wustlinghang.wusthelper.internal.physics.api.json;
import cn.wustlinghang.mywust.core.parser.undergraduate.UndergradCreditStatusParser;
import cn.wustlinghang.mywust.core.request.service.undergraduate.UndergradCreditStatusApiService;
import cn.wustlinghang.mywust.data.global.StudentInfo;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.mywust.network.RequestClientOption;
import cn.wustlinghang.wusthelper.rpc.response.RpcResponse;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
@Path("/credit_status")
@ApplicationScoped
public class CreditStatusApi {
private final UndergradCreditStatusApiService creditStatusApiService;
private final UndergradCreditStatusParser creditStatusParser;
private final RequestClientOption option;
public CreditStatusApi(UndergradCreditStatusApiService creditStatusApiService,
UndergradCreditStatusParser creditStatusParser,
RequestClientOption option) {
this.creditStatusApiService = creditStatusApiService;
this.creditStatusParser = creditStatusParser;
this.option = option;
}
@GET
@Path("/")
public String get(String cookie) throws IOException, ApiException, ParseException {
String html = creditStatusApiService.getPage(cookie, option, false);
return this.parse(html);
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie)
throws IOException, ApiException {
return creditStatusApiService.getPage(cookie, option, false);
}
@POST
@Path("/parse")
public String parse(String html) throws ParseException {
return creditStatusParser.parse(html);
}
}

@ -1,50 +0,0 @@
package cn.wustlinghang.wusthelper.internal.physics.api.json;
import cn.wustlinghang.mywust.core.parser.undergraduate.UndergradScoreParser;
import cn.wustlinghang.mywust.core.request.service.undergraduate.UndergradScoreApiService;
import cn.wustlinghang.mywust.data.global.Score;
import cn.wustlinghang.mywust.data.global.StudentInfo;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.rpc.response.RpcResponse;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
import java.util.List;
@Path("/score")
@ApplicationScoped
public class ScoreApi {
private final UndergradScoreApiService scoreApiService;
private final UndergradScoreParser scoreParser;
public ScoreApi(UndergradScoreApiService scoreApiService, UndergradScoreParser scoreParser) {
this.scoreApiService = scoreApiService;
this.scoreParser = scoreParser;
}
@GET
@Path("/")
public List<Score> get(String cookie) throws IOException, ApiException, ParseException {
String html = scoreApiService.getPage(cookie);
return this.parse(html);
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie)
throws IOException, ApiException {
return scoreApiService.getPage(cookie);
}
@POST
@Path("/parse")
public List<Score> parse(String html) throws ParseException {
return scoreParser.parse(html);
}
}

@ -1,47 +0,0 @@
package cn.wustlinghang.wusthelper.internal.physics.api.json;
import cn.wustlinghang.mywust.core.parser.undergraduate.UndergradStudentInfoPageParser;
import cn.wustlinghang.mywust.core.request.service.undergraduate.UndergradStudentInfoApiService;
import cn.wustlinghang.mywust.data.global.StudentInfo;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
@Path("/student_info")
@ApplicationScoped
public class StudentInfoApi {
private final UndergradStudentInfoApiService studentInfoApiService;
private final UndergradStudentInfoPageParser studentInfoPageParser;
public StudentInfoApi(UndergradStudentInfoApiService studentInfoApiService,
UndergradStudentInfoPageParser studentInfoPageParser) {
this.studentInfoApiService = studentInfoApiService;
this.studentInfoPageParser = studentInfoPageParser;
}
@GET
@Path("/")
public StudentInfo get(@QueryParam("cookie") @NotNull String cookie) throws IOException, ApiException, ParseException {
return this.parse(this.agent(cookie));
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie)
throws IOException, ApiException {
return studentInfoApiService.getPage(cookie);
}
@POST
@Path("/parse")
public StudentInfo parse(String html) throws ParseException {
return studentInfoPageParser.parse(html);
}
}

@ -1,47 +0,0 @@
package cn.wustlinghang.wusthelper.internal.physics.api.json;
import cn.wustlinghang.mywust.core.parser.undergraduate.UndergradTrainingPlanPageParser;
import cn.wustlinghang.mywust.core.request.service.undergraduate.UndergradTrainingPlanApiService;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
@Path("/training_plan")
@ApplicationScoped
public class TrainingPlanApi {
private final UndergradTrainingPlanApiService trainingPlanApiService;
private final UndergradTrainingPlanPageParser trainingPlanPageParser;
public TrainingPlanApi(UndergradTrainingPlanApiService trainingPlanApiService,
UndergradTrainingPlanPageParser trainingPlanPageParser) {
this.trainingPlanApiService = trainingPlanApiService;
this.trainingPlanPageParser = trainingPlanPageParser;
}
@GET
@Path("/")
public String get(String cookie) throws IOException, ApiException, ParseException {
String html = trainingPlanApiService.getPage(cookie);
return this.parse(html);
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie)
throws IOException, ApiException {
return trainingPlanApiService.getPage(cookie);
}
@POST
@Path("/parse")
public String parse(String html) throws ParseException {
return trainingPlanPageParser.parse(html);
}
}

@ -1,14 +0,0 @@
package cn.wustlinghang.wusthelper.internal.physics.api.json.handler;
import cn.wustlinghang.mywust.exception.ApiException;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
@Provider
public class ApiExceptionHandler extends ExceptionHandlerBase implements ExceptionMapper<ApiException> {
@Override
public Response toResponse(ApiException e) {
return super.toResponse(e.getCodeValue(), e.toString(), "ApiExceptionHandler");
}
}

@ -1,32 +0,0 @@
package cn.wustlinghang.wusthelper.internal.physics.services;
import cn.wustlinghang.mywust.core.request.service.auth.UndergraduateLogin;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.network.RequestClientOption;
import jakarta.enterprise.context.ApplicationScoped;
import java.io.IOException;
@ApplicationScoped
public class LoginService {
private final RequestClientOption option;
private final UndergraduateLogin undergraduateLogin;
public LoginService(RequestClientOption option,
UndergraduateLogin undergraduateLogin) {
this.option = option;
this.undergraduateLogin = undergraduateLogin;
}
public String login(String username, String password, boolean legacy) throws IOException, ApiException {
if (legacy) {
return undergraduateLogin.getLoginCookieLegacy(username, password, option);
} else {
return undergraduateLogin.getLoginCookie(username, password, option);
}
}
public boolean verify(String cookie) throws IOException {
return !undergraduateLogin.checkCookiesFail(cookie);
}
}

@ -1,60 +0,0 @@
package cn.wustlinghang.wusthelper.internal.physics.services;
import cn.wustlinghang.mywust.core.parser.undergraduate.*;
import cn.wustlinghang.mywust.data.global.Course;
import cn.wustlinghang.mywust.data.global.Score;
import cn.wustlinghang.mywust.data.global.StudentInfo;
import cn.wustlinghang.mywust.data.undergrad.ExamDelayApplication;
import cn.wustlinghang.mywust.exception.ParseException;
import jakarta.enterprise.context.ApplicationScoped;
import java.util.List;
@ApplicationScoped
public class ParseService {
private final UndergradCourseTableParser courseTableParser;
private final UndergradScoreParser scoreParser;
private final UndergradStudentInfoPageParser studentInfoPageParser;
private final UndergradTrainingPlanPageParser trainingPlanPageParser;
private final UndergradCreditStatusParser creditStatusParser;
private final UndergradExamDelayParser examDelayParser;
public ParseService(UndergradCourseTableParser courseTableParser,
UndergradScoreParser scoreParser,
UndergradStudentInfoPageParser studentInfoPageParser,
UndergradTrainingPlanPageParser trainingPlanPageParser,
UndergradCreditStatusParser creditStatusParser,
UndergradExamDelayParser examDelayParser) {
this.courseTableParser = courseTableParser;
this.scoreParser = scoreParser;
this.studentInfoPageParser = studentInfoPageParser;
this.trainingPlanPageParser = trainingPlanPageParser;
this.creditStatusParser = creditStatusParser;
this.examDelayParser = examDelayParser;
}
public List<Course> parseCourseTable(String data) throws ParseException {
return courseTableParser.parse(data);
}
public List<Score> parseScore(String data) throws ParseException {
return scoreParser.parse(data);
}
public StudentInfo parseStudentInfo(String data) throws ParseException {
return studentInfoPageParser.parse(data);
}
public String parseTrainingPlan(String data) throws ParseException {
return trainingPlanPageParser.parse(data);
}
public String parseCreditStatus(String data) throws ParseException {
return creditStatusParser.parse(data);
}
public List<ExamDelayApplication> parseExamDelayApplications(String data) throws ParseException {
return examDelayParser.parse(data);
}
}

@ -1,62 +0,0 @@
package cn.wustlinghang.wusthelper.internal.physics.services;
import cn.wustlinghang.mywust.core.request.service.undergraduate.*;
import cn.wustlinghang.mywust.exception.ApiException;
import jakarta.enterprise.context.ApplicationScoped;
import java.io.IOException;
@ApplicationScoped
public class RequestAgentService {
private final UndergradCourseTableApiService courseTableApiService;
private final UndergradScoreApiService scoreApiService;
private final UndergradStudentInfoApiService studentInfoApiService;
private final UndergradTrainingPlanApiService trainingPlanApiService;
private final UndergradCreditStatusApiService creditStatusApiService;
private final UndergradExamDelayApiService examDelayApiService;
public RequestAgentService(UndergradCourseTableApiService courseTableApiService,
UndergradScoreApiService scoreApiService,
UndergradStudentInfoApiService studentInfoApiService,
UndergradTrainingPlanApiService trainingPlanApiService,
UndergradCreditStatusApiService creditStatusApiService,
UndergradExamDelayApiService examDelayApiService) {
this.courseTableApiService = courseTableApiService;
this.scoreApiService = scoreApiService;
this.studentInfoApiService = studentInfoApiService;
this.trainingPlanApiService = trainingPlanApiService;
this.creditStatusApiService = creditStatusApiService;
this.examDelayApiService = examDelayApiService;
}
public String getStudentInfoPage(String cookie) throws IOException, ApiException {
return studentInfoApiService.getPage(cookie);
}
public String getCourseTable(String cookie, String term) throws IOException, ApiException {
return courseTableApiService.getPage(term, cookie);
}
public String getScore(String cookie) throws IOException, ApiException {
return scoreApiService.getPage(cookie);
}
public String getTrainingPlan(String cookie) throws IOException, ApiException {
return trainingPlanApiService.getPage(cookie);
}
public String getCreditStatus(String cookie) throws IOException, ApiException {
return creditStatusApiService.getPage(cookie, null, false);
}
public UndergradExamDelayApiService.ExamActivity[] getExamActivities(String cookie, String term)
throws IOException, ApiException {
return examDelayApiService.getActivities(term, cookie);
}
public String getExamDelayApplications(String cookie, String term, String activityId)
throws IOException, ApiException {
return examDelayApiService.getPage(term, activityId, cookie);
}
}

@ -0,0 +1,16 @@
package cn.wustlinghang.wusthelper.internal.undergrad;
import io.quarkus.runtime.Startup;
import jakarta.annotation.PostConstruct;
import jakarta.inject.Singleton;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Startup
@Singleton
public class Main {
@PostConstruct
public void run() {
log.info("Undergrad service started.");
}
}

@ -1,7 +1,7 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.json;
package cn.wustlinghang.wusthelper.internal.undergrad.api.json;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.wusthelper.internal.graduate.services.LoginService;
import cn.wustlinghang.wusthelper.internal.undergrad.services.LoginService;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
@ -20,13 +20,13 @@ public class CookieApi {
@GET
@Path("/")
public String login(@QueryParam("username") @NotNull String username,
@QueryParam("password") @NotNull String password) throws IOException, ApiException {
@QueryParam("password") @NotNull String password) throws RpcException {
return loginService.login(username, password, false);
}
@GET
@Path("/verify")
public Boolean verify(@QueryParam("cookie") @NotNull String cookie) throws IOException {
public Boolean verify(@QueryParam("cookie") @NotNull String cookie) throws RpcException {
return loginService.verify(cookie);
}
}

@ -0,0 +1,52 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.json;
import cn.wustlinghang.mywust.data.global.Course;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.internal.undergrad.services.ParseService;
import cn.wustlinghang.wusthelper.internal.undergrad.services.RequestAgentService;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
import java.util.List;
@Path("/course_table")
@ApplicationScoped
public class CourseTableApi {
private final RequestAgentService agentService;
private final ParseService parseService;
public CourseTableApi(RequestAgentService agentService,
ParseService parseService) {
this.agentService = agentService;
this.parseService = parseService;
}
@GET
@Path("/")
public List<Course> get(@QueryParam("cookie") @NotNull String cookie,
@QueryParam("term") String term)
throws RpcException {
return this.parse(this.agent(cookie, term));
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie,
@QueryParam("term") String term)
throws RpcException {
return agentService.getCourseTable(cookie, term);
}
@POST
@Path("/parse")
public List<Course> parse(String html) throws RpcException {
return parseService.parseCourseTable(html);
}
}

@ -0,0 +1,49 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.json;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.internal.undergrad.services.ParseService;
import cn.wustlinghang.wusthelper.internal.undergrad.services.RequestAgentService;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
@Path("/credit_status")
@ApplicationScoped
public class CreditStatusApi {
private final RequestAgentService agentService;
private final ParseService parseService;
public CreditStatusApi(RequestAgentService agentService,
ParseService parseService) {
this.agentService = agentService;
this.parseService = parseService;
}
@GET
@Path("/")
public String get(@QueryParam("cookie") @NotNull String cookie)
throws RpcException {
String html = this.agent(cookie);
return this.parse(html);
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie)
throws RpcException {
return agentService.getCreditStatus(cookie);
}
@POST
@Path("/parse")
public String parse(String html) throws RpcException {
return parseService.parseCreditStatus(html);
}
}

@ -0,0 +1,48 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.json;
import cn.wustlinghang.mywust.core.request.service.undergraduate.UndergradExamDelayApiService;
import cn.wustlinghang.mywust.data.global.Score;
import cn.wustlinghang.wusthelper.internal.undergrad.services.RequestAgentService;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.util.List;
@Path("/exam_activities")
@ApplicationScoped
public class ExamActivitiesApi {
private final RequestAgentService agentService;
public ExamActivitiesApi(RequestAgentService agentService) {
this.agentService = agentService;
}
@GET
@Path("/")
public UndergradExamDelayApiService.ExamActivity[] get(
@QueryParam("cookie") @NotNull String cookie,
@QueryParam("term") @NotNull String term)
throws RpcException {
return this.agent(cookie, term);
}
@GET
@Path("/agent")
public UndergradExamDelayApiService.ExamActivity[] agent(
@QueryParam("cookie") @NotNull String cookie,
@QueryParam("term") @NotNull String term)
throws RpcException {
return agentService.getExamActivities(cookie, term);
}
@POST
@Path("/parse")
public List<Score> parse(String html) throws RpcException {
throw RpcException.ApiNotImplement();
}
}

@ -0,0 +1,52 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.json;
import cn.wustlinghang.mywust.data.undergrad.ExamDelayApplication;
import cn.wustlinghang.wusthelper.internal.undergrad.services.ParseService;
import cn.wustlinghang.wusthelper.internal.undergrad.services.RequestAgentService;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.util.List;
@Path("/exam_delay_application")
@ApplicationScoped
public class ExamDelayApplicationApi {
private final RequestAgentService agentService;
private final ParseService parseService;
public ExamDelayApplicationApi(RequestAgentService agentService,
ParseService parseService) {
this.agentService = agentService;
this.parseService = parseService;
}
@GET
@Path("/")
public List<ExamDelayApplication> get(
@QueryParam("cookie") @NotNull String cookie,
@QueryParam("term") @NotNull String term,
@QueryParam("activity_id") @NotNull String activityId)
throws RpcException {
return this.parse(this.agent(cookie, term, activityId));
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie,
@QueryParam("term") @NotNull String term,
@QueryParam("activity_id") @NotNull String activityId)
throws RpcException {
return agentService.getExamDelayApplications(cookie, term, activityId);
}
@POST
@Path("/parse")
public List<ExamDelayApplication> parse(String html) throws RpcException {
return parseService.parseExamDelayApplications(html);
}
}

@ -0,0 +1,50 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.json;
import cn.wustlinghang.mywust.data.global.Score;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.internal.undergrad.services.ParseService;
import cn.wustlinghang.wusthelper.internal.undergrad.services.RequestAgentService;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
import java.util.List;
@Path("/score")
@ApplicationScoped
public class ScoreApi {
private final RequestAgentService agentService;
private final ParseService parseService;
public ScoreApi(RequestAgentService agentService,
ParseService parseService) {
this.agentService = agentService;
this.parseService = parseService;
}
@GET
@Path("/")
public List<Score> get(@QueryParam("cookie") @NotNull String cookie)
throws RpcException {
return this.parse(this.agent(cookie));
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie)
throws RpcException {
return agentService.getScore(cookie);
}
@POST
@Path("/parse")
public List<Score> parse(String html) throws RpcException {
return parseService.parseScore(html);
}
}

@ -0,0 +1,50 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.json;
import cn.wustlinghang.mywust.data.global.StudentInfo;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.internal.undergrad.exception.UndergradRpcException;
import cn.wustlinghang.wusthelper.internal.undergrad.services.ParseService;
import cn.wustlinghang.wusthelper.internal.undergrad.services.RequestAgentService;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
@Path("/student_info")
@ApplicationScoped
public class StudentInfoApi {
private final RequestAgentService agentService;
private final ParseService parseService;
public StudentInfoApi(RequestAgentService agentService,
ParseService parseService) {
this.agentService = agentService;
this.parseService = parseService;
}
@GET
@Path("/")
public StudentInfo get(@QueryParam("cookie") @NotNull String cookie)
throws RpcException {
return this.parse(this.agent(cookie));
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie)
throws RpcException {
return agentService.getStudentInfoPage(cookie);
}
@POST
@Path("/parse")
public StudentInfo parse(String html) throws RpcException {
return parseService.parseStudentInfo(html);
}
}

@ -0,0 +1,48 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.json;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.internal.undergrad.services.ParseService;
import cn.wustlinghang.wusthelper.internal.undergrad.services.RequestAgentService;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
@Path("/training_plan")
@ApplicationScoped
public class TrainingPlanApi {
private final RequestAgentService agentService;
private final ParseService parseService;
public TrainingPlanApi(RequestAgentService agentService,
ParseService parseService) {
this.agentService = agentService;
this.parseService = parseService;
}
@GET
@Path("/")
public String get(@QueryParam("cookie") @NotNull String cookie)
throws RpcException {
return this.parse(this.agent(cookie));
}
@GET
@Path("/agent")
public String agent(@QueryParam("cookie") @NotNull String cookie)
throws RpcException {
return agentService.getTrainingPlan(cookie);
}
@POST
@Path("/parse")
public String parse(String html) throws RpcException {
return parseService.parseTrainingPlan(html);
}
}

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.physics.api.json.handler;
package cn.wustlinghang.wusthelper.internal.undergrad.api.json.handler;
import cn.wustlinghang.wusthelper.rpc.response.ResponseCode;
import cn.wustlinghang.wusthelper.rpc.response.RpcResponse;
@ -7,7 +7,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
public abstract class ExceptionHandlerBase {
public abstract class BaseExceptionHandler {
public static final String EXCEPTION_HEADER_KEY = "X-exception-handler";
private static final ObjectMapper objectMapper = new ObjectMapper();
@ -17,6 +17,14 @@ public abstract class ExceptionHandlerBase {
}
public Response toResponse(int code, String msg, String handlerName) {
return toResponse(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), code, msg, handlerName);
}
public Response toResponse(int status, int code, String msg, String handlerName) {
return toResponse(Response.Status.fromStatusCode(status), code, msg, handlerName);
}
public Response toResponse(Response.Status status, int code, String msg, String handlerName) {
Object response;
try {
response = objectMapper.writeValueAsString(RpcResponse.error(code, msg));
@ -24,7 +32,7 @@ public abstract class ExceptionHandlerBase {
response = RpcResponse.error(ResponseCode.SERVER_INTERNAL_ERROR);
}
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
return Response.status(status)
.entity(response)
.header(EXCEPTION_HEADER_KEY, handlerName)
.type(MediaType.APPLICATION_JSON)

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.json.handler;
package cn.wustlinghang.wusthelper.internal.undergrad.api.json.handler;
import cn.wustlinghang.wusthelper.rpc.response.ResponseCode;
import jakarta.ws.rs.core.Response;
@ -8,7 +8,7 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
@Provider
public class DefaultExceptionHandler extends ExceptionHandlerBase implements ExceptionMapper<Exception> {
public class DefaultExceptionHandler extends BaseExceptionHandler implements ExceptionMapper<Exception> {
@Override
public Response toResponse(Exception e) {
log.error("未知异常:", e);

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.library.api.json.handler;
package cn.wustlinghang.wusthelper.internal.undergrad.api.json.handler;
import cn.wustlinghang.wusthelper.rpc.response.ResponseCode;
import jakarta.ws.rs.core.Response;
@ -10,7 +10,7 @@ import java.io.IOException;
@Slf4j
@Provider
public class IOExceptionHandler extends ExceptionHandlerBase implements ExceptionMapper<IOException> {
public class IOExceptionHandler extends BaseExceptionHandler implements ExceptionMapper<IOException> {
@Override
public Response toResponse(IOException e) {
log.error("IO异常:", e);

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.json.handler;
package cn.wustlinghang.wusthelper.internal.undergrad.api.json.handler;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.rpc.response.ResponseCode;
@ -9,7 +9,7 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
@Provider
public class ParseExceptionHandler extends ExceptionHandlerBase implements ExceptionMapper<ParseException> {
public class ParseExceptionHandler extends BaseExceptionHandler implements ExceptionMapper<ParseException> {
@Override
public Response toResponse(ParseException e) {
log.error("解析异常:", e);

@ -0,0 +1,17 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.json.handler;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
@Provider
public class RpcExceptionHandler extends BaseExceptionHandler implements ExceptionMapper<RpcException> {
@Override
public Response toResponse(RpcException e) {
return super.toResponse(
e.getCode(),
e.toString(),
"RpcExceptionHandler");
}
}

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.physics.api.json.handler;
package cn.wustlinghang.wusthelper.internal.undergrad.api.json.handler;
import cn.wustlinghang.wusthelper.rpc.response.ResponseCode;
import jakarta.validation.ValidationException;
@ -9,7 +9,7 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
@Provider
public class ValidationExceptionHandler extends ExceptionHandlerBase
public class ValidationExceptionHandler extends BaseExceptionHandler
implements ExceptionMapper<ValidationException> {
@Override
public Response toResponse(ValidationException e) {

@ -0,0 +1,26 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.json.handler;
import cn.wustlinghang.wusthelper.internal.undergrad.exception.UndergradRpcException;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
@Provider
public class WebApplicationExceptionHandler extends BaseExceptionHandler implements ExceptionMapper<WebApplicationException> {
@Override
public Response toResponse(WebApplicationException e) {
return super.toResponse(
e.getResponse().getStatus(),
RpcException.toIntCode(
UndergradRpcException.UNDERGRAD_MODULE,
UndergradRpcException.SubModuleCode.COMMON.ordinal(),
UndergradRpcException.TypeCode.OTHER_EXCEPTION.ordinal() * 100
+ UndergradRpcException.ErrorCode.REQUEST_INVALID.ordinal()
),
e.getMessage(),
"WebApplicationExceptionHandler"
);
}
}

@ -1,6 +1,6 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.json.interceptor;
package cn.wustlinghang.wusthelper.internal.undergrad.api.json.interceptor;
import cn.wustlinghang.wusthelper.internal.graduate.api.json.handler.ExceptionHandlerBase;
import cn.wustlinghang.wusthelper.internal.undergrad.api.json.handler.BaseExceptionHandler;
import cn.wustlinghang.wusthelper.rpc.response.RpcResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.ws.rs.WebApplicationException;
@ -22,7 +22,7 @@ public class ResponseWrapperInterceptor implements WriterInterceptor {
@Override
public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
boolean hasException = context.getHeaders().get(ExceptionHandlerBase.EXCEPTION_HEADER_KEY) != null;
boolean hasException = context.getHeaders().get(BaseExceptionHandler.EXCEPTION_HEADER_KEY) != null;
if (!hasException) {
Object data = context.getEntity();
RpcResponse<Object> wrappedResponse = RpcResponse.success(data);

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.library.bean;
package cn.wustlinghang.wusthelper.internal.undergrad.bean;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.enterprise.context.ApplicationScoped;

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.library.bean;
package cn.wustlinghang.wusthelper.internal.undergrad.bean;
import cn.wustlinghang.mywust.core.parser.undergraduate.*;
import jakarta.enterprise.context.ApplicationScoped;

@ -1,4 +1,4 @@
package cn.wustlinghang.wusthelper.internal.graduate.bean;
package cn.wustlinghang.wusthelper.internal.undergrad.bean;
import cn.wustlinghang.mywust.core.request.service.auth.UndergraduateLogin;
import cn.wustlinghang.mywust.core.request.service.undergraduate.*;

@ -0,0 +1,73 @@
package cn.wustlinghang.wusthelper.internal.undergrad.exception;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import java.util.StringJoiner;
public class UndergradRpcException extends RpcException {
public static final int UNDERGRAD_MODULE = 1;
public UndergradRpcException(TypeCode typeCode,
SubModuleCode subModuleCode,
ErrorCode errorCode) {
super(UNDERGRAD_MODULE,
typeCode.ordinal(),
subModuleCode.ordinal() * 100 + errorCode.ordinal(),
new StringJoiner("-")
.add("UNDERGRAD")
.add(typeCode.name())
.add(subModuleCode.name())
.add(errorCode.name())
.toString()
);
}
/**
* 异常类型编码
*/
public enum TypeCode {
// 网络异常类型
NETWORK_EXCEPTION,
// 参数异常类型
PARAM_EXCEPTION,
// 权限认证异常类型
AUTH_EXCEPTION,
// 网页解析异常类型
PARSE_EXCEPTION,
// 其他的异常类型
OTHER_EXCEPTION
}
/**
* 子模块编码
*/
public enum SubModuleCode {
COMMON, AUTH, COURSE_TABLE, CREDIT_STATUS, SCORE,
STUDENT_INFO, TRAINING_PLAN, EXAM_ACTIVITIES, EXAM_DELAY_APPLICATION
}
/**
* 具体错误编码
*/
public enum ErrorCode {
REQUEST_INVALID,
PARAM_INVALID,
COOKIE_INVALID,
NETWORK_ERROR,
PARSE_ERROR,
// 需要评教
NEED_EVALUATE,
AUTH_PASSWORD_WRONG,
// 用户不存在
AUTH_USER_NOT_EXISTS,
// 封号
AUTH_USER_BANNED,
// 用户账号禁用
AUTH_USER_DISABLED,
// 用户账号需要更改
AUTH_NEED_CHANGE_PASSWORD,
AUTH_UNKNOWN_ERROR
}
}

@ -0,0 +1,78 @@
package cn.wustlinghang.wusthelper.internal.undergrad.services;
import cn.wustlinghang.mywust.core.request.service.auth.UndergraduateLogin;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.network.RequestClientOption;
import cn.wustlinghang.wusthelper.internal.undergrad.exception.UndergradRpcException;
import jakarta.enterprise.context.ApplicationScoped;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
@Slf4j
@ApplicationScoped
public class LoginService {
private final RequestClientOption option;
private final UndergraduateLogin undergraduateLogin;
public LoginService(RequestClientOption option,
UndergraduateLogin undergraduateLogin) {
this.option = option;
this.undergraduateLogin = undergraduateLogin;
}
public String login(String username, String password, boolean legacy) throws UndergradRpcException {
try {
if (legacy) {
return undergraduateLogin.getLoginCookieLegacy(username, password, option);
} else {
return undergraduateLogin.getLoginCookie(username, password, option);
}
} catch (ApiException e) {
throw wrapApiException(e);
} catch (IOException e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
UndergradRpcException.SubModuleCode.AUTH,
UndergradRpcException.ErrorCode.NETWORK_ERROR
);
}
}
public boolean verify(String cookie) throws UndergradRpcException {
try {
return !undergraduateLogin.checkCookiesFail(cookie);
} catch (IOException e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
UndergradRpcException.SubModuleCode.AUTH,
UndergradRpcException.ErrorCode.NETWORK_ERROR
);
}
}
private UndergradRpcException wrapApiException(ApiException e) {
UndergradRpcException.ErrorCode errorCode = switch (e.getCode()) {
case NETWORK_EXCEPTION -> UndergradRpcException.ErrorCode.NETWORK_ERROR;
case UNI_LOGIN_PASSWORD_WRONG -> UndergradRpcException.ErrorCode.AUTH_PASSWORD_WRONG;
case UNI_LOGIN_USER_NOT_EXISTS -> UndergradRpcException.ErrorCode.AUTH_USER_NOT_EXISTS;
case UNI_LOGIN_USER_BANNED -> UndergradRpcException.ErrorCode.AUTH_USER_BANNED;
case UNI_LOGIN_USER_DISABLED -> UndergradRpcException.ErrorCode.AUTH_USER_DISABLED;
case UNI_LOGIN_NEED_CHANGE_PASSWORD -> UndergradRpcException.ErrorCode.AUTH_NEED_CHANGE_PASSWORD;
case UNI_LOGIN_USER_NOT_ONLY -> UndergradRpcException.ErrorCode.AUTH_UNKNOWN_ERROR;
case UNI_LOGIN_NO_REGISTER -> UndergradRpcException.ErrorCode.AUTH_UNKNOWN_ERROR;
case UNI_LOGIN_NEED_TFA -> UndergradRpcException.ErrorCode.AUTH_UNKNOWN_ERROR;
default -> {
log.error("本科生:登录代理请求异常,异常未处理");
log.error("异常:", e);
yield UndergradRpcException.ErrorCode.AUTH_UNKNOWN_ERROR;
}
};
return new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
UndergradRpcException.SubModuleCode.AUTH,
errorCode
);
}
}

@ -0,0 +1,132 @@
package cn.wustlinghang.wusthelper.internal.undergrad.services;
import cn.wustlinghang.mywust.core.parser.undergraduate.*;
import cn.wustlinghang.mywust.data.global.Course;
import cn.wustlinghang.mywust.data.global.Score;
import cn.wustlinghang.mywust.data.global.StudentInfo;
import cn.wustlinghang.mywust.data.undergrad.ExamDelayApplication;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.internal.undergrad.exception.UndergradRpcException;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.enterprise.context.ApplicationScoped;
import java.util.List;
@ApplicationScoped
public class ParseService {
private final UndergradCourseTableParser courseTableParser;
private final UndergradScoreParser scoreParser;
private final UndergradStudentInfoPageParser studentInfoPageParser;
private final UndergradTrainingPlanPageParser trainingPlanPageParser;
private final UndergradCreditStatusParser creditStatusParser;
private final UndergradExamDelayParser examDelayParser;
public ParseService(UndergradCourseTableParser courseTableParser,
UndergradScoreParser scoreParser,
UndergradStudentInfoPageParser studentInfoPageParser,
UndergradTrainingPlanPageParser trainingPlanPageParser,
UndergradCreditStatusParser creditStatusParser,
UndergradExamDelayParser examDelayParser) {
this.courseTableParser = courseTableParser;
this.scoreParser = scoreParser;
this.studentInfoPageParser = studentInfoPageParser;
this.trainingPlanPageParser = trainingPlanPageParser;
this.creditStatusParser = creditStatusParser;
this.examDelayParser = examDelayParser;
}
public List<Course> parseCourseTable(String data) throws UndergradRpcException {
try {
if (data.contains("评教")) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.PARSE_EXCEPTION,
UndergradRpcException.SubModuleCode.COURSE_TABLE,
UndergradRpcException.ErrorCode.NEED_EVALUATE
);
}
return courseTableParser.parse(data);
} catch (UndergradRpcException e) {
throw e;
} catch (Exception e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.PARSE_EXCEPTION,
UndergradRpcException.SubModuleCode.COURSE_TABLE,
UndergradRpcException.ErrorCode.PARSE_ERROR
);
}
}
public List<Score> parseScore(String data) throws RpcException {
try {
if (data.contains("评教")) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.PARSE_EXCEPTION,
UndergradRpcException.SubModuleCode.SCORE,
UndergradRpcException.ErrorCode.NEED_EVALUATE
);
}
return scoreParser.parse(data);
} catch (UndergradRpcException e) {
throw e;
} catch (Exception e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.PARSE_EXCEPTION,
UndergradRpcException.SubModuleCode.SCORE,
UndergradRpcException.ErrorCode.PARSE_ERROR
);
}
}
public StudentInfo parseStudentInfo(String data) throws RpcException {
try {
return studentInfoPageParser.parse(data);
} catch (Exception e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.PARSE_EXCEPTION,
UndergradRpcException.SubModuleCode.STUDENT_INFO,
UndergradRpcException.ErrorCode.PARSE_ERROR
);
}
}
public String parseTrainingPlan(String data) throws RpcException {
try {
return trainingPlanPageParser.parse(data);
} catch (Exception e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.PARSE_EXCEPTION,
UndergradRpcException.SubModuleCode.TRAINING_PLAN,
UndergradRpcException.ErrorCode.PARSE_ERROR
);
}
}
public String parseCreditStatus(String data) throws RpcException {
try {
return creditStatusParser.parse(data);
} catch (Exception e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.PARSE_EXCEPTION,
UndergradRpcException.SubModuleCode.CREDIT_STATUS,
UndergradRpcException.ErrorCode.PARSE_ERROR
);
}
}
public List<ExamDelayApplication> parseExamDelayApplications(String data) throws RpcException {
try {
return examDelayParser.parse(data);
} catch (Exception e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.PARSE_EXCEPTION,
UndergradRpcException.SubModuleCode.EXAM_DELAY_APPLICATION,
UndergradRpcException.ErrorCode.PARSE_ERROR
);
}
}
}

@ -0,0 +1,166 @@
package cn.wustlinghang.wusthelper.internal.undergrad.services;
import cn.wustlinghang.mywust.core.request.service.undergraduate.*;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.network.RequestClientOption;
import cn.wustlinghang.wusthelper.internal.undergrad.exception.UndergradRpcException;
import cn.wustlinghang.wusthelper.rpc.exception.RpcException;
import jakarta.enterprise.context.ApplicationScoped;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
@Slf4j
@ApplicationScoped
public class RequestAgentService {
private final UndergradCourseTableApiService courseTableApiService;
private final UndergradScoreApiService scoreApiService;
private final UndergradStudentInfoApiService studentInfoApiService;
private final UndergradTrainingPlanApiService trainingPlanApiService;
private final UndergradCreditStatusApiService creditStatusApiService;
private final UndergradExamDelayApiService examDelayApiService;
private final RequestClientOption requestClientOption;
public RequestAgentService(UndergradCourseTableApiService courseTableApiService,
UndergradScoreApiService scoreApiService,
UndergradStudentInfoApiService studentInfoApiService,
UndergradTrainingPlanApiService trainingPlanApiService,
UndergradCreditStatusApiService creditStatusApiService,
UndergradExamDelayApiService examDelayApiService,
RequestClientOption requestClientOption) {
this.courseTableApiService = courseTableApiService;
this.scoreApiService = scoreApiService;
this.studentInfoApiService = studentInfoApiService;
this.trainingPlanApiService = trainingPlanApiService;
this.creditStatusApiService = creditStatusApiService;
this.examDelayApiService = examDelayApiService;
this.requestClientOption = requestClientOption;
}
public String getStudentInfoPage(String cookie) throws RpcException {
try {
return studentInfoApiService.getPage(cookie);
} catch (ApiException e) {
throw wrapApiException(e, UndergradRpcException.SubModuleCode.STUDENT_INFO);
} catch (IOException e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
UndergradRpcException.SubModuleCode.STUDENT_INFO,
UndergradRpcException.ErrorCode.NETWORK_ERROR
);
}
}
public String getCourseTable(String cookie, String term) throws RpcException {
try {
return courseTableApiService.getPage(term, cookie);
} catch (ApiException e) {
throw wrapApiException(e, UndergradRpcException.SubModuleCode.COURSE_TABLE);
} catch (IOException e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
UndergradRpcException.SubModuleCode.COURSE_TABLE,
UndergradRpcException.ErrorCode.NETWORK_ERROR
);
}
}
public String getScore(String cookie) throws RpcException {
try {
return scoreApiService.getPage(cookie);
} catch (ApiException e) {
throw wrapApiException(e, UndergradRpcException.SubModuleCode.SCORE);
} catch (IOException e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
UndergradRpcException.SubModuleCode.SCORE,
UndergradRpcException.ErrorCode.NETWORK_ERROR
);
}
}
public String getTrainingPlan(String cookie) throws RpcException {
try {
return trainingPlanApiService.getPage(cookie);
} catch (ApiException e) {
throw wrapApiException(e, UndergradRpcException.SubModuleCode.TRAINING_PLAN);
} catch (IOException e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
UndergradRpcException.SubModuleCode.TRAINING_PLAN,
UndergradRpcException.ErrorCode.NETWORK_ERROR
);
}
}
public String getCreditStatus(String cookie) throws RpcException {
try {
return creditStatusApiService.getPage(cookie, requestClientOption, false);
} catch (ApiException e) {
throw wrapApiException(e, UndergradRpcException.SubModuleCode.CREDIT_STATUS);
} catch (IOException e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
UndergradRpcException.SubModuleCode.CREDIT_STATUS,
UndergradRpcException.ErrorCode.NETWORK_ERROR
);
}
}
public UndergradExamDelayApiService.ExamActivity[] getExamActivities(String cookie, String term)
throws RpcException {
try {
return examDelayApiService.getActivities(term, cookie);
} catch (ApiException e) {
throw wrapApiException(e, UndergradRpcException.SubModuleCode.EXAM_ACTIVITIES);
} catch (IOException e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
UndergradRpcException.SubModuleCode.EXAM_ACTIVITIES,
UndergradRpcException.ErrorCode.NETWORK_ERROR
);
}
}
public String getExamDelayApplications(String cookie, String term, String activityId)
throws RpcException {
try {
return examDelayApiService.getPage(term, activityId, cookie);
} catch (ApiException e) {
throw wrapApiException(e, UndergradRpcException.SubModuleCode.EXAM_DELAY_APPLICATION);
} catch (IOException e) {
throw new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
UndergradRpcException.SubModuleCode.EXAM_DELAY_APPLICATION,
UndergradRpcException.ErrorCode.NETWORK_ERROR
);
}
}
private UndergradRpcException wrapApiException(ApiException e, UndergradRpcException.SubModuleCode subModuleCode) {
return switch (e.getCode()) {
case NETWORK_EXCEPTION -> new UndergradRpcException(
UndergradRpcException.TypeCode.NETWORK_EXCEPTION,
subModuleCode,
UndergradRpcException.ErrorCode.NETWORK_ERROR
);
case COOKIE_INVALID -> new UndergradRpcException(
UndergradRpcException.TypeCode.AUTH_EXCEPTION,
subModuleCode,
UndergradRpcException.ErrorCode.COOKIE_INVALID
);
default -> {
log.error("本科生:{}代理请求异常,异常未处理", subModuleCode.name());
log.error("异常:", e);
yield new UndergradRpcException(
UndergradRpcException.TypeCode.AUTH_EXCEPTION,
subModuleCode,
UndergradRpcException.ErrorCode.COOKIE_INVALID
);
}
};
}
}

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

Loading…
Cancel
Save