0%

西电晨午晚检自动填报工具

使用方法

不打包运行

修改src\main\resources\account.properties的内容为自己的学号和密码,以及src\main\resources\data.json的内容为要上报的信息。

1
2
3
4
5
6
7
8
{
"sfzx": "1", # 是否在校(0->否, 1->是)
"tw": "1", # 体温 (36℃->0, 36℃到36.5℃->1, 36.5℃到36.9℃->2, 36.9℃到37.3->3, 37.3℃到38℃->4, 38℃到38.5℃->5, 38.5℃到39℃->6, 39℃到40℃->7, 40℃以上->8)
"sfcyglq": "0", # 是否处于隔离期? (0->否, 1->是)
"sfyzz": "0", # 是否出现乏力、干咳、呼吸困难等症状? (0->否, 1->是)
"qtqk": "", # 其他情况 (文本)
"askforleave": "0" # 是否请假外出? (0->否, 1->是)
}

打包运行

修改jar包中account.propertiesdata.json文件同上。

java -jar -Dfile.encoding=UTF-8 xxxxx.jar

实现思路

https://xxcapp.xidian.edu.cn/uc/wap/login/check发送post请求获取cookie,再带着获得的cookie向https://xxcapp.xidian.edu.cn/xisuncov/wap/open-report/save发送post请求上传数据。

通过Timer使这个过程每两个小时重复一次,把程序挂在服务器就可以高枕无忧了。

源码

https://github.com/carpediemtal/XDCOV

Covid.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package eternal.fire.entity;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.Properties;

public class Covid {
private final static String LOGIN_URL = "https://xxcapp.xidian.edu.cn/uc/wap/login/check";
private final static String UPLOAD_URL = "https://xxcapp.xidian.edu.cn/xisuncov/wap/open-report/save";

private final static HttpClient httpClient = HttpClient.newBuilder().build();

private final String username;
private final String password;
private final ObjectMapper mapper;


public Covid(String username, String password) {
this.username = username;
this.password = password;
this.mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}

public Covid() throws IOException {
var account = getAccountFromFile();
this.username = account[0];
this.password = account[1];
this.mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}

public void uploadData() throws InterruptedException, IOException, URISyntaxException {
String cookie;
try {
cookie = getCookieByLogIn();
} catch (RuntimeException e) {
System.out.println(e.getMessage());
return;
}
String data = getContentFromFile();
HttpRequest request = HttpRequest.newBuilder(new URI(UPLOAD_URL))
.header("Content-Type", "application/x-www-form-urlencoded")
.headers("Cookie", cookie)
.POST(HttpRequest.BodyPublishers.ofString(data, StandardCharsets.UTF_8))
.build();
var response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
Message message = mapper.readValue(response.body(), Message.class);
if (message.getE() == 0) {
System.out.println("上报成功");
} else {
System.out.println("上报失败:" + message.getM());
}
}

private String getCookieByLogIn() throws IOException, InterruptedException, URISyntaxException {
String body = String.format("username=%s&password=%s", username, password);
HttpRequest request = HttpRequest.newBuilder(new URI(LOGIN_URL))
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(HttpRequest.BodyPublishers.ofString(body, StandardCharsets.UTF_8))
.build();
var response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
Message message = mapper.readValue(response.body(), Message.class);
if (message.getE() == 0) {
var cookies = response.headers().allValues("set-cookie");
StringBuilder ans = new StringBuilder();
for (var cookie : cookies) {
ans.append(purifyCookie(cookie));
}
return ans.toString();
}
throw new RuntimeException("登录失败,请检查用户名和密码是否正确");
}

private String purifyCookie(String cookie) {
int index = cookie.indexOf(';');
return cookie.substring(0, index + 2);
}

private String getContentFromFile() throws IOException {
InputStreamReader reader = new InputStreamReader(Covid.class.getResourceAsStream("/data.json"));
StringBuilder data = new StringBuilder();
char[] buffer = new char[1024];
if (reader.read(buffer) != -1) {
for (var ch : buffer) {
data.append(ch);
}
}
return data.toString();
}

public String[] getAccountFromFile() throws IOException {
Properties properties = new Properties();
properties.load(Covid.class.getResourceAsStream("/account.properties"));
String[] ans = new String[2];
ans[0] = properties.getProperty("username");
ans[1] = properties.getProperty("password");
return ans;
}
}

Message.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package eternal.fire.entity;

public class Message {
private int e;
private String m;

public Message() {

}

public int getE() {
return e;
}

public void setE(int e) {
this.e = e;
}

public String getM() {
return m;
}

public void setM(String m) {
this.m = m;
}

public Message(int e, String m) {
this.e = e;
this.m = m;
}
}

CovidTimerTask.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package eternal.fire.utils;

import eternal.fire.entity.Covid;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.TimerTask;

public class CovidTimerTask extends TimerTask {
private final Covid covid;

public CovidTimerTask() throws IOException {
this.covid = new Covid();
}

@Override
public void run() {
try {
this.covid.uploadData();
} catch (InterruptedException | IOException | URISyntaxException e) {
e.printStackTrace();
}
}
}

Schedule.java

1
2
3
4
5
6
7
8
9
10
11
package eternal.fire.utils;

import java.io.IOException;
import java.util.Timer;

public class Schedule {
public static void uploadDataEveryTwoHours() throws IOException {
Timer timer = new Timer();
timer.schedule(new CovidTimerTask(), 0, 1000 * 60 * 60 * 2);
}
}

Application.java

1
2
3
4
5
6
7
8
9
10
11
package eternal.fire;

import eternal.fire.utils.Schedule;

import java.io.IOException;

public class Application {
public static void main(String[] args) throws IOException {
Schedule.uploadDataEveryTwoHours();
}
}