lensfrex 1 year ago
parent 73d6058e18
commit 731f3b70ca
Signed by: lensfrex
GPG Key ID: 0F69A0A2FBEE98A0
  1. 4
      common/src/main/java/cn/wustlinghang/wusthelper/rpc/exception/CommonRpcException.java
  2. 59
      sub-services/graduate/.flattened-pom.xml
  3. 132
      sub-services/graduate/pom.xml
  4. 54
      sub-services/graduate/src/main/docker/Dockerfile.jvm
  5. 51
      sub-services/graduate/src/main/docker/Dockerfile.legacy-jar
  6. 27
      sub-services/graduate/src/main/docker/Dockerfile.native
  7. 23
      sub-services/graduate/src/main/docker/Dockerfile.native-micro
  8. 7
      sub-services/graduate/src/main/java/cn/wustlinghang/Main.java
  9. 32
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/json/CookieApi.java
  10. 52
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/json/CourseTableApi.java
  11. 54
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/json/CreditStatusApi.java
  12. 50
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/json/ScoreApi.java
  13. 47
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/json/StudentInfoApi.java
  14. 47
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/json/TrainingPlanApi.java
  15. 14
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/json/handler/ApiExceptionHandler.java
  16. 21
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/json/handler/DefaultExceptionHandler.java
  17. 33
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/json/handler/ExceptionHandlerBase.java
  18. 23
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/json/handler/IOExceptionHandler.java
  19. 22
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/json/handler/ParseExceptionHandler.java
  20. 22
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/json/handler/ValidationExceptionHandler.java
  21. 36
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/api/json/interceptor/ResponseWrapperInterceptor.java
  22. 12
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/bean/JacksonBean.java
  23. 36
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/bean/MywustParserBeans.java
  24. 63
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/bean/MywustRequestAgentBeans.java
  25. 32
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/services/LoginService.java
  26. 60
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/services/ParseService.java
  27. 62
      sub-services/graduate/src/main/java/cn/wustlinghang/wusthelper/internal/graduate/services/RequestAgentService.java
  28. 152
      sub-services/graduate/src/main/resources/META-INF/resources/index.html
  29. 11
      sub-services/graduate/src/main/resources/application.properties
  30. 59
      sub-services/library/.flattened-pom.xml
  31. 132
      sub-services/library/pom.xml
  32. 54
      sub-services/library/src/main/docker/Dockerfile.jvm
  33. 51
      sub-services/library/src/main/docker/Dockerfile.legacy-jar
  34. 27
      sub-services/library/src/main/docker/Dockerfile.native
  35. 23
      sub-services/library/src/main/docker/Dockerfile.native-micro
  36. 7
      sub-services/library/src/main/java/cn/wustlinghang/Main.java
  37. 32
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/json/CookieApi.java
  38. 52
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/json/CourseTableApi.java
  39. 54
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/json/CreditStatusApi.java
  40. 50
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/json/ScoreApi.java
  41. 47
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/json/StudentInfoApi.java
  42. 47
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/json/TrainingPlanApi.java
  43. 14
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/json/handler/ApiExceptionHandler.java
  44. 21
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/json/handler/DefaultExceptionHandler.java
  45. 33
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/json/handler/ExceptionHandlerBase.java
  46. 23
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/json/handler/IOExceptionHandler.java
  47. 22
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/json/handler/ParseExceptionHandler.java
  48. 22
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/json/handler/ValidationExceptionHandler.java
  49. 36
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/api/json/interceptor/ResponseWrapperInterceptor.java
  50. 12
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/bean/JacksonBean.java
  51. 36
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/bean/MywustParserBeans.java
  52. 63
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/bean/MywustRequestAgentBeans.java
  53. 32
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/services/LoginService.java
  54. 60
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/services/ParseService.java
  55. 62
      sub-services/library/src/main/java/cn/wustlinghang/wusthelper/internal/library/services/RequestAgentService.java
  56. 152
      sub-services/library/src/main/resources/META-INF/resources/index.html
  57. 11
      sub-services/library/src/main/resources/application.properties
  58. 59
      sub-services/physics/.flattened-pom.xml
  59. 132
      sub-services/physics/pom.xml
  60. 54
      sub-services/physics/src/main/docker/Dockerfile.jvm
  61. 51
      sub-services/physics/src/main/docker/Dockerfile.legacy-jar
  62. 27
      sub-services/physics/src/main/docker/Dockerfile.native
  63. 23
      sub-services/physics/src/main/docker/Dockerfile.native-micro
  64. 7
      sub-services/physics/src/main/java/cn/wustlinghang/Main.java
  65. 32
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/json/CookieApi.java
  66. 52
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/json/CourseTableApi.java
  67. 54
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/json/CreditStatusApi.java
  68. 50
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/json/ScoreApi.java
  69. 47
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/json/StudentInfoApi.java
  70. 47
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/json/TrainingPlanApi.java
  71. 14
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/json/handler/ApiExceptionHandler.java
  72. 21
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/json/handler/DefaultExceptionHandler.java
  73. 33
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/json/handler/ExceptionHandlerBase.java
  74. 23
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/json/handler/IOExceptionHandler.java
  75. 22
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/json/handler/ParseExceptionHandler.java
  76. 22
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/json/handler/ValidationExceptionHandler.java
  77. 36
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/api/json/interceptor/ResponseWrapperInterceptor.java
  78. 12
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/bean/JacksonBean.java
  79. 36
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/bean/MywustParserBeans.java
  80. 63
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/bean/MywustRequestAgentBeans.java
  81. 32
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/services/LoginService.java
  82. 60
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/services/ParseService.java
  83. 62
      sub-services/physics/src/main/java/cn/wustlinghang/wusthelper/internal/physics/services/RequestAgentService.java
  84. 152
      sub-services/physics/src/main/resources/META-INF/resources/index.html
  85. 11
      sub-services/physics/src/main/resources/application.properties
  86. 5
      sub-services/undergrad/pom.xml
  87. 16
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/Main.java
  88. 35
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/CreditStatusApi.java
  89. 31
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/ScoreApi.java
  90. 32
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/TrainingPlanApi.java
  91. 1
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/handler/ApiExceptionHandler.java
  92. 1
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/api/json/handler/ValidationExceptionHandler.java
  93. 4
      sub-services/undergrad/src/main/java/cn/wustlinghang/wusthelper/internal/undergrad/exception/InternalException.java
  94. 5
      sub-services/undergrad/src/main/resources/application.properties

@ -0,0 +1,4 @@
package cn.wustlinghang.wusthelper.rpc.exception;
public class CommonRpcException extends RuntimeException {
}

@ -1,59 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.wustlinghang.wusthelper</groupId>
<artifactId>graduate</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>cn.wustlinghang</groupId>
<artifactId>mywust-core</artifactId>
<version>0.0.2-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>cn.wustlinghang</groupId>
<artifactId>mywust-network-okhttp</artifactId>
<version>0.0.2-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>cn.wustlinghang.wusthelper</groupId>
<artifactId>common</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>2.1.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.26</version>
<scope>provided</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>central</id>
<url>https://repo1.maven.org/maven2</url>
</repository>
<repository>
<snapshots>
<enabled>true</enabled>
</snapshots>
<id>github</id>
<url>https://maven.pkg.github.com/LingHangStudio/mywust</url>
</repository>
</repositories>
</project>

@ -10,11 +10,143 @@
</parent> </parent>
<artifactId>graduate</artifactId> <artifactId>graduate</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties> <properties>
<compiler-plugin.version>3.11.0</compiler-plugin.version>
<maven.compiler.release>17</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
<quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
<!-- 3.2.0.Final版本与flatten-maven-plugin插件同时使用会出现问题,现临时降至3.1.3 -->
<quarkus.platform.version>3.1.3.Final</quarkus.platform.version>
<skipITs>true</skipITs>
<surefire-plugin.version>3.0.0</surefire-plugin.version>
<maven.compiler.source>17</maven.compiler.source> <maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target> <maven.compiler.target>17</maven.compiler.target>
<maven.compiler.parameters>true</maven.compiler.parameters>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> </properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>${quarkus.platform.artifact-id}</artifactId>
<version>${quarkus.platform.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive-jackson</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus.platform.version}</version>
<extensions>true</extensions>
<configuration>
<systemProperties>
<file.encoding>UTF-8</file.encoding>
</systemProperties>
</configuration>
<executions>
<execution>
<goals>
<goal>build</goal>
<goal>generate-code</goal>
<goal>generate-code-tests</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler-plugin.version}</version>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<configuration>
<systemPropertyVariables>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<systemPropertyVariables>
<native.image.path>${project.build.directory}/${project.build.finalName}-runner
</native.image.path>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>native</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<properties>
<skipITs>false</skipITs>
<quarkus.package.type>native</quarkus.package.type>
</properties>
</profile>
</profiles>
</project> </project>

@ -0,0 +1,54 @@
####
# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
#
# Before building the container image run:
#
# ./mvnw package
#
# Then, build the image with:
#
# docker build -f src/main/docker/Dockerfile.jvm -t quarkus/getting-started-jvm .
#
# Then run the container using:
#
# docker run -i --rm -p 8080:8080 quarkus/getting-started-jvm
#
# If you want to include the debug port into your docker image
# you will have to expose the debug port (default 5005) like this : EXPOSE 8080 5050
#
# Then run the container using :
#
# docker run -i --rm -p 8080:8080 -p 5005:5005 -e JAVA_ENABLE_DEBUG="true" quarkus/getting-started-jvm
#
###
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.3
ARG JAVA_PACKAGE=java-11-openjdk-headless
ARG RUN_JAVA_VERSION=1.3.8
ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en'
# Install java and the run-java script
# Also set up permissions for user `1001`
RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \
&& microdnf update \
&& microdnf clean all \
&& mkdir /deployments \
&& chown 1001 /deployments \
&& chmod "g+rwX" /deployments \
&& chown 1001:root /deployments \
&& curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \
&& chown 1001 /deployments/run-java.sh \
&& chmod 540 /deployments/run-java.sh \
&& echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/lib/security/java.security
# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size.
ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
# We make four distinct layers so if there are application changes the library layers can be re-used
COPY --chown=1001 target/quarkus-app/lib/ /deployments/lib/
COPY --chown=1001 target/quarkus-app/*.jar /deployments/
COPY --chown=1001 target/quarkus-app/app/ /deployments/app/
COPY --chown=1001 target/quarkus-app/quarkus/ /deployments/quarkus/
EXPOSE 8080
USER 1001
ENTRYPOINT [ "/deployments/run-java.sh" ]

@ -0,0 +1,51 @@
####
# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
#
# Before building the container image run:
#
# ./mvnw package -Dquarkus.package.type=legacy-jar
#
# Then, build the image with:
#
# docker build -f src/main/docker/Dockerfile.legacy-jar -t quarkus/getting-started-legacy-jar .
#
# Then run the container using:
#
# docker run -i --rm -p 8080:8080 quarkus/getting-started-legacy-jar
#
# If you want to include the debug port into your docker image
# you will have to expose the debug port (default 5005) like this : EXPOSE 8080 5050
#
# Then run the container using :
#
# docker run -i --rm -p 8080:8080 -p 5005:5005 -e JAVA_ENABLE_DEBUG="true" quarkus/getting-started-legacy-jar
#
###
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.3
ARG JAVA_PACKAGE=java-11-openjdk-headless
ARG RUN_JAVA_VERSION=1.3.8
ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en'
# Install java and the run-java script
# Also set up permissions for user `1001`
RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \
&& microdnf update \
&& microdnf clean all \
&& mkdir /deployments \
&& chown 1001 /deployments \
&& chmod "g+rwX" /deployments \
&& chown 1001:root /deployments \
&& curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \
&& chown 1001 /deployments/run-java.sh \
&& chmod 540 /deployments/run-java.sh \
&& echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/lib/security/java.security
# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size.
ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
COPY target/lib/* /deployments/lib/
COPY target/*-runner.jar /deployments/app.jar
EXPOSE 8080
USER 1001
ENTRYPOINT [ "/deployments/run-java.sh" ]

@ -0,0 +1,27 @@
####
# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode
#
# Before building the container image run:
#
# ./mvnw package -Pnative
#
# Then, build the image with:
#
# docker build -f src/main/docker/Dockerfile.native -t quarkus/getting-started .
#
# Then run the container using:
#
# docker run -i --rm -p 8080:8080 quarkus/getting-started
#
###
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.3
WORKDIR /work/
RUN chown 1001 /work \
&& chmod "g+rwX" /work \
&& chown 1001:root /work
COPY --chown=1001:root target/*-runner /work/application
EXPOSE 8080
USER 1001
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]

@ -0,0 +1,23 @@
####
# This Dockerfile is used in order to build a distroless container that runs the Quarkus application in native (no JVM) mode
#
# Before building the container image run:
#
# ./mvnw package -Pnative
#
# Then, build the image with:
#
# docker build -f src/main/docker/Dockerfile.native-micro -t quarkus/getting-started .
#
# Then run the container using:
#
# docker run -i --rm -p 8080:8080 quarkus/getting-started
#
###
FROM quay.io/quarkus/quarkus-micro-image:1.0
COPY target/*-runner /application
EXPOSE 8080
USER 1001
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]

@ -1,7 +0,0 @@
package cn.wustlinghang;
public class Main {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}

@ -0,0 +1,32 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.json;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.wusthelper.internal.graduate.services.LoginService;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
@Path("/cookie")
public class CookieApi {
private final LoginService loginService;
public CookieApi(LoginService loginService) {
this.loginService = loginService;
}
@GET
@Path("/")
public String login(@QueryParam("username") @NotNull String username,
@QueryParam("password") @NotNull String password) throws IOException, ApiException {
return loginService.login(username, password, false);
}
@GET
@Path("/verify")
public Boolean verify(@QueryParam("cookie") @NotNull String cookie) throws IOException {
return loginService.verify(cookie);
}
}

@ -0,0 +1,52 @@
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);
}
}

@ -0,0 +1,54 @@
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);
}
}

@ -0,0 +1,50 @@
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);
}
}

@ -0,0 +1,47 @@
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);
}
}

@ -0,0 +1,47 @@
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);
}
}

@ -0,0 +1,14 @@
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");
}
}

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

@ -0,0 +1,33 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.json.handler;
import cn.wustlinghang.wusthelper.rpc.response.ResponseCode;
import cn.wustlinghang.wusthelper.rpc.response.RpcResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
public abstract class ExceptionHandlerBase {
public static final String EXCEPTION_HEADER_KEY = "X-exception-handler";
private static final ObjectMapper objectMapper = new ObjectMapper();
public Response toResponse(ResponseCode code, String msg, String handlerName) {
return toResponse(code.getCode(), msg, handlerName);
}
public Response toResponse(int code, String msg, String handlerName) {
Object response;
try {
response = objectMapper.writeValueAsString(RpcResponse.error(code, msg));
} catch (JsonProcessingException e) {
response = RpcResponse.error(ResponseCode.SERVER_INTERNAL_ERROR);
}
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity(response)
.header(EXCEPTION_HEADER_KEY, handlerName)
.type(MediaType.APPLICATION_JSON)
.build();
}
}

@ -0,0 +1,23 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.json.handler;
import cn.wustlinghang.wusthelper.rpc.response.ResponseCode;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
@Slf4j
@Provider
public class IOExceptionHandler extends ExceptionHandlerBase implements ExceptionMapper<IOException> {
@Override
public Response toResponse(IOException e) {
log.error("IO异常:", e);
return super.toResponse(
ResponseCode.SERVER_INTERNAL_ERROR,
e.toString(),
"IOExceptionHandler"
);
}
}

@ -0,0 +1,22 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.json.handler;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.rpc.response.ResponseCode;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Provider
public class ParseExceptionHandler extends ExceptionHandlerBase implements ExceptionMapper<ParseException> {
@Override
public Response toResponse(ParseException e) {
log.error("解析异常:", e);
return super.toResponse(
ResponseCode.SERVER_INTERNAL_ERROR,
e.toString(),
"ParseExceptionHandler"
);
}
}

@ -0,0 +1,22 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.json.handler;
import cn.wustlinghang.wusthelper.rpc.response.ResponseCode;
import jakarta.validation.ValidationException;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Provider
public class ValidationExceptionHandler extends ExceptionHandlerBase
implements ExceptionMapper<ValidationException> {
@Override
public Response toResponse(ValidationException e) {
return super.toResponse(
ResponseCode.PARAM_WRONG,
"参数错误:" + e.toString(),
"ValidationExceptionHandler"
);
}
}

@ -0,0 +1,36 @@
package cn.wustlinghang.wusthelper.internal.graduate.api.json.interceptor;
import cn.wustlinghang.wusthelper.internal.graduate.api.json.handler.ExceptionHandlerBase;
import cn.wustlinghang.wusthelper.rpc.response.RpcResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.ext.Provider;
import jakarta.ws.rs.ext.WriterInterceptor;
import jakarta.ws.rs.ext.WriterInterceptorContext;
import java.io.IOException;
@Provider
public class ResponseWrapperInterceptor implements WriterInterceptor {
private final ObjectMapper objectMapper;
public ResponseWrapperInterceptor(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
@Override
public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
boolean hasException = context.getHeaders().get(ExceptionHandlerBase.EXCEPTION_HEADER_KEY) != null;
if (!hasException) {
Object data = context.getEntity();
RpcResponse<Object> wrappedResponse = RpcResponse.success(data);
String json = objectMapper.writeValueAsString(wrappedResponse);
context.getHeaders().putSingle(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
context.setEntity(json);
}
context.proceed();
}
}

@ -0,0 +1,12 @@
package cn.wustlinghang.wusthelper.internal.graduate.bean;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Singleton;
public class JacksonBean {
@ApplicationScoped
public ObjectMapper objectMapper() {
return new ObjectMapper();
}
}

@ -0,0 +1,36 @@
package cn.wustlinghang.wusthelper.internal.graduate.bean;
import cn.wustlinghang.mywust.core.parser.undergraduate.*;
import jakarta.enterprise.context.ApplicationScoped;
public class MywustParserBeans {
@ApplicationScoped
public UndergradCourseTableParser undergradCourseTableParser() {
return new UndergradCourseTableParser();
}
@ApplicationScoped
public UndergradScoreParser undergradScoreParser() {
return new UndergradScoreParser();
}
@ApplicationScoped
public UndergradStudentInfoPageParser undergradStudentInfoPageParser() {
return new UndergradStudentInfoPageParser();
}
@ApplicationScoped
public UndergradTrainingPlanPageParser undergradTrainingPlanPageParser() {
return new UndergradTrainingPlanPageParser();
}
@ApplicationScoped
public UndergradCreditStatusParser undergradCreditStatusParser() {
return new UndergradCreditStatusParser();
}
@ApplicationScoped
public UndergradExamDelayParser undergradExamDelayParser() {
return new UndergradExamDelayParser();
}
}

@ -0,0 +1,63 @@
package cn.wustlinghang.wusthelper.internal.graduate.bean;
import cn.wustlinghang.mywust.core.request.service.auth.UndergraduateLogin;
import cn.wustlinghang.mywust.core.request.service.undergraduate.*;
import cn.wustlinghang.mywust.network.RequestClientOption;
import cn.wustlinghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.okhttp.SimpleOkhttpRequester;
import jakarta.inject.Singleton;
public class MywustRequestAgentBeans {
@Singleton
public RequestClientOption requestClientOption() {
RequestClientOption.Proxy proxy = RequestClientOption.Proxy.builder()
.address("127.0.0.1")
.port(8080)
.build();
RequestClientOption option = new RequestClientOption();
// option.setProxy(proxy);
return option;
}
@Singleton
public Requester requester(RequestClientOption option) {
return new SimpleOkhttpRequester(option, true);
}
@Singleton
public UndergraduateLogin undergraduateLogin(Requester requester) {
return new UndergraduateLogin(requester);
}
@Singleton
public UndergradCourseTableApiService undergradCourseTableApiService(Requester requester) {
return new UndergradCourseTableApiService(requester);
}
@Singleton
public UndergradScoreApiService undergradScoreApiService(Requester requester) {
return new UndergradScoreApiService(requester);
}
@Singleton
public UndergradStudentInfoApiService undergradStudentInfoApiService(Requester requester) {
return new UndergradStudentInfoApiService(requester);
}
@Singleton
public UndergradTrainingPlanApiService undergradTrainingPlanApiService(Requester requester) {
return new UndergradTrainingPlanApiService(requester);
}
@Singleton
public UndergradCreditStatusApiService undergradCreditStatusApiService(Requester requester) {
return new UndergradCreditStatusApiService(requester);
}
@Singleton
public UndergradExamDelayApiService undergradExamDelayApiService(Requester requester) {
return new UndergradExamDelayApiService(requester);
}
}

@ -0,0 +1,32 @@
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);
}
}

@ -0,0 +1,60 @@
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);
}
}

@ -0,0 +1,62 @@
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,152 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>getting-started - 1.0.0-SNAPSHOT</title>
<style>
h1, h2, h3, h4, h5, h6 {
margin-bottom: 0.5rem;
font-weight: 400;
line-height: 1.5;
}
h1 {
font-size: 2.5rem;
}
h2 {
font-size: 2rem
}
h3 {
font-size: 1.75rem
}
h4 {
font-size: 1.5rem
}
h5 {
font-size: 1.25rem
}
h6 {
font-size: 1rem
}
.lead {
font-weight: 300;
font-size: 2rem;
}
.banner {
font-size: 2.7rem;
margin: 0;
padding: 2rem 1rem;
background-color: #00A1E2;
color: white;
}
body {
margin: 0;
font-family: -apple-system, system-ui, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
}
code {
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 87.5%;
color: #e83e8c;
word-break: break-word;
}
.left-column {
padding: .75rem;
max-width: 75%;
min-width: 55%;
}
.right-column {
padding: .75rem;
max-width: 25%;
}
.container {
display: flex;
width: 100%;
}
li {
margin: 0.75rem;
}
.right-section {
margin-left: 1rem;
padding-left: 0.5rem;
}
.right-section h3 {
padding-top: 0;
font-weight: 200;
}
.right-section ul {
border-left: 0.3rem solid #00A1E2;
list-style-type: none;
padding-left: 0;
}
</style>
</head>
<body>
<div class="banner lead">
Your new Cloud-Native application is ready!
</div>
<div class="container">
<div class="left-column">
<p class="lead"> Congratulations, you have created a new Quarkus application.</p>
<h2>Why do you see this?</h2>
<p>This page is served by Quarkus. The source is in
<code>src/main/resources/META-INF/resources/index.html</code>.</p>
<h2>What can I do from here?</h2>
<p>If not already done, run the application in <em>dev mode</em> using: <code>mvn quarkus:dev</code>.
</p>
<ul>
<li>Add REST resources, Servlets, functions and other services in <code>src/main/java</code>.</li>
<li>Your static assets are located in <code>src/main/resources/META-INF/resources</code>.</li>
<li>Configure your application in <code>src/main/resources/application.properties</code>.
</li>
</ul>
<h2>How do I get rid of this page?</h2>
<p>Just delete the <code>src/main/resources/META-INF/resources/index.html</code> file.</p>
</div>
<div class="right-column">
<div class="right-section">
<h3>Application</h3>
<ul>
<li>GroupId: org.acme</li>
<li>ArtifactId: getting-started</li>
<li>Version: 1.0.0-SNAPSHOT</li>
<li>Quarkus Version: 0.11.0</li>
</ul>
</div>
<div class="right-section">
<h3>Next steps</h3>
<ul>
<li><a href="https://quarkus.io/guides/maven-tooling.html">Setup your IDE</a></li>
<li><a href="https://quarkus.io/guides/getting-started-guide.html">Getting started</a></li>
<li><a href="https://quarkus.io">Quarkus Web Site</a></li>
</ul>
</div>
</div>
</div>
</body>
</html>

@ -0,0 +1,11 @@
quarkus.http.port=22800
#quarkus.log.level=DEBUG
quarkus.log.file.encoding=UTF-8
# 打包成jar时附带依赖
quarkus.package.type=uber-jar
# 原生镜像编译附加参数,去掉后编译会失败
# 但也只是能编译完成,目前的编译产物完全不可用,有非常多的严重bug
# 现阶段使用jar运行,启动效率虽不如原生程序,但速度尚可
quarkus.native.additional-build-args="--initialize-at-run-time=cn.wustlinghang.mywust"

@ -1,59 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.wustlinghang.wusthelper</groupId>
<artifactId>library</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>cn.wustlinghang</groupId>
<artifactId>mywust-core</artifactId>
<version>0.0.2-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>cn.wustlinghang</groupId>
<artifactId>mywust-network-okhttp</artifactId>
<version>0.0.2-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>cn.wustlinghang.wusthelper</groupId>
<artifactId>common</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>2.1.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.26</version>
<scope>provided</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>central</id>
<url>https://repo1.maven.org/maven2</url>
</repository>
<repository>
<snapshots>
<enabled>true</enabled>
</snapshots>
<id>github</id>
<url>https://maven.pkg.github.com/LingHangStudio/mywust</url>
</repository>
</repositories>
</project>

@ -10,11 +10,143 @@
</parent> </parent>
<artifactId>library</artifactId> <artifactId>library</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties> <properties>
<compiler-plugin.version>3.11.0</compiler-plugin.version>
<maven.compiler.release>17</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
<quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
<!-- 3.2.0.Final版本与flatten-maven-plugin插件同时使用会出现问题,现临时降至3.1.3 -->
<quarkus.platform.version>3.1.3.Final</quarkus.platform.version>
<skipITs>true</skipITs>
<surefire-plugin.version>3.0.0</surefire-plugin.version>
<maven.compiler.source>17</maven.compiler.source> <maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target> <maven.compiler.target>17</maven.compiler.target>
<maven.compiler.parameters>true</maven.compiler.parameters>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> </properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>${quarkus.platform.artifact-id}</artifactId>
<version>${quarkus.platform.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive-jackson</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus.platform.version}</version>
<extensions>true</extensions>
<configuration>
<systemProperties>
<file.encoding>UTF-8</file.encoding>
</systemProperties>
</configuration>
<executions>
<execution>
<goals>
<goal>build</goal>
<goal>generate-code</goal>
<goal>generate-code-tests</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler-plugin.version}</version>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<configuration>
<systemPropertyVariables>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<systemPropertyVariables>
<native.image.path>${project.build.directory}/${project.build.finalName}-runner
</native.image.path>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>native</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<properties>
<skipITs>false</skipITs>
<quarkus.package.type>native</quarkus.package.type>
</properties>
</profile>
</profiles>
</project> </project>

@ -0,0 +1,54 @@
####
# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
#
# Before building the container image run:
#
# ./mvnw package
#
# Then, build the image with:
#
# docker build -f src/main/docker/Dockerfile.jvm -t quarkus/getting-started-jvm .
#
# Then run the container using:
#
# docker run -i --rm -p 8080:8080 quarkus/getting-started-jvm
#
# If you want to include the debug port into your docker image
# you will have to expose the debug port (default 5005) like this : EXPOSE 8080 5050
#
# Then run the container using :
#
# docker run -i --rm -p 8080:8080 -p 5005:5005 -e JAVA_ENABLE_DEBUG="true" quarkus/getting-started-jvm
#
###
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.3
ARG JAVA_PACKAGE=java-11-openjdk-headless
ARG RUN_JAVA_VERSION=1.3.8
ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en'
# Install java and the run-java script
# Also set up permissions for user `1001`
RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \
&& microdnf update \
&& microdnf clean all \
&& mkdir /deployments \
&& chown 1001 /deployments \
&& chmod "g+rwX" /deployments \
&& chown 1001:root /deployments \
&& curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \
&& chown 1001 /deployments/run-java.sh \
&& chmod 540 /deployments/run-java.sh \
&& echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/lib/security/java.security
# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size.
ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
# We make four distinct layers so if there are application changes the library layers can be re-used
COPY --chown=1001 target/quarkus-app/lib/ /deployments/lib/
COPY --chown=1001 target/quarkus-app/*.jar /deployments/
COPY --chown=1001 target/quarkus-app/app/ /deployments/app/
COPY --chown=1001 target/quarkus-app/quarkus/ /deployments/quarkus/
EXPOSE 8080
USER 1001
ENTRYPOINT [ "/deployments/run-java.sh" ]

@ -0,0 +1,51 @@
####
# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
#
# Before building the container image run:
#
# ./mvnw package -Dquarkus.package.type=legacy-jar
#
# Then, build the image with:
#
# docker build -f src/main/docker/Dockerfile.legacy-jar -t quarkus/getting-started-legacy-jar .
#
# Then run the container using:
#
# docker run -i --rm -p 8080:8080 quarkus/getting-started-legacy-jar
#
# If you want to include the debug port into your docker image
# you will have to expose the debug port (default 5005) like this : EXPOSE 8080 5050
#
# Then run the container using :
#
# docker run -i --rm -p 8080:8080 -p 5005:5005 -e JAVA_ENABLE_DEBUG="true" quarkus/getting-started-legacy-jar
#
###
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.3
ARG JAVA_PACKAGE=java-11-openjdk-headless
ARG RUN_JAVA_VERSION=1.3.8
ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en'
# Install java and the run-java script
# Also set up permissions for user `1001`
RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \
&& microdnf update \
&& microdnf clean all \
&& mkdir /deployments \
&& chown 1001 /deployments \
&& chmod "g+rwX" /deployments \
&& chown 1001:root /deployments \
&& curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \
&& chown 1001 /deployments/run-java.sh \
&& chmod 540 /deployments/run-java.sh \
&& echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/lib/security/java.security
# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size.
ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
COPY target/lib/* /deployments/lib/
COPY target/*-runner.jar /deployments/app.jar
EXPOSE 8080
USER 1001
ENTRYPOINT [ "/deployments/run-java.sh" ]

@ -0,0 +1,27 @@
####
# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode
#
# Before building the container image run:
#
# ./mvnw package -Pnative
#
# Then, build the image with:
#
# docker build -f src/main/docker/Dockerfile.native -t quarkus/getting-started .
#
# Then run the container using:
#
# docker run -i --rm -p 8080:8080 quarkus/getting-started
#
###
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.3
WORKDIR /work/
RUN chown 1001 /work \
&& chmod "g+rwX" /work \
&& chown 1001:root /work
COPY --chown=1001:root target/*-runner /work/application
EXPOSE 8080
USER 1001
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]

@ -0,0 +1,23 @@
####
# This Dockerfile is used in order to build a distroless container that runs the Quarkus application in native (no JVM) mode
#
# Before building the container image run:
#
# ./mvnw package -Pnative
#
# Then, build the image with:
#
# docker build -f src/main/docker/Dockerfile.native-micro -t quarkus/getting-started .
#
# Then run the container using:
#
# docker run -i --rm -p 8080:8080 quarkus/getting-started
#
###
FROM quay.io/quarkus/quarkus-micro-image:1.0
COPY target/*-runner /application
EXPOSE 8080
USER 1001
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]

@ -1,7 +0,0 @@
package cn.wustlinghang;
public class Main {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}

@ -0,0 +1,32 @@
package cn.wustlinghang.wusthelper.internal.library.api.json;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.wusthelper.internal.library.services.LoginService;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
@Path("/cookie")
public class CookieApi {
private final LoginService loginService;
public CookieApi(LoginService loginService) {
this.loginService = loginService;
}
@GET
@Path("/")
public String login(@QueryParam("username") @NotNull String username,
@QueryParam("password") @NotNull String password) throws IOException, ApiException {
return loginService.login(username, password, false);
}
@GET
@Path("/verify")
public Boolean verify(@QueryParam("cookie") @NotNull String cookie) throws IOException {
return loginService.verify(cookie);
}
}

@ -0,0 +1,52 @@
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);
}
}

@ -0,0 +1,54 @@
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);
}
}

@ -0,0 +1,50 @@
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);
}
}

@ -0,0 +1,47 @@
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);
}
}

@ -0,0 +1,47 @@
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);
}
}

@ -0,0 +1,14 @@
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");
}
}

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

@ -0,0 +1,33 @@
package cn.wustlinghang.wusthelper.internal.library.api.json.handler;
import cn.wustlinghang.wusthelper.rpc.response.ResponseCode;
import cn.wustlinghang.wusthelper.rpc.response.RpcResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
public abstract class ExceptionHandlerBase {
public static final String EXCEPTION_HEADER_KEY = "X-exception-handler";
private static final ObjectMapper objectMapper = new ObjectMapper();
public Response toResponse(ResponseCode code, String msg, String handlerName) {
return toResponse(code.getCode(), msg, handlerName);
}
public Response toResponse(int code, String msg, String handlerName) {
Object response;
try {
response = objectMapper.writeValueAsString(RpcResponse.error(code, msg));
} catch (JsonProcessingException e) {
response = RpcResponse.error(ResponseCode.SERVER_INTERNAL_ERROR);
}
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity(response)
.header(EXCEPTION_HEADER_KEY, handlerName)
.type(MediaType.APPLICATION_JSON)
.build();
}
}

@ -0,0 +1,23 @@
package cn.wustlinghang.wusthelper.internal.library.api.json.handler;
import cn.wustlinghang.wusthelper.rpc.response.ResponseCode;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
@Slf4j
@Provider
public class IOExceptionHandler extends ExceptionHandlerBase implements ExceptionMapper<IOException> {
@Override
public Response toResponse(IOException e) {
log.error("IO异常:", e);
return super.toResponse(
ResponseCode.SERVER_INTERNAL_ERROR,
e.toString(),
"IOExceptionHandler"
);
}
}

@ -0,0 +1,22 @@
package cn.wustlinghang.wusthelper.internal.library.api.json.handler;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.rpc.response.ResponseCode;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Provider
public class ParseExceptionHandler extends ExceptionHandlerBase implements ExceptionMapper<ParseException> {
@Override
public Response toResponse(ParseException e) {
log.error("解析异常:", e);
return super.toResponse(
ResponseCode.SERVER_INTERNAL_ERROR,
e.toString(),
"ParseExceptionHandler"
);
}
}

@ -0,0 +1,22 @@
package cn.wustlinghang.wusthelper.internal.library.api.json.handler;
import cn.wustlinghang.wusthelper.rpc.response.ResponseCode;
import jakarta.validation.ValidationException;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Provider
public class ValidationExceptionHandler extends ExceptionHandlerBase
implements ExceptionMapper<ValidationException> {
@Override
public Response toResponse(ValidationException e) {
return super.toResponse(
ResponseCode.PARAM_WRONG,
"参数错误:" + e.toString(),
"ValidationExceptionHandler"
);
}
}

@ -0,0 +1,36 @@
package cn.wustlinghang.wusthelper.internal.library.api.json.interceptor;
import cn.wustlinghang.wusthelper.internal.library.api.json.handler.ExceptionHandlerBase;
import cn.wustlinghang.wusthelper.rpc.response.RpcResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.ext.Provider;
import jakarta.ws.rs.ext.WriterInterceptor;
import jakarta.ws.rs.ext.WriterInterceptorContext;
import java.io.IOException;
@Provider
public class ResponseWrapperInterceptor implements WriterInterceptor {
private final ObjectMapper objectMapper;
public ResponseWrapperInterceptor(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
@Override
public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
boolean hasException = context.getHeaders().get(ExceptionHandlerBase.EXCEPTION_HEADER_KEY) != null;
if (!hasException) {
Object data = context.getEntity();
RpcResponse<Object> wrappedResponse = RpcResponse.success(data);
String json = objectMapper.writeValueAsString(wrappedResponse);
context.getHeaders().putSingle(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
context.setEntity(json);
}
context.proceed();
}
}

@ -0,0 +1,12 @@
package cn.wustlinghang.wusthelper.internal.library.bean;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Singleton;
public class JacksonBean {
@ApplicationScoped
public ObjectMapper objectMapper() {
return new ObjectMapper();
}
}

@ -0,0 +1,36 @@
package cn.wustlinghang.wusthelper.internal.library.bean;
import cn.wustlinghang.mywust.core.parser.undergraduate.*;
import jakarta.enterprise.context.ApplicationScoped;
public class MywustParserBeans {
@ApplicationScoped
public UndergradCourseTableParser undergradCourseTableParser() {
return new UndergradCourseTableParser();
}
@ApplicationScoped
public UndergradScoreParser undergradScoreParser() {
return new UndergradScoreParser();
}
@ApplicationScoped
public UndergradStudentInfoPageParser undergradStudentInfoPageParser() {
return new UndergradStudentInfoPageParser();
}
@ApplicationScoped
public UndergradTrainingPlanPageParser undergradTrainingPlanPageParser() {
return new UndergradTrainingPlanPageParser();
}
@ApplicationScoped
public UndergradCreditStatusParser undergradCreditStatusParser() {
return new UndergradCreditStatusParser();
}
@ApplicationScoped
public UndergradExamDelayParser undergradExamDelayParser() {
return new UndergradExamDelayParser();
}
}

@ -0,0 +1,63 @@
package cn.wustlinghang.wusthelper.internal.library.bean;
import cn.wustlinghang.mywust.core.request.service.auth.UndergraduateLogin;
import cn.wustlinghang.mywust.core.request.service.undergraduate.*;
import cn.wustlinghang.mywust.network.RequestClientOption;
import cn.wustlinghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.okhttp.SimpleOkhttpRequester;
import jakarta.inject.Singleton;
public class MywustRequestAgentBeans {
@Singleton
public RequestClientOption requestClientOption() {
RequestClientOption.Proxy proxy = RequestClientOption.Proxy.builder()
.address("127.0.0.1")
.port(8080)
.build();
RequestClientOption option = new RequestClientOption();
// option.setProxy(proxy);
return option;
}
@Singleton
public Requester requester(RequestClientOption option) {
return new SimpleOkhttpRequester(option, true);
}
@Singleton
public UndergraduateLogin undergraduateLogin(Requester requester) {
return new UndergraduateLogin(requester);
}
@Singleton
public UndergradCourseTableApiService undergradCourseTableApiService(Requester requester) {
return new UndergradCourseTableApiService(requester);
}
@Singleton
public UndergradScoreApiService undergradScoreApiService(Requester requester) {
return new UndergradScoreApiService(requester);
}
@Singleton
public UndergradStudentInfoApiService undergradStudentInfoApiService(Requester requester) {
return new UndergradStudentInfoApiService(requester);
}
@Singleton
public UndergradTrainingPlanApiService undergradTrainingPlanApiService(Requester requester) {
return new UndergradTrainingPlanApiService(requester);
}
@Singleton
public UndergradCreditStatusApiService undergradCreditStatusApiService(Requester requester) {
return new UndergradCreditStatusApiService(requester);
}
@Singleton
public UndergradExamDelayApiService undergradExamDelayApiService(Requester requester) {
return new UndergradExamDelayApiService(requester);
}
}

@ -0,0 +1,32 @@
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);
}
}

@ -0,0 +1,60 @@
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);
}
}

@ -0,0 +1,62 @@
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,152 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>getting-started - 1.0.0-SNAPSHOT</title>
<style>
h1, h2, h3, h4, h5, h6 {
margin-bottom: 0.5rem;
font-weight: 400;
line-height: 1.5;
}
h1 {
font-size: 2.5rem;
}
h2 {
font-size: 2rem
}
h3 {
font-size: 1.75rem
}
h4 {
font-size: 1.5rem
}
h5 {
font-size: 1.25rem
}
h6 {
font-size: 1rem
}
.lead {
font-weight: 300;
font-size: 2rem;
}
.banner {
font-size: 2.7rem;
margin: 0;
padding: 2rem 1rem;
background-color: #00A1E2;
color: white;
}
body {
margin: 0;
font-family: -apple-system, system-ui, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
}
code {
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 87.5%;
color: #e83e8c;
word-break: break-word;
}
.left-column {
padding: .75rem;
max-width: 75%;
min-width: 55%;
}
.right-column {
padding: .75rem;
max-width: 25%;
}
.container {
display: flex;
width: 100%;
}
li {
margin: 0.75rem;
}
.right-section {
margin-left: 1rem;
padding-left: 0.5rem;
}
.right-section h3 {
padding-top: 0;
font-weight: 200;
}
.right-section ul {
border-left: 0.3rem solid #00A1E2;
list-style-type: none;
padding-left: 0;
}
</style>
</head>
<body>
<div class="banner lead">
Your new Cloud-Native application is ready!
</div>
<div class="container">
<div class="left-column">
<p class="lead"> Congratulations, you have created a new Quarkus application.</p>
<h2>Why do you see this?</h2>
<p>This page is served by Quarkus. The source is in
<code>src/main/resources/META-INF/resources/index.html</code>.</p>
<h2>What can I do from here?</h2>
<p>If not already done, run the application in <em>dev mode</em> using: <code>mvn quarkus:dev</code>.
</p>
<ul>
<li>Add REST resources, Servlets, functions and other services in <code>src/main/java</code>.</li>
<li>Your static assets are located in <code>src/main/resources/META-INF/resources</code>.</li>
<li>Configure your application in <code>src/main/resources/application.properties</code>.
</li>
</ul>
<h2>How do I get rid of this page?</h2>
<p>Just delete the <code>src/main/resources/META-INF/resources/index.html</code> file.</p>
</div>
<div class="right-column">
<div class="right-section">
<h3>Application</h3>
<ul>
<li>GroupId: org.acme</li>
<li>ArtifactId: getting-started</li>
<li>Version: 1.0.0-SNAPSHOT</li>
<li>Quarkus Version: 0.11.0</li>
</ul>
</div>
<div class="right-section">
<h3>Next steps</h3>
<ul>
<li><a href="https://quarkus.io/guides/maven-tooling.html">Setup your IDE</a></li>
<li><a href="https://quarkus.io/guides/getting-started-guide.html">Getting started</a></li>
<li><a href="https://quarkus.io">Quarkus Web Site</a></li>
</ul>
</div>
</div>
</div>
</body>
</html>

@ -0,0 +1,11 @@
quarkus.http.port=22800
#quarkus.log.level=DEBUG
quarkus.log.file.encoding=UTF-8
# 打包成jar时附带依赖
quarkus.package.type=uber-jar
# 原生镜像编译附加参数,去掉后编译会失败
# 但也只是能编译完成,目前的编译产物完全不可用,有非常多的严重bug
# 现阶段使用jar运行,启动效率虽不如原生程序,但速度尚可
quarkus.native.additional-build-args="--initialize-at-run-time=cn.wustlinghang.mywust"

@ -1,59 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.wustlinghang.wusthelper</groupId>
<artifactId>physics</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>cn.wustlinghang</groupId>
<artifactId>mywust-core</artifactId>
<version>0.0.2-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>cn.wustlinghang</groupId>
<artifactId>mywust-network-okhttp</artifactId>
<version>0.0.2-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>cn.wustlinghang.wusthelper</groupId>
<artifactId>common</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>2.1.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.26</version>
<scope>provided</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>central</id>
<url>https://repo1.maven.org/maven2</url>
</repository>
<repository>
<snapshots>
<enabled>true</enabled>
</snapshots>
<id>github</id>
<url>https://maven.pkg.github.com/LingHangStudio/mywust</url>
</repository>
</repositories>
</project>

@ -10,11 +10,143 @@
</parent> </parent>
<artifactId>physics</artifactId> <artifactId>physics</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties> <properties>
<compiler-plugin.version>3.11.0</compiler-plugin.version>
<maven.compiler.release>17</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
<quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
<!-- 3.2.0.Final版本与flatten-maven-plugin插件同时使用会出现问题,现临时降至3.1.3 -->
<quarkus.platform.version>3.1.3.Final</quarkus.platform.version>
<skipITs>true</skipITs>
<surefire-plugin.version>3.0.0</surefire-plugin.version>
<maven.compiler.source>17</maven.compiler.source> <maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target> <maven.compiler.target>17</maven.compiler.target>
<maven.compiler.parameters>true</maven.compiler.parameters>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> </properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>${quarkus.platform.artifact-id}</artifactId>
<version>${quarkus.platform.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive-jackson</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus.platform.version}</version>
<extensions>true</extensions>
<configuration>
<systemProperties>
<file.encoding>UTF-8</file.encoding>
</systemProperties>
</configuration>
<executions>
<execution>
<goals>
<goal>build</goal>
<goal>generate-code</goal>
<goal>generate-code-tests</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${compiler-plugin.version}</version>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<configuration>
<systemPropertyVariables>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${surefire-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<systemPropertyVariables>
<native.image.path>${project.build.directory}/${project.build.finalName}-runner
</native.image.path>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>native</id>
<activation>
<property>
<name>native</name>
</property>
</activation>
<properties>
<skipITs>false</skipITs>
<quarkus.package.type>native</quarkus.package.type>
</properties>
</profile>
</profiles>
</project> </project>

@ -0,0 +1,54 @@
####
# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
#
# Before building the container image run:
#
# ./mvnw package
#
# Then, build the image with:
#
# docker build -f src/main/docker/Dockerfile.jvm -t quarkus/getting-started-jvm .
#
# Then run the container using:
#
# docker run -i --rm -p 8080:8080 quarkus/getting-started-jvm
#
# If you want to include the debug port into your docker image
# you will have to expose the debug port (default 5005) like this : EXPOSE 8080 5050
#
# Then run the container using :
#
# docker run -i --rm -p 8080:8080 -p 5005:5005 -e JAVA_ENABLE_DEBUG="true" quarkus/getting-started-jvm
#
###
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.3
ARG JAVA_PACKAGE=java-11-openjdk-headless
ARG RUN_JAVA_VERSION=1.3.8
ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en'
# Install java and the run-java script
# Also set up permissions for user `1001`
RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \
&& microdnf update \
&& microdnf clean all \
&& mkdir /deployments \
&& chown 1001 /deployments \
&& chmod "g+rwX" /deployments \
&& chown 1001:root /deployments \
&& curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \
&& chown 1001 /deployments/run-java.sh \
&& chmod 540 /deployments/run-java.sh \
&& echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/lib/security/java.security
# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size.
ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
# We make four distinct layers so if there are application changes the library layers can be re-used
COPY --chown=1001 target/quarkus-app/lib/ /deployments/lib/
COPY --chown=1001 target/quarkus-app/*.jar /deployments/
COPY --chown=1001 target/quarkus-app/app/ /deployments/app/
COPY --chown=1001 target/quarkus-app/quarkus/ /deployments/quarkus/
EXPOSE 8080
USER 1001
ENTRYPOINT [ "/deployments/run-java.sh" ]

@ -0,0 +1,51 @@
####
# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
#
# Before building the container image run:
#
# ./mvnw package -Dquarkus.package.type=legacy-jar
#
# Then, build the image with:
#
# docker build -f src/main/docker/Dockerfile.legacy-jar -t quarkus/getting-started-legacy-jar .
#
# Then run the container using:
#
# docker run -i --rm -p 8080:8080 quarkus/getting-started-legacy-jar
#
# If you want to include the debug port into your docker image
# you will have to expose the debug port (default 5005) like this : EXPOSE 8080 5050
#
# Then run the container using :
#
# docker run -i --rm -p 8080:8080 -p 5005:5005 -e JAVA_ENABLE_DEBUG="true" quarkus/getting-started-legacy-jar
#
###
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.3
ARG JAVA_PACKAGE=java-11-openjdk-headless
ARG RUN_JAVA_VERSION=1.3.8
ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en'
# Install java and the run-java script
# Also set up permissions for user `1001`
RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \
&& microdnf update \
&& microdnf clean all \
&& mkdir /deployments \
&& chown 1001 /deployments \
&& chmod "g+rwX" /deployments \
&& chown 1001:root /deployments \
&& curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \
&& chown 1001 /deployments/run-java.sh \
&& chmod 540 /deployments/run-java.sh \
&& echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/lib/security/java.security
# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size.
ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
COPY target/lib/* /deployments/lib/
COPY target/*-runner.jar /deployments/app.jar
EXPOSE 8080
USER 1001
ENTRYPOINT [ "/deployments/run-java.sh" ]

@ -0,0 +1,27 @@
####
# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode
#
# Before building the container image run:
#
# ./mvnw package -Pnative
#
# Then, build the image with:
#
# docker build -f src/main/docker/Dockerfile.native -t quarkus/getting-started .
#
# Then run the container using:
#
# docker run -i --rm -p 8080:8080 quarkus/getting-started
#
###
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.3
WORKDIR /work/
RUN chown 1001 /work \
&& chmod "g+rwX" /work \
&& chown 1001:root /work
COPY --chown=1001:root target/*-runner /work/application
EXPOSE 8080
USER 1001
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]

@ -0,0 +1,23 @@
####
# This Dockerfile is used in order to build a distroless container that runs the Quarkus application in native (no JVM) mode
#
# Before building the container image run:
#
# ./mvnw package -Pnative
#
# Then, build the image with:
#
# docker build -f src/main/docker/Dockerfile.native-micro -t quarkus/getting-started .
#
# Then run the container using:
#
# docker run -i --rm -p 8080:8080 quarkus/getting-started
#
###
FROM quay.io/quarkus/quarkus-micro-image:1.0
COPY target/*-runner /application
EXPOSE 8080
USER 1001
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]

@ -1,7 +0,0 @@
package cn.wustlinghang;
public class Main {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}

@ -0,0 +1,32 @@
package cn.wustlinghang.wusthelper.internal.physics.api.json;
import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.wusthelper.internal.physics.services.LoginService;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam;
import java.io.IOException;
@Path("/cookie")
public class CookieApi {
private final LoginService loginService;
public CookieApi(LoginService loginService) {
this.loginService = loginService;
}
@GET
@Path("/")
public String login(@QueryParam("username") @NotNull String username,
@QueryParam("password") @NotNull String password) throws IOException, ApiException {
return loginService.login(username, password, false);
}
@GET
@Path("/verify")
public Boolean verify(@QueryParam("cookie") @NotNull String cookie) throws IOException {
return loginService.verify(cookie);
}
}

@ -0,0 +1,52 @@
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);
}
}

@ -0,0 +1,54 @@
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);
}
}

@ -0,0 +1,50 @@
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);
}
}

@ -0,0 +1,47 @@
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);
}
}

@ -0,0 +1,47 @@
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);
}
}

@ -0,0 +1,14 @@
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");
}
}

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

@ -0,0 +1,33 @@
package cn.wustlinghang.wusthelper.internal.physics.api.json.handler;
import cn.wustlinghang.wusthelper.rpc.response.ResponseCode;
import cn.wustlinghang.wusthelper.rpc.response.RpcResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
public abstract class ExceptionHandlerBase {
public static final String EXCEPTION_HEADER_KEY = "X-exception-handler";
private static final ObjectMapper objectMapper = new ObjectMapper();
public Response toResponse(ResponseCode code, String msg, String handlerName) {
return toResponse(code.getCode(), msg, handlerName);
}
public Response toResponse(int code, String msg, String handlerName) {
Object response;
try {
response = objectMapper.writeValueAsString(RpcResponse.error(code, msg));
} catch (JsonProcessingException e) {
response = RpcResponse.error(ResponseCode.SERVER_INTERNAL_ERROR);
}
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity(response)
.header(EXCEPTION_HEADER_KEY, handlerName)
.type(MediaType.APPLICATION_JSON)
.build();
}
}

@ -0,0 +1,23 @@
package cn.wustlinghang.wusthelper.internal.physics.api.json.handler;
import cn.wustlinghang.wusthelper.rpc.response.ResponseCode;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
@Slf4j
@Provider
public class IOExceptionHandler extends ExceptionHandlerBase implements ExceptionMapper<IOException> {
@Override
public Response toResponse(IOException e) {
log.error("IO异常:", e);
return super.toResponse(
ResponseCode.SERVER_INTERNAL_ERROR,
e.toString(),
"IOExceptionHandler"
);
}
}

@ -0,0 +1,22 @@
package cn.wustlinghang.wusthelper.internal.physics.api.json.handler;
import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.rpc.response.ResponseCode;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Provider
public class ParseExceptionHandler extends ExceptionHandlerBase implements ExceptionMapper<ParseException> {
@Override
public Response toResponse(ParseException e) {
log.error("解析异常:", e);
return super.toResponse(
ResponseCode.SERVER_INTERNAL_ERROR,
e.toString(),
"ParseExceptionHandler"
);
}
}

@ -0,0 +1,22 @@
package cn.wustlinghang.wusthelper.internal.physics.api.json.handler;
import cn.wustlinghang.wusthelper.rpc.response.ResponseCode;
import jakarta.validation.ValidationException;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Provider
public class ValidationExceptionHandler extends ExceptionHandlerBase
implements ExceptionMapper<ValidationException> {
@Override
public Response toResponse(ValidationException e) {
return super.toResponse(
ResponseCode.PARAM_WRONG,
"参数错误:" + e.toString(),
"ValidationExceptionHandler"
);
}
}

@ -0,0 +1,36 @@
package cn.wustlinghang.wusthelper.internal.physics.api.json.interceptor;
import cn.wustlinghang.wusthelper.internal.physics.api.json.handler.ExceptionHandlerBase;
import cn.wustlinghang.wusthelper.rpc.response.RpcResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.ext.Provider;
import jakarta.ws.rs.ext.WriterInterceptor;
import jakarta.ws.rs.ext.WriterInterceptorContext;
import java.io.IOException;
@Provider
public class ResponseWrapperInterceptor implements WriterInterceptor {
private final ObjectMapper objectMapper;
public ResponseWrapperInterceptor(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
@Override
public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
boolean hasException = context.getHeaders().get(ExceptionHandlerBase.EXCEPTION_HEADER_KEY) != null;
if (!hasException) {
Object data = context.getEntity();
RpcResponse<Object> wrappedResponse = RpcResponse.success(data);
String json = objectMapper.writeValueAsString(wrappedResponse);
context.getHeaders().putSingle(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
context.setEntity(json);
}
context.proceed();
}
}

@ -0,0 +1,12 @@
package cn.wustlinghang.wusthelper.internal.physics.bean;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Singleton;
public class JacksonBean {
@ApplicationScoped
public ObjectMapper objectMapper() {
return new ObjectMapper();
}
}

@ -0,0 +1,36 @@
package cn.wustlinghang.wusthelper.internal.physics.bean;
import cn.wustlinghang.mywust.core.parser.undergraduate.*;
import jakarta.enterprise.context.ApplicationScoped;
public class MywustParserBeans {
@ApplicationScoped
public UndergradCourseTableParser undergradCourseTableParser() {
return new UndergradCourseTableParser();
}
@ApplicationScoped
public UndergradScoreParser undergradScoreParser() {
return new UndergradScoreParser();
}
@ApplicationScoped
public UndergradStudentInfoPageParser undergradStudentInfoPageParser() {
return new UndergradStudentInfoPageParser();
}
@ApplicationScoped
public UndergradTrainingPlanPageParser undergradTrainingPlanPageParser() {
return new UndergradTrainingPlanPageParser();
}
@ApplicationScoped
public UndergradCreditStatusParser undergradCreditStatusParser() {
return new UndergradCreditStatusParser();
}
@ApplicationScoped
public UndergradExamDelayParser undergradExamDelayParser() {
return new UndergradExamDelayParser();
}
}

@ -0,0 +1,63 @@
package cn.wustlinghang.wusthelper.internal.physics.bean;
import cn.wustlinghang.mywust.core.request.service.auth.UndergraduateLogin;
import cn.wustlinghang.mywust.core.request.service.undergraduate.*;
import cn.wustlinghang.mywust.network.RequestClientOption;
import cn.wustlinghang.mywust.network.Requester;
import cn.wustlinghang.mywust.network.okhttp.SimpleOkhttpRequester;
import jakarta.inject.Singleton;
public class MywustRequestAgentBeans {
@Singleton
public RequestClientOption requestClientOption() {
RequestClientOption.Proxy proxy = RequestClientOption.Proxy.builder()
.address("127.0.0.1")
.port(8080)
.build();
RequestClientOption option = new RequestClientOption();
// option.setProxy(proxy);
return option;
}
@Singleton
public Requester requester(RequestClientOption option) {
return new SimpleOkhttpRequester(option, true);
}
@Singleton
public UndergraduateLogin undergraduateLogin(Requester requester) {
return new UndergraduateLogin(requester);
}
@Singleton
public UndergradCourseTableApiService undergradCourseTableApiService(Requester requester) {
return new UndergradCourseTableApiService(requester);
}
@Singleton
public UndergradScoreApiService undergradScoreApiService(Requester requester) {
return new UndergradScoreApiService(requester);
}
@Singleton
public UndergradStudentInfoApiService undergradStudentInfoApiService(Requester requester) {
return new UndergradStudentInfoApiService(requester);
}
@Singleton
public UndergradTrainingPlanApiService undergradTrainingPlanApiService(Requester requester) {
return new UndergradTrainingPlanApiService(requester);
}
@Singleton
public UndergradCreditStatusApiService undergradCreditStatusApiService(Requester requester) {
return new UndergradCreditStatusApiService(requester);
}
@Singleton
public UndergradExamDelayApiService undergradExamDelayApiService(Requester requester) {
return new UndergradExamDelayApiService(requester);
}
}

@ -0,0 +1,32 @@
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);
}
}

@ -0,0 +1,60 @@
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);
}
}

@ -0,0 +1,62 @@
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,152 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>getting-started - 1.0.0-SNAPSHOT</title>
<style>
h1, h2, h3, h4, h5, h6 {
margin-bottom: 0.5rem;
font-weight: 400;
line-height: 1.5;
}
h1 {
font-size: 2.5rem;
}
h2 {
font-size: 2rem
}
h3 {
font-size: 1.75rem
}
h4 {
font-size: 1.5rem
}
h5 {
font-size: 1.25rem
}
h6 {
font-size: 1rem
}
.lead {
font-weight: 300;
font-size: 2rem;
}
.banner {
font-size: 2.7rem;
margin: 0;
padding: 2rem 1rem;
background-color: #00A1E2;
color: white;
}
body {
margin: 0;
font-family: -apple-system, system-ui, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
}
code {
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 87.5%;
color: #e83e8c;
word-break: break-word;
}
.left-column {
padding: .75rem;
max-width: 75%;
min-width: 55%;
}
.right-column {
padding: .75rem;
max-width: 25%;
}
.container {
display: flex;
width: 100%;
}
li {
margin: 0.75rem;
}
.right-section {
margin-left: 1rem;
padding-left: 0.5rem;
}
.right-section h3 {
padding-top: 0;
font-weight: 200;
}
.right-section ul {
border-left: 0.3rem solid #00A1E2;
list-style-type: none;
padding-left: 0;
}
</style>
</head>
<body>
<div class="banner lead">
Your new Cloud-Native application is ready!
</div>
<div class="container">
<div class="left-column">
<p class="lead"> Congratulations, you have created a new Quarkus application.</p>
<h2>Why do you see this?</h2>
<p>This page is served by Quarkus. The source is in
<code>src/main/resources/META-INF/resources/index.html</code>.</p>
<h2>What can I do from here?</h2>
<p>If not already done, run the application in <em>dev mode</em> using: <code>mvn quarkus:dev</code>.
</p>
<ul>
<li>Add REST resources, Servlets, functions and other services in <code>src/main/java</code>.</li>
<li>Your static assets are located in <code>src/main/resources/META-INF/resources</code>.</li>
<li>Configure your application in <code>src/main/resources/application.properties</code>.
</li>
</ul>
<h2>How do I get rid of this page?</h2>
<p>Just delete the <code>src/main/resources/META-INF/resources/index.html</code> file.</p>
</div>
<div class="right-column">
<div class="right-section">
<h3>Application</h3>
<ul>
<li>GroupId: org.acme</li>
<li>ArtifactId: getting-started</li>
<li>Version: 1.0.0-SNAPSHOT</li>
<li>Quarkus Version: 0.11.0</li>
</ul>
</div>
<div class="right-section">
<h3>Next steps</h3>
<ul>
<li><a href="https://quarkus.io/guides/maven-tooling.html">Setup your IDE</a></li>
<li><a href="https://quarkus.io/guides/getting-started-guide.html">Getting started</a></li>
<li><a href="https://quarkus.io">Quarkus Web Site</a></li>
</ul>
</div>
</div>
</div>
</body>
</html>

@ -0,0 +1,11 @@
quarkus.http.port=22800
#quarkus.log.level=DEBUG
quarkus.log.file.encoding=UTF-8
# 打包成jar时附带依赖
quarkus.package.type=uber-jar
# 原生镜像编译附加参数,去掉后编译会失败
# 但也只是能编译完成,目前的编译产物完全不可用,有非常多的严重bug
# 现阶段使用jar运行,启动效率虽不如原生程序,但速度尚可
quarkus.native.additional-build-args="--initialize-at-run-time=cn.wustlinghang.mywust"

@ -20,9 +20,8 @@
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id> <quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
<quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id> <quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
<quarkus.platform.version>3.2.0.Final</quarkus.platform.version>
<!-- 3.2.0.Final版本与flatten-maven-plugin插件同时使用会出现问题,现临时降至3.1.3 --> <!-- 3.2.0.Final版本与flatten-maven-plugin插件同时使用会出现问题,现临时降至3.1.3 -->
<quarkus-maven-plugin.version>3.1.3.Final</quarkus-maven-plugin.version> <quarkus.platform.version>3.1.3.Final</quarkus.platform.version>
<skipITs>true</skipITs> <skipITs>true</skipITs>
<surefire-plugin.version>3.0.0</surefire-plugin.version> <surefire-plugin.version>3.0.0</surefire-plugin.version>
@ -78,7 +77,7 @@
<plugin> <plugin>
<groupId>${quarkus.platform.group-id}</groupId> <groupId>${quarkus.platform.group-id}</groupId>
<artifactId>quarkus-maven-plugin</artifactId> <artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus-maven-plugin.version}</version> <version>${quarkus.platform.version}</version>
<extensions>true</extensions> <extensions>true</extensions>
<configuration> <configuration>
<systemProperties> <systemProperties>

@ -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,10 +1,11 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.json; package cn.wustlinghang.wusthelper.internal.undergrad.api.json;
import cn.wustlinghang.mywust.core.parser.undergraduate.UndergradStudentInfoPageParser; import cn.wustlinghang.mywust.core.parser.undergraduate.UndergradCreditStatusParser;
import cn.wustlinghang.mywust.core.request.service.undergraduate.UndergradStudentInfoApiService; import cn.wustlinghang.mywust.core.request.service.undergraduate.UndergradCreditStatusApiService;
import cn.wustlinghang.mywust.data.global.StudentInfo; import cn.wustlinghang.mywust.data.global.StudentInfo;
import cn.wustlinghang.mywust.exception.ApiException; import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException; import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.mywust.network.RequestClientOption;
import cn.wustlinghang.wusthelper.rpc.response.RpcResponse; import cn.wustlinghang.wusthelper.rpc.response.RpcResponse;
import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
@ -18,34 +19,36 @@ import java.io.IOException;
@Path("/credit_status") @Path("/credit_status")
@ApplicationScoped @ApplicationScoped
public class CreditStatusApi { public class CreditStatusApi {
private final UndergradStudentInfoApiService studentInfoApiService; private final UndergradCreditStatusApiService creditStatusApiService;
private final UndergradStudentInfoPageParser studentInfoPageParser; private final UndergradCreditStatusParser creditStatusParser;
public CreditStatusApi(UndergradStudentInfoApiService studentInfoApiService, private final RequestClientOption option;
UndergradStudentInfoPageParser studentInfoPageParser) {
this.studentInfoApiService = studentInfoApiService; public CreditStatusApi(UndergradCreditStatusApiService creditStatusApiService,
this.studentInfoPageParser = studentInfoPageParser; UndergradCreditStatusParser creditStatusParser,
RequestClientOption option) {
this.creditStatusApiService = creditStatusApiService;
this.creditStatusParser = creditStatusParser;
this.option = option;
} }
@GET @GET
@Path("/") @Path("/")
public RpcResponse<StudentInfo> get(String cookie) throws IOException, ApiException, ParseException { public String get(String cookie) throws IOException, ApiException, ParseException {
String html = studentInfoApiService.getPage(cookie); String html = creditStatusApiService.getPage(cookie, option, false);
return this.parse(html); return this.parse(html);
} }
@GET @GET
@Path("/agent") @Path("/agent")
public RpcResponse<String> agent(@QueryParam("cookie") @NotNull String cookie) public String agent(@QueryParam("cookie") @NotNull String cookie)
throws IOException, ApiException { throws IOException, ApiException {
String html = studentInfoApiService.getPage(cookie); return creditStatusApiService.getPage(cookie, option, false);
return RpcResponse.success(html);
} }
@POST @POST
@Path("/parse") @Path("/parse")
public RpcResponse<StudentInfo> parse(String html) throws ParseException { public String parse(String html) throws ParseException {
StudentInfo result = studentInfoPageParser.parse(html); return creditStatusParser.parse(html);
return RpcResponse.success(result);
} }
} }

@ -1,7 +1,8 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.json; package cn.wustlinghang.wusthelper.internal.undergrad.api.json;
import cn.wustlinghang.mywust.core.parser.undergraduate.UndergradStudentInfoPageParser; import cn.wustlinghang.mywust.core.parser.undergraduate.UndergradScoreParser;
import cn.wustlinghang.mywust.core.request.service.undergraduate.UndergradStudentInfoApiService; 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.data.global.StudentInfo;
import cn.wustlinghang.mywust.exception.ApiException; import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException; import cn.wustlinghang.mywust.exception.ParseException;
@ -14,38 +15,36 @@ import jakarta.ws.rs.Path;
import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.QueryParam;
import java.io.IOException; import java.io.IOException;
import java.util.List;
@Path("/score") @Path("/score")
@ApplicationScoped @ApplicationScoped
public class ScoreApi { public class ScoreApi {
private final UndergradStudentInfoApiService studentInfoApiService; private final UndergradScoreApiService scoreApiService;
private final UndergradStudentInfoPageParser studentInfoPageParser; private final UndergradScoreParser scoreParser;
public ScoreApi(UndergradStudentInfoApiService studentInfoApiService, public ScoreApi(UndergradScoreApiService scoreApiService, UndergradScoreParser scoreParser) {
UndergradStudentInfoPageParser studentInfoPageParser) { this.scoreApiService = scoreApiService;
this.studentInfoApiService = studentInfoApiService; this.scoreParser = scoreParser;
this.studentInfoPageParser = studentInfoPageParser;
} }
@GET @GET
@Path("/") @Path("/")
public RpcResponse<StudentInfo> get(String cookie) throws IOException, ApiException, ParseException { public List<Score> get(String cookie) throws IOException, ApiException, ParseException {
String html = studentInfoApiService.getPage(cookie); String html = scoreApiService.getPage(cookie);
return this.parse(html); return this.parse(html);
} }
@GET @GET
@Path("/agent") @Path("/agent")
public RpcResponse<String> agent(@QueryParam("cookie") @NotNull String cookie) public String agent(@QueryParam("cookie") @NotNull String cookie)
throws IOException, ApiException { throws IOException, ApiException {
String html = studentInfoApiService.getPage(cookie); return scoreApiService.getPage(cookie);
return RpcResponse.success(html);
} }
@POST @POST
@Path("/parse") @Path("/parse")
public RpcResponse<StudentInfo> parse(String html) throws ParseException { public List<Score> parse(String html) throws ParseException {
StudentInfo result = studentInfoPageParser.parse(html); return scoreParser.parse(html);
return RpcResponse.success(result);
} }
} }

@ -1,11 +1,9 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.json; package cn.wustlinghang.wusthelper.internal.undergrad.api.json;
import cn.wustlinghang.mywust.core.parser.undergraduate.UndergradStudentInfoPageParser; import cn.wustlinghang.mywust.core.parser.undergraduate.UndergradTrainingPlanPageParser;
import cn.wustlinghang.mywust.core.request.service.undergraduate.UndergradStudentInfoApiService; import cn.wustlinghang.mywust.core.request.service.undergraduate.UndergradTrainingPlanApiService;
import cn.wustlinghang.mywust.data.global.StudentInfo;
import cn.wustlinghang.mywust.exception.ApiException; import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.mywust.exception.ParseException; import cn.wustlinghang.mywust.exception.ParseException;
import cn.wustlinghang.wusthelper.rpc.response.RpcResponse;
import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ApplicationScoped;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.GET; import jakarta.ws.rs.GET;
@ -18,34 +16,32 @@ import java.io.IOException;
@Path("/training_plan") @Path("/training_plan")
@ApplicationScoped @ApplicationScoped
public class TrainingPlanApi { public class TrainingPlanApi {
private final UndergradStudentInfoApiService studentInfoApiService; private final UndergradTrainingPlanApiService trainingPlanApiService;
private final UndergradStudentInfoPageParser studentInfoPageParser; private final UndergradTrainingPlanPageParser trainingPlanPageParser;
public TrainingPlanApi(UndergradStudentInfoApiService studentInfoApiService, public TrainingPlanApi(UndergradTrainingPlanApiService trainingPlanApiService,
UndergradStudentInfoPageParser studentInfoPageParser) { UndergradTrainingPlanPageParser trainingPlanPageParser) {
this.studentInfoApiService = studentInfoApiService; this.trainingPlanApiService = trainingPlanApiService;
this.studentInfoPageParser = studentInfoPageParser; this.trainingPlanPageParser = trainingPlanPageParser;
} }
@GET @GET
@Path("/") @Path("/")
public RpcResponse<StudentInfo> get(String cookie) throws IOException, ApiException, ParseException { public String get(String cookie) throws IOException, ApiException, ParseException {
String html = studentInfoApiService.getPage(cookie); String html = trainingPlanApiService.getPage(cookie);
return this.parse(html); return this.parse(html);
} }
@GET @GET
@Path("/agent") @Path("/agent")
public RpcResponse<String> agent(@QueryParam("cookie") @NotNull String cookie) public String agent(@QueryParam("cookie") @NotNull String cookie)
throws IOException, ApiException { throws IOException, ApiException {
String html = studentInfoApiService.getPage(cookie); return trainingPlanApiService.getPage(cookie);
return RpcResponse.success(html);
} }
@POST @POST
@Path("/parse") @Path("/parse")
public RpcResponse<StudentInfo> parse(String html) throws ParseException { public String parse(String html) throws ParseException {
StudentInfo result = studentInfoPageParser.parse(html); return trainingPlanPageParser.parse(html);
return RpcResponse.success(result);
} }
} }

@ -1,7 +1,6 @@
package cn.wustlinghang.wusthelper.internal.undergrad.api.json.handler; package cn.wustlinghang.wusthelper.internal.undergrad.api.json.handler;
import cn.wustlinghang.mywust.exception.ApiException; import cn.wustlinghang.mywust.exception.ApiException;
import cn.wustlinghang.wusthelper.rpc.response.ResponseCode;
import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper; import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider; import jakarta.ws.rs.ext.Provider;

@ -1,7 +1,6 @@
package cn.wustlinghang.wusthelper.internal.undergrad.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.ResponseCode;
import jakarta.validation.ConstraintViolationException;
import jakarta.validation.ValidationException; import jakarta.validation.ValidationException;
import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper; import jakarta.ws.rs.ext.ExceptionMapper;

@ -1,4 +0,0 @@
package cn.wustlinghang.wusthelper.internal.undergrad.exception;
public class InternalException extends Exception {
}

@ -4,3 +4,8 @@ quarkus.log.file.encoding=UTF-8
# 打包成jar时附带依赖 # 打包成jar时附带依赖
quarkus.package.type=uber-jar quarkus.package.type=uber-jar
# 原生镜像编译附加参数,去掉后编译会失败
# 但也只是能编译完成,目前的编译产物完全不可用,有非常多的严重bug
# 现阶段使用jar运行,启动效率虽不如原生程序,但速度尚可
quarkus.native.additional-build-args="--initialize-at-run-time=cn.wustlinghang.mywust"
Loading…
Cancel
Save