Skip to content
This repository was archived by the owner on Dec 4, 2023. It is now read-only.

Commit 63dad47

Browse files
committed
add new features
1 parent 44998ba commit 63dad47

File tree

12 files changed

+185
-22
lines changed

12 files changed

+185
-22
lines changed

README.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,9 @@
9191
}
9292
],
9393
// 开启打卡前表单验证
94-
"formvalidation": true
94+
"formvalidation": true,
95+
// 是否开启预览功能特性
96+
"enablepreview": false
9597
}
9698
```
9799
邮箱用于打卡的通知,默认使用浙大邮箱,否则需要`mail.smtp``mail.port`参数配置为指定第三方邮箱如QQ邮箱的配置。若不配置邮箱信息,将不会邮件提醒。
@@ -235,6 +237,9 @@ powershell build.ps1 ## windows
235237
若打卡题目被更新或者你的任何信息情况有变化(如返校),请先手动打卡一次。本项目仅供学习参考。使用时请确保信息的正确性。滥用造成的后果请自行承担。
236238

237239
## 八、更新记录
240+
### v1.4.4
241+
对钉钉通知信息引入markdown格式增强,新增预览特性(看到自己的照片hhh,默认不开启预览特性,想要自我欣赏的可以设置`enablepreview: true`启用)。
242+
238243
### v1.4.3
239244
支持对健康打卡进行表单数据校验,检测健康打卡表单是否更新,当表单校验不通过,意味着健康打卡已经更新,请清除数据缓存`autocard_cache.json`文件并重启打卡程序。例如2022年4月6日浙江大学对表单有所更新。
240245

action/autocard.jar

4.55 KB
Binary file not shown.

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
<groupId>org.gcszhn</groupId>
66
<artifactId>autocard</artifactId>
7-
<version>1.4.3</version>
7+
<version>1.4.4</version>
88
<packaging>jar</packaging>
99

1010
<name>Auto Heathy Report for Zhejiang University</name>

src/main/java/org/gcszhn/autocard/AppConfig.java

+3
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ public class AppConfig implements EnvironmentAware {
5353
private JSONObject appConfig;
5454
/**是否为测试模式 */
5555
private @Getter boolean testMode = false;
56+
/**是否启用预览特性 */
57+
private @Getter boolean enablePreview = false;
5658
public AppConfig() {
5759
LogUtils.printMessage("Test mode is " + testMode, LogUtils.Level.DEBUG);
5860
try (FileInputStream fis = new FileInputStream(APP_CACHE)) {
@@ -70,6 +72,7 @@ public AppConfig() {
7072
public void setEnvironment(Environment env) {
7173
loadJSONConfig(env.getProperty("app.autoCard.config"));
7274
testMode = appConfig.getBooleanValue("testmode");
75+
enablePreview = appConfig.getBooleanValue("enablepreview");
7376

7477
// 通过系统环境变量添加单个打卡用户
7578

src/main/java/org/gcszhn/autocard/service/AutoCardJob.java

+16-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,22 @@ public static void execute(
9191
if (dingtalkSecret!=null && !dingtalkSecret.isEmpty()) {
9292
dingtalkURL = dingTalkHookService.getSignature(dingtalkSecret, dingtalkURL);
9393
}
94-
StatusCode status = dingTalkHookService.sendText(dingtalkURL, "【健康打卡通知】" + statusCode.getMessage());
94+
StatusCode status;
95+
if (statusCode.getJsonMessage() != null) {
96+
String message = String.format("### 【健康打卡通知】\n%s\n![photo](%s)",
97+
statusCode.getJsonMessage().getString("message"),
98+
statusCode.getJsonMessage().getString("photo"));
99+
100+
status = dingTalkHookService.sendMarkdown(dingtalkURL, "【健康打卡通知】", message);
101+
102+
} else {
103+
status = dingTalkHookService.sendMarkdown(
104+
dingtalkURL,
105+
"【健康打卡通知】",
106+
String.format("### 【健康打卡通知】\n%s",
107+
statusCode.getMessage()));
108+
}
109+
95110
if (status.getStatus() == 0) {
96111
LogUtils.printMessage("钉钉推送成功");
97112
} else {

src/main/java/org/gcszhn/autocard/service/AutoCardService.java

+23-4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.apache.http.message.BasicNameValuePair;
2828
import org.gcszhn.autocard.AppConfig;
2929
import org.gcszhn.autocard.utils.DigestUtils;
30+
import org.gcszhn.autocard.utils.ImageUtils;
3031
import org.gcszhn.autocard.utils.LogUtils;
3132
import org.gcszhn.autocard.utils.StatusCode;
3233
import org.jsoup.Jsoup;
@@ -207,8 +208,27 @@ public StatusCode submit(String username, String password) {
207208
case 0:{level= LogUtils.Level.INFO;break;}
208209
case 1:{level= LogUtils.Level.ERROR;break;}
209210
}
211+
JSONObject userInfo = client.getUserInfo();
212+
String message = String.format("%s,你好,今日自动健康打卡状态:%s,打卡地区为:%s(如若区域不符,请次日手动打卡更改地址)",
213+
userInfo==null? username: userInfo.getString("userName"),
214+
resp.getString("m"),
215+
area);
210216
statusCode.setStatus(status);
211-
statusCode.setMessage(client.getUserInfo().getString("userName")+"您好,"+resp.getString("m")+",打卡地区为:"+ area+"(如若区域不符,请次日手动打卡更改地址)");
217+
statusCode.setMessage(message);
218+
219+
if (appConfig.isEnablePreview()) {
220+
JSONObject jsonMessage = new JSONObject();
221+
jsonMessage.put("id", username);
222+
jsonMessage.put("name", userInfo==null? username: userInfo.getString("userName"));
223+
jsonMessage.put("message", message);
224+
String photo = client.getUserPhoto();
225+
if (photo != null) {
226+
photo = ImageUtils.toBase64(ImageUtils.resize(ImageUtils.toImage(photo), 75, 100), "gif");
227+
jsonMessage.put("photo", "data:image/gif;base64,"+photo);
228+
}
229+
statusCode.setJsonMessage(jsonMessage);
230+
}
231+
212232
LogUtils.printMessage(resp.getString("m"), level);
213233
LogUtils.printMessage("地点:"+area);
214234
return statusCode;
@@ -217,10 +237,9 @@ public StatusCode submit(String username, String password) {
217237
public void close() {
218238
try {
219239
client.close();
220-
LogUtils.printMessage("Service stopped", LogUtils.Level.INFO);
221-
240+
System.out.println("AutoCardService stopped");
222241
} catch (Exception e) {
223-
LogUtils.printMessage(null, e, LogUtils.Level.ERROR);
242+
e.printStackTrace();
224243
}
225244
}
226245
/**

src/main/java/org/gcszhn/autocard/service/DingTalkHookService.java

+2
Original file line numberDiff line numberDiff line change
@@ -142,5 +142,7 @@ private StatusCode checkURL(String payLoadURL) {
142142
@Override
143143
public void close() throws IOException {
144144
client.close();
145+
System.out.println("DingTalkHookService stopped");
146+
//LogUtils.printMessage("Service stopped");
145147
}
146148
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
* Copyright © 2021 <a href="mailto:zhang.h.n@foxmail.com">Zhang.H.N</a>.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (thie "License");
5+
* You may not use this file except in compliance with the license.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://wwww.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language govering permissions and
14+
* limitations under the License.
15+
*/
16+
package org.gcszhn.autocard.utils;
17+
18+
import java.awt.image.BufferedImage;
19+
import java.io.ByteArrayInputStream;
20+
import java.io.ByteArrayOutputStream;
21+
import java.io.File;
22+
import java.io.FileOutputStream;
23+
import java.util.Base64;
24+
25+
import javax.imageio.ImageIO;
26+
27+
import java.awt.Graphics2D;
28+
import java.awt.Image;
29+
30+
public class ImageUtils {
31+
public static BufferedImage resize(BufferedImage image, int width, int height) {
32+
BufferedImage newImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
33+
Image tmp = image.getScaledInstance(width, height, Image.SCALE_SMOOTH);
34+
Graphics2D g2d = newImage.createGraphics();
35+
g2d.drawImage(tmp, 0, 0, null);
36+
g2d.dispose();
37+
return newImage;
38+
}
39+
40+
public static String toBase64(BufferedImage image, String formatName) {
41+
try {
42+
return Base64.getEncoder().encodeToString(toByteArray(image, formatName));
43+
} catch (Exception e) {
44+
LogUtils.printMessage(null, e, LogUtils.Level.ERROR);
45+
}
46+
return null;
47+
}
48+
49+
public static byte[] toByteArray(BufferedImage image, String formatName) {
50+
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
51+
ImageIO.write(image, formatName , outputStream);
52+
return outputStream.toByteArray();
53+
} catch (Exception e) {
54+
LogUtils.printMessage(null, e, LogUtils.Level.ERROR);
55+
}
56+
return null;
57+
}
58+
59+
public static BufferedImage toImage(String base64) {
60+
try {
61+
return toImage(Base64.getDecoder().decode(base64));
62+
} catch (Exception e) {
63+
LogUtils.printMessage(null, e, LogUtils.Level.ERROR);
64+
}
65+
return null;
66+
}
67+
68+
public static BufferedImage toImage(byte[] byteArray) {
69+
try (ByteArrayInputStream inputStream = new ByteArrayInputStream(byteArray)) {
70+
return ImageIO.read(inputStream);
71+
} catch (Exception e) {
72+
LogUtils.printMessage(null, e, LogUtils.Level.ERROR);
73+
}
74+
return null;
75+
}
76+
77+
public static void write(BufferedImage image, String formatName, File file) {
78+
try {
79+
ImageIO.write(image, formatName, file);
80+
} catch (Exception e) {
81+
LogUtils.printMessage(null, e, LogUtils.Level.ERROR);
82+
}
83+
}
84+
85+
public static void write(byte[] byteArray, File file) {
86+
try (FileOutputStream outputStream = new FileOutputStream(file)) {
87+
outputStream.write(byteArray);
88+
} catch (Exception e) {
89+
LogUtils.printMessage(null, e, LogUtils.Level.ERROR);
90+
}
91+
}
92+
93+
public static void write(String base64, File file) {
94+
try {
95+
write(Base64.getDecoder().decode(base64), file);
96+
} catch (Exception e) {
97+
LogUtils.printMessage(null, e, LogUtils.Level.ERROR);
98+
}
99+
}
100+
}

src/main/java/org/gcszhn/autocard/utils/StatusCode.java

+4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
*/
1616
package org.gcszhn.autocard.utils;
1717

18+
import com.alibaba.fastjson.JSONObject;
19+
1820
import lombok.Data;
1921

2022
/**
@@ -28,4 +30,6 @@ public class StatusCode {
2830
private int status = 0;
2931
/**信息,可以是返回正文,也就是状态描述 */
3032
private String message = null;
33+
/**JSON格式信息,部分数据返回报文复杂,采用json格式更加合适 */
34+
private JSONObject jsonMessage = null;
3135
}

src/test/java/org/gcszhn/autocard/service/AutoCardServiceTest.java

+8-6
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package org.gcszhn.autocard.service;
1717

1818
import org.gcszhn.autocard.AppTest;
19+
import org.gcszhn.autocard.utils.StatusCode;
1920
import org.junit.After;
2021
import org.junit.Assert;
2122
import org.junit.Test;
@@ -28,32 +29,33 @@
2829
*/
2930
public class AutoCardServiceTest extends AppTest {
3031
@Autowired
31-
AutoCardService autoCard;
32+
AutoCardService autoCardService;
3233

3334
@Autowired
3435
DingTalkHookService dingTalkHookService;
3536
@After
3637
public void afterTest() {
37-
autoCard.close();
38+
autoCardService.close();
3839
}
3940
@Test
4041
public void getPageTest() {
4142
try {
4243
for (int i = 0; i < 2; i++) {
43-
String page = autoCard.getPage(trueZjuPassPortUser, trueZjuPassPortPass);
44+
String page = autoCardService.getPage(trueZjuPassPortUser, trueZjuPassPortPass);
4445
Assert.assertNotNull(page);
45-
Assert.assertTrue(autoCard.formValidation(page));
46+
Assert.assertTrue(autoCardService.formValidation(page));
4647
}
4748
} catch (Exception e) {
4849
e.printStackTrace();
4950
}
5051
}
5152
@Test
5253
public void getOldInfoTest() {
53-
System.out.println(autoCard.getOldInfo(trueZjuPassPortUser, trueZjuPassPortPass));
54+
System.out.println(autoCardService.getOldInfo(trueZjuPassPortUser, trueZjuPassPortPass));
5455
}
5556
@Test
5657
public void submitReportTest() {
57-
Assert.assertNotEquals(-1, autoCard.submit(trueZjuPassPortUser, trueZjuPassPortPass));
58+
StatusCode statusCode = autoCardService.submit(trueZjuPassPortUser, trueZjuPassPortPass);
59+
Assert.assertNotEquals(statusCode.getStatus(), -1);
5860
}
5961
}

src/test/java/org/gcszhn/autocard/service/DingTalkHookServiceTest.java

+13-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
package org.gcszhn.autocard.service;
1717

1818
import org.gcszhn.autocard.AppTest;
19-
19+
import org.gcszhn.autocard.utils.SpringUtils;
20+
import org.gcszhn.autocard.utils.StatusCode;
2021
import org.junit.Assert;
2122
import org.junit.Before;
2223
import org.junit.Test;
@@ -42,4 +43,15 @@ public void sendTextTest() {
4243
public void sendMarkdownTest() {
4344
Assert.assertEquals(service.sendMarkdown(encrypt_url, "杭州天气", "### 杭州天气 \n> 9度,西北风1级,空气良89,相对温度73%\n> ![screenshot](https://img.alicdn.com/tfs/TB1NwmBEL9TBuNjy1zbXXXpepXa-2400-1218.png)\n> ###### 10点20分发布 [天气](https://www.dingalk.com) \n", true).getStatus(), 0);
4445
}
46+
47+
@Test
48+
public void sendPhotoTest() {
49+
ZJUClientService clientService = SpringUtils.getBean(ZJUClientService.class);
50+
if (clientService.login(trueZjuPassPortUser, trueZjuPassPortPass)) {
51+
String photo = clientService.getUserPhoto();
52+
StatusCode statusCode = service.sendMarkdown(encrypt_url, trueZjuPassPortUser, "### "+trueZjuPassPortUser+"\n你好\n![img](data:image/gif;base64,"+photo+")");
53+
System.out.println(statusCode.getMessage());
54+
Assert.assertEquals(statusCode.getStatus(), 0);
55+
}
56+
}
4557
}

src/test/java/org/gcszhn/autocard/service/ZJUClientServiceTest.java

+9-8
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,18 @@
1515
*/
1616
package org.gcszhn.autocard.service;
1717

18+
import java.awt.image.BufferedImage;
19+
import java.io.File;
1820
import java.io.FileNotFoundException;
19-
import java.io.FileOutputStream;
2021
import java.io.IOException;
2122
import java.io.PrintWriter;
2223
import java.util.ArrayList;
23-
import java.util.Base64;
2424

2525
import com.alibaba.fastjson.JSONArray;
2626
import com.alibaba.fastjson.JSONObject;
2727

2828
import org.gcszhn.autocard.AppTest;
29+
import org.gcszhn.autocard.utils.ImageUtils;
2930
import org.jsoup.Jsoup;
3031
import org.jsoup.nodes.Document;
3132
import org.junit.After;
@@ -65,15 +66,15 @@ public void getUserPhotoTest() {
6566
if (client.login(trueZjuPassPortUser, trueZjuPassPortPass)) {
6667
String photo = client.getUserPhoto();
6768
if (photo != null) {
68-
try (
69-
FileOutputStream fileOutputStream = new FileOutputStream(trueZjuPassPortUser+".gif")) {
70-
fileOutputStream.write(Base64.getDecoder().decode(photo));
71-
} catch (Exception e) {
72-
e.printStackTrace();
73-
}
69+
ImageUtils.write(photo, new File(trueZjuPassPortUser+ "-raw.gif"));
70+
BufferedImage image = ImageUtils.toImage(photo);
71+
ImageUtils.write(image, "gif", new File(trueZjuPassPortUser+ "-t.gif"));
72+
image = ImageUtils.resize(image, 75, 100);
73+
ImageUtils.write(image, "gif", new File(trueZjuPassPortUser+ "-resize.gif"));
7474
}
7575
}
7676
}
77+
7778
@Test
7879
public void loginCourseTest() throws FileNotFoundException {
7980
String userUrl="https://courses.zju.edu.cn/user/index";

0 commit comments

Comments
 (0)