diff --git a/Main.java b/Main.java deleted file mode 100644 index ae234b5..0000000 --- a/Main.java +++ /dev/null @@ -1,131 +0,0 @@ - - -import java.util.Calendar; -import java.util.Scanner; - -public class Main { - private static int hour; - private static int endHour; - public static int getHour() { - return hour; - } - - public static void setHour(int hour) { - Main.hour = hour; - } - - public static int getEndHour() { - return endHour; - } - - public static void setEndHour(int endHour) { - Main.endHour = endHour; - } - static { - Scanner input = new Scanner(System.in); - System.out.print("请输入开始监测的小时:"); - setHour(Integer.parseInt(input.nextLine()));;// 小时 - System.out.print("请输入结束监测的小时:"); - setEndHour(Integer.parseInt(input.nextLine()));; - input.close(); - } - - /** - * 返回结果 - * submited 今日已提交 - * error 今日提交失败 - * success 今日提交成功 - * noform 未发现最新表单 - * - * @return - */ - public static String start() { - String[] fields = CpDaily.getForm(); - String result;// 存储运行的结果,邮件通知 - boolean flag; - // 判断是否有新表单,yes为有,no为没有 - if (fields[0].equals("yes")) { - flag = true; - // 判断是否提交,1为已提交,0为未提交 - if (fields[1].equals("1")) { - System.out.println("今日表单已经提交过了!"); - result = "submited"; - } else { - System.out.println("正在准备提交今日表单..."); - String schoolTaskWid = CpDaily.getSchool(fields); - String message = CpDaily.submit(fields, schoolTaskWid, Data.address); - // 判断是否提交成功 - if (message.equals("SUCCESS")) { - System.out.println("今日表单已成功提交!"); - result = "success"; - } else { - System.out.println("今日表单提交失败,失败报告->" + message); - result = "error"; - } - } - } else { - System.out.println("尚未发布最新表单!"); - result = "noform"; - } - return result; - - } - - public static void main(String[] args) throws Exception { - //开启提交线程 - new Thread(()->{ - Calendar c; - System.out.println("正在运行..."); - boolean flag;// 若监测并成功提交,则true;若未监测到发布表单,则false - while (true) { - c = Calendar.getInstance(); - String result = null; - int sleepHour=0; - if (c.get(Calendar.HOUR_OF_DAY) >= getHour()&&c.get(Calendar.HOUR_OF_DAY)=getEndHour()) { - result="submited"; - } - /* - * 若success或者error或者submited,则等到第二天的时间再执行 - * 若noform,则每隔1小时查询是否发布新表单 - */ - if ("success".equals(result)) { - System.out.print(SendMail.send(new String[] { "今日校园问卷提交通知", "今日表单提交结果:成功!" })); - sleepHour=24-c.get(Calendar.HOUR_OF_DAY)+getHour(); - System.out.println("程序休眠"+sleepHour+"小时后运行"); - } else if ("error".equals(result)) { - System.out.print(SendMail.send(new String[] { "今日校园问卷提交通知", "今日表单提交结果:失败。请手动提交" })); - sleepHour=24-c.get(Calendar.HOUR_OF_DAY)+getHour(); - System.out.println("程序休眠"+sleepHour+"小时后运行"); - } else if ("noform".equals(result)) { - sleepHour=1; - System.out.println("程序休眠"+sleepHour+"小时后运行"); - } else if ("submited".equals(result)) { - sleepHour=24-c.get(Calendar.HOUR_OF_DAY)+getHour(); - System.out.println("程序休眠"+sleepHour+"小时后运行"); - } - try { - Thread.sleep(1000*60*60*sleepHour); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - } - }).start(); - //开启保持会话线程 - new Thread(()->{ - while(true) { - HttpUtil.sendGet(Data.keepingUrl,Data.getHeaders()); - try { - Thread.sleep(1000*60*10); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - }).start(); - - } -} diff --git a/README.md b/README.md index f11d3e2..3615fc4 100644 --- a/README.md +++ b/README.md @@ -1,320 +1,11 @@ -# 使用的话,只需要修改Data.java即可 +# 使用的话,只需要修改collection.properties即可。 -站在巨人的肩膀上,我所写的东西,也会开源分享出来! +适用于所有学校。 -授人以鱼不如授人以渔,我把思路分享出来。 +思路看篇文章[今日校园实现自动监测并提交最新表单](https://meethigher.top/blog/2020/cpdaily-automation/) -截止到5月11日,已经完美运行三天了。各种小bug也已修复。 +历史源码 -源码放在这里[今日校园实现自动检测并提交最新表单](https://github.com/meethigher/cpdaily-submit),思路的话也可以直接访问我[博客](https://meethigher.top/blog/2020/cpdaily-automation/) +* [1.0](https://github.com/meethigher/cpdaily-submit/tree/1.0) +* [2.0](https://github.com/meethigher/cpdaily-submit/tree/2.0) -# 一、抓包(重点) - -## 1.1 如何抓包 - -Fiddler4电脑端与手机端抓包的教程,我不多bb了。点这个[链接](https://blog.csdn.net/c406495762/article/details/76850843)里面有具体步骤,这个大佬是专门学习机器学习的,他的博客放到[这里](https://cuijiahua.com/)。 - -一开始,我是用的Fiddler4来进行抓包的,但是涉及到ssl-pinning的问题。导致抓包失败,也就是抓取过程中,一堆灰色链接。同时,手机上的网路也会被断开。 - -之后,我就开始考虑,要不用手机抓包,就下载了[HttpCannary](https://github.com/MegatronKing/HttpCanary),HttpCanary有普通版和高级版之分,建议下载高级版,同样会遇到ssl-pinning的问题,具体解决方法请移步到[系统证书的安装,解决APP抓不到包](https://www.bilibili.com/video/BV1Qe411s7q9?from=search&seid=10930251094898400074),下载软件点[这里](https://lanzous.com/b0c2a09rg) - -## 1.2 我的解决方法 - -此节是废话,请略过。 - -我一开始用幸运破解器,很幸运的是,虽然显示破解授权失败,但打开的时候,发现能用了。 - -下一步,就是安装系统证书了,我就把手机root了,我的手机是小米的,直接root就行。 - -但是,还是在安装系统证书的过程中出了问题,不能往系统里面移动证书,原因是没有权限。 - -后来百度了一下,发现,MIUI的root权限,从Android7之后,就没有完整的root权限了。除非刷第三方系统。 - -但是我又舍不得自己的MIUI12。 - -接下来,就准备用模拟器了,我下载的是[逍遥安卓模拟器](http://www.xyaz.cn/)。安卓的是4.4版本系统,刷入了[xposed框架](http://xposed.appkg.com/),安装了[justtrustme模块](https://github.com/Fuzion24/JustTrustMe)。 - -然后,打开Fiddler抓包,Yes! - -有了Cpdaily-Extension跟MOD_AUTH_CAS这两条数据,就能模拟提交了。 - -抓包问题就此解决。耗费了我一整天的时间 - -# 二、Java模拟get跟post请求 - -这个算是套模板吧,都是这个套路,直接上代码。不要拿来就用,还是根据实际情况进行修改的。 - -```java -/** - * HttpUtil类 - * @author kit chen - * @description 用来模拟发送post请求 - */ -public class HttpUtil { - public static String sendPost(String url, String param,Map headers) { - BufferedWriter out = null; - BufferedReader in = null; - String result = ""; - try { - URL realUrl = new URL(url); - URLConnection conn = realUrl.openConnection(); - Set> set=headers.entrySet(); - for(Entry header:set) { - conn.setRequestProperty(header.getKey(), header.getValue()); - } - conn.setDoOutput(true); - conn.setDoInput(true); - out = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), "utf-8")); - out.write(param); - out.flush(); - in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8")); - String line; - while ((line = in.readLine()) != null) { - result += line; - } - } catch (Exception e) { - System.out.println("发送 POST 请求出现异常!" + e); - e.printStackTrace(); - } finally { - try { - if (out != null) { - out.close(); - } - if (in != null) { - in.close(); - } - } catch (IOException ex) { - ex.printStackTrace(); - } - } - return result; - } -} -``` - -# 三、模拟请求中的问题 - -通过抓包获取了请求头跟请求参数,请求参数还好说。 - -在抓取请求头的时候,遇到了点问题。 - -通过测试发现,如果想要成功提交内容,需要Cpdaily-Extension跟MOD_AUTH_CAS。 - -如果设备不去主动退出的话,Cpdaily-Extension是会**一直存在有效**的。类似的像QQ也是这样的。我在抓取Cpdaily-Extension的过程中,尝试访问各种页面,但是都没法获取到这个的值。哪怕是在登录的时候,也没有这个参数。只有在提交的时候,才能抓取到。 - -像MOD_AUTH_CAS这个的值,类似于session,是有有效期的。我目前还没有测试一直让这个东西保持有效。这个值,大概6个小时左右,就会失效了,需要重新登录网页获取。 - -问了大佬,好像是涉及到了[cas单点登录](https://blog.csdn.net/anumbrella/article/details/80821486)的知识,这块我也不懂。学! - -# 四、监测表单并返回表单号 - -今日校园有个获取今日最新表单的接口,如果没有的话,里面某个数据会是个空数组。 - -接口`/wec-counselor-collector-apps/stu/collector/queryCollectorProcessingList` - -post的请求参数`{"pageSize": 6,"pageNumber": 1}` - -这个pageSize是指返回几条数据,响应请求中,我记得返回的json字符串,最多就只有6个参数,所以这个传个6就行了。大于等于6 - -返回的内容 - -```json -{ - "code": "0", - "message": "SUCCESS", - "datas": { - "totalSize": 0, - "pageSize": 6, - "pageNumber": 1, - "rows": [ - "wid":"xx", - "formWid":"xx", - "isHandled":"0" - ... - ] - } -} -``` - -我们要的就是这个wid、formWid跟isHandled。isHandled表示是否提交,非0为提交。 - -监测到有rows有数据,并且isHandled未提交的时候,我们就可以进行模拟提交了。 - -# 五、获取学校表单号 - -这个还有一个坑就是,每天的学校的表单号schoolTaskWid不是固定的,由此,我们就需要来模拟请求来获取schoolTaskWid - -接口`/wec-counselor-collector-apps/stu/collector/detailCollector` - -post请求参数 `{"collectorWid": 传进来第三步获取的collectWid}` - -> 注意: -> -> 这sb接口开发者,一开始定义的是collectWid,结果后面又成了collectorWid,一开始在这边把我给坑了,需要注意。 -> -> 这个接口获取的是collectorWid,第三步获取的是collectWid,其实他俩是一个东西。 - -大致的返回内容 - -```json -{ - "code": "0", - "message": "SUCCESS", - "datas": { - "collector": { - "wid": "8888", - "formWid": "164", - "priority": "5", - "endTime": "8888-88-88 88:00:00", - "currentTime": "8888-88-88 88:00:00", - "schoolTaskWid": "8888", - "isConfirmed": 1, - "senderUserName": "牛逼学院(牛逼老师)", - "createTime": "8888-88-88 88:00:00", - "attachmentUrls": null, - "attachmentNames": null, - "attachmentSizes": null, - "isUserSubmit": 1, - "fetchStuLocation": true, - "address": "xx省xx市xx县" - //这个根据地图上面的为准,大致就是省市县 - }, - "form": { - "wid": "164", - "formTitle": "8月8日学生身体健康状况调查", - "formContent": "https://wecres.cpdaily.com/counselor/1076158768111098/content/d1c0daf5604af56fbccfadaf28cdbd82.html", - "backReason": null, - "isBack": 0, - "attachments": [] - } - } -} -``` - -这里我们需要获取schoolTaskWid。 - -# 六、获取详细表单 - -今日校园还有一条验证就是每次请求的表的id,以及表选项的id都是变化的。 - -所有,我们还需要抓取表的详细表单。 - -接口`/wec-counselor-collector-apps/stu/collector/getFormFields` - -参数`{"pageSize":30,"pageNumber":1,"formWid":formWid,"collectorWid":collectorWid}` - -返回的内容,依你们老师的设定为准,不放结果了。 - -# 七、模拟Post请求提交 - -## 7.1 思路 - -通过上面,我们获取到了formWid,collectWid,schoolTaskWid,address,form。 - -接下来,我们构造出post的json字符串请求体。 - -发送! - -成功! - -## 7.2 扩展-邮件通知 - -如果提交成功,或者提交失败。都会发通知邮件给我。 - -但是,试了几次,经常报错`554 DT:SPM`,也就是被当做垃圾邮件驳回了。 - -尝试了好几个邮箱,像139,163,qq邮箱,都会有这个问题,网上说设置端口啊,不要25,要465...开启ssl...等等 - -如果涉及到敏感词,什么签到、自动,仍然没有一个奏效的,都没当成垃圾邮件处理。 - -刚好看到一个大佬写的博客,建议用腾讯企业邮箱,试了一下,果然ok了。 - -[记录一次Could not connect to SMTP host: smtp.163.com, port: 25的解决办法](https://blog.csdn.net/qq_38410730/article/details/86538298?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1) - -> 腾讯云或者阿里云,是默认禁用25端口的 - -我附上发邮件的代码 - -```java -public class SendMail { - public static String send(String[] mail) { - Properties properties = new Properties(); - properties.put("mail.transport.protocol", "smtp");// 连接协议 - properties.put("mail.smtp.host", "smtp.exmail.qq.com");// 主机名 - properties.put("mail.smtp.port", "587");// 端口号 - properties.put("mail.smtp.auth", "true");//设置smtp是否需要认证 - properties.put("mail.smtp.ssl.enable", "true");// 设置是否使用ssl安全连接 ---一般都使用 - properties.put("mail.debug", "false");// 设置是否显示debug信息 true 会在控制台显示相关信息 - try{ - Session session = Session.getInstance(properties); - Message message = new MimeMessage(session); - message.setFrom(new InternetAddress("xxxxxxxxx@xxxxx.onexmail.com")); - message.setRecipient(Message.RecipientType.TO, new InternetAddress("meethigher@qq.com")); - message.setSubject(mail[0]); - message.setText(mail[1]); - message.setSentDate(new Date()); - Transport transport = session.getTransport(); - transport.connect("xxxxxxxxx@xxxxxx.onexmail.com", "xxxxxx");//登录发信账号 - transport.sendMessage(message, message.getAllRecipients()); - transport.close(); - return "邮件发送成功"; - }catch (Exception e){ - return "邮件发送失败"; - } - } -} -``` - -## 7.3 运行结果 - -去我博客看吧 - -# 八、总结 - -## 8.1 感谢大佬 - -[python版今日校园自动签到、填表](https://www.cnblogs.com/FSHOU/p/12425456.html) - -[python版今日校园自动填报脚本](https://github.com/Itswag/cpdaily_submit) - -[java定时刷新网页](https://www.jianshu.com/p/c6059b265dd0) - -[手机抓包教程第四节——系统证书的安装,解决APP抓不到包](https://www.bilibili.com/video/BV1Qe411s7q9?from=search&seid=6692535577953796826) - -[记录一次Could not connect to SMTP host: smtp.163.com, port: 25的解决办法](https://blog.csdn.net/qq_38410730/article/details/86538298?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1) - -[java抓取网页指定元素/内容](https://blog.csdn.net/yfx000/article/details/56831023) - -[模拟登陆系列](https://github.com/CharlesPikachu/DecryptLogin) - -[QQ空间模拟登录](https://mp.weixin.qq.com/s/Awnj0x_E7XJtbOW_7OBwbA) - -还是那句话,站在巨人的肩膀上 - -## 8.2 个人收获 - -连着两天,早上5点就起。 - -因为这个是学校的老师发的表单,我没有老师权限,没法模拟。 - -所以,只能,每天早起,在表单未提交之前,进行测试。这也是最难受的一点。 - -今天专业课考试,我当时写代码写得正在兴头上,结果作业没给交上去。估计这学期也就考个60分吧。无所谓了,反正我也不是学霸,计较个锤子。而且,我这学期,也都没咋听课,天天在家里就知道玩。每次都下定决心好好学习,结果,嘿嘿... - -总得来说,抓包还是很关键的。 - -这个博客算是整理整个的思路,如果思路看明白了,那么,实现这样的功能就不难了。 - -我看网上也有不少的类似程序,但是大多数是Python开发的,确实,Python在处理数据的时候,很舒服,给我的感觉,就是跟JavaScript一样,就是舒服。PHP如果实现这个功能的话,也会比较轻松。 - -由于我现在正在学java,还没学透,正好可以拿这个练练手。毕竟,java就像是我的初恋,虽然她身材很臃肿,但我依然爱她啊! - -处理过程中,真的感觉**人生苦短,多用python**。 - -像这样的功能,好多编程语言都能实现,Java不是不能,只是太繁琐了。 - -如果我再次写这个的话,首选Python,其次Nodejs。 - -在分层方面,还是觉得自己做地不太好,像学过的继承多态,我在处理的过程中,就是一直在硬写、闷头写。自己的代码也能看得出毛病来,但是想优化,却又不知从何改起。一方面,是对学过的东西,没有彻底理解;另一方面,也是自己的项目经验太少了。 - -一定要花时间,弥补这方面的不足! diff --git a/SendMail.java b/SendMail.java deleted file mode 100644 index 8a99670..0000000 --- a/SendMail.java +++ /dev/null @@ -1,44 +0,0 @@ - - -import java.util.Date; -import java.util.Properties; - -import javax.mail.Message; -import javax.mail.Session; -import javax.mail.Transport; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeMessage; - -/** - * - * SendMailû֪ͨ - * @author kit chen - * - */ -public class SendMail { - public static String send(String[] mail) { - Properties properties = new Properties(); - properties.put("mail.transport.protocol", "smtp");// Э - properties.put("mail.smtp.host", "smtp.exmail.qq.com");// - properties.put("mail.smtp.port", "587");// ˿ں - properties.put("mail.smtp.auth", "true");//smtpǷҪ֤ - properties.put("mail.smtp.ssl.enable", "true");// Ƿʹsslȫ ---һ㶼ʹ - properties.put("mail.debug", "false");// ǷʾdebugϢ true ڿ̨ʾϢ - try{ - Session session = Session.getInstance(properties); - Message message = new MimeMessage(session); - message.setFrom(new InternetAddress(Data.fromMail)); - message.setRecipient(Message.RecipientType.TO, new InternetAddress(Data.toMail)); - message.setSubject(mail[0]); - message.setText(mail[1]); - message.setSentDate(new Date()); - Transport transport = session.getTransport(); - transport.connect(Data.fromMail, Data.fromMailPw);//¼˺ - transport.sendMessage(message, message.getAllRecipients()); - transport.close(); - return "ʼͳɹ!"; - }catch (Exception e){ - return "ʼʧ!"; - } - } -} diff --git a/activation.jar b/lib/activation.jar similarity index 100% rename from activation.jar rename to lib/activation.jar diff --git a/commons-beanutils-1.8.0.jar b/lib/commons-beanutils-1.8.0.jar similarity index 100% rename from commons-beanutils-1.8.0.jar rename to lib/commons-beanutils-1.8.0.jar diff --git a/commons-collections-3.2.1.jar b/lib/commons-collections-3.2.1.jar similarity index 100% rename from commons-collections-3.2.1.jar rename to lib/commons-collections-3.2.1.jar diff --git a/commons-lang-2.4.jar b/lib/commons-lang-2.4.jar similarity index 100% rename from commons-lang-2.4.jar rename to lib/commons-lang-2.4.jar diff --git a/commons-logging.jar b/lib/commons-logging.jar similarity index 100% rename from commons-logging.jar rename to lib/commons-logging.jar diff --git a/ezmorph-1.0.6.jar b/lib/ezmorph-1.0.6.jar similarity index 100% rename from ezmorph-1.0.6.jar rename to lib/ezmorph-1.0.6.jar diff --git a/lib/fastjson-1.2.70.jar b/lib/fastjson-1.2.70.jar new file mode 100644 index 0000000..95487d7 Binary files /dev/null and b/lib/fastjson-1.2.70.jar differ diff --git a/json-lib-2.4-jdk15.jar b/lib/json-lib-2.4-jdk15.jar similarity index 100% rename from json-lib-2.4-jdk15.jar rename to lib/json-lib-2.4-jdk15.jar diff --git a/jsoup-1.13.1.jar b/lib/jsoup-1.13.1.jar similarity index 100% rename from jsoup-1.13.1.jar rename to lib/jsoup-1.13.1.jar diff --git a/mail.jar b/lib/mail.jar similarity index 100% rename from mail.jar rename to lib/mail.jar diff --git a/org.apache.commons.httpclient-3.1.jar b/lib/org.apache.commons.httpclient-3.1.jar similarity index 100% rename from org.apache.commons.httpclient-3.1.jar rename to lib/org.apache.commons.httpclient-3.1.jar diff --git a/src/auto_release/Config.java b/src/auto_release/Config.java new file mode 100644 index 0000000..58dabc9 --- /dev/null +++ b/src/auto_release/Config.java @@ -0,0 +1,71 @@ +package auto_release; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +/** + * + * Config ȡļ + * + * @author kit chen + * @github https://github.com/meethigher + * @blog https://meethigher.top + * + */ +public class Config { + private static String host; + private static String id; + private static String poi; + private static String tomail; + private static String fromail; + private static String fromailPw; + private static String key; + public static Properties pro; + static { + ClassLoader cl = Config.class.getClassLoader(); + InputStream is = cl.getResourceAsStream("collection.properties"); + try { + pro = new Properties(); + pro.load(is); + host = pro.getProperty("host"); + id = pro.getProperty("id"); + poi = pro.getProperty("poi"); + tomail = pro.getProperty("tomail"); + fromail = pro.getProperty("fromail"); + fromailPw = pro.getProperty("fromailPw"); + key = pro.getProperty("key"); + } catch (IOException e) { + System.out.println("ȡļִ"); + e.printStackTrace(); + } + } + + public static String getHost() { + return host; + } + + public static String getId() { + return id; + } + + public static String getPoi() { + return poi; + } + + public static String getTomail() { + return tomail; + } + + public static String getFromail() { + return fromail; + } + + public static String getFromailPw() { + return fromailPw; + } + + public static String getKey() { + return key; + } +} diff --git a/CpDaily.java b/src/auto_release/CpDaily.java similarity index 81% rename from CpDaily.java rename to src/auto_release/CpDaily.java index 634bfbc..bce8b42 100644 --- a/CpDaily.java +++ b/src/auto_release/CpDaily.java @@ -1,4 +1,4 @@ - +package auto_release; import java.util.ArrayList; @@ -6,43 +6,33 @@ import net.sf.json.JSONObject; /** - * CpDaily࣬йͨӿڻȡݵһϵ󷽷 * + * CpDaily Ϣһϵв + * * @author kit chen + * @github https://github.com/meethigher + * @blog https://meethigher.top * */ public class CpDaily { - /** - * postύؽ - * - * @param fields - * @param schoolTaskWid - * @param address - * @return - */ - public static String submit(String[] fields, String schoolTaskWid, String address) { - String formFields = getFields(fields); - String param = new Form(fields[3], address, fields[2], schoolTaskWid, formFields).toString(); - String result = HttpUtil.sendPost(Data.submitForm, param, Data.getSubHeaders()); - return JSONObject.fromObject(result).get("message").toString(); - } /** - * ȡؾıID + * ȡرϢ * * @return */ public static String[] getForm() { String todayData = HttpUtil.sendPost(Data.queryCollector, "{\"pageSize\": 6,\"pageNumber\": 1}", Data.getSubHeaders()); + System.out.println(todayData); JSONArray todayForm = null; try { + // Ϣ todayForm = JSONObject.fromObject(todayData).getJSONObject("datas").getJSONArray("rows"); } catch (Exception e) { System.out.println("ȡϢʧܣֹ¼ǷʧЧ"); System.exit(0); } - String flag;// flagжϱβѯǷ String isHandled = "", collectWid = "", formWid = ""; if (todayForm.size() < 1) {// û @@ -59,13 +49,14 @@ public static String[] getForm() { } /** - * ȡѧУID + * ȡϸschoolTaskWid * * @param fields * @return */ public static String getSchool(String[] fields) { String param = "{\"collectorWid\":\"" + fields[2] + "\"}"; + // ϸ String todayData = HttpUtil.sendPost(Data.detailCollector, param, Data.getSubHeaders()); String todaySchool = null; try { @@ -79,7 +70,7 @@ public static String getSchool(String[] fields) { } /** - * ȡϸϢҵѧУ23ʾҴpageSize30 + * ȡϸҵѧУ23ʾҴpageSize30 * * @param fields * @return @@ -87,6 +78,7 @@ public static String getSchool(String[] fields) { public static String getFields(String[] fields) { String param = "{\"pageSize\": 30, \"pageNumber\": 1, \"formWid\": " + fields[3] + ", \"collectorWid\": " + fields[2] + "}"; + // String todayData = HttpUtil.sendPost(Data.formFields, param, Data.getHeaders()); JSONArray todayRows = null; try { @@ -99,7 +91,7 @@ public static String getFields(String[] fields) { } /** - * ˵δѡ + * ˱δѡ * * @param array * @return @@ -115,7 +107,7 @@ public static String filterFields(JSONArray array) { } /** - * fieldItemsеnullɾֻisSelected=1 + * fieldItemsеnullɾֻϹؼֵ * * @param fieldItems * @return @@ -125,12 +117,42 @@ public static String changeJsonArray(String fieldItems) { ArrayList list = new ArrayList(); for (Object o : array) { JSONObject item = JSONObject.fromObject(o); - if ("1".equals(item.get("isSelected").toString())) { + if (isSelected(item.getString("content"))) { + item.put("isSelected", 1); list.add(item); } - } return list.toString(); } + /** + * ѡйؼֵѡ + * + * @param name + * @return + */ + public static boolean isSelected(String name) { + String[] items = Data.key.split(","); + for (String i : items) { + System.out.println(i); + if (i.equals(name)) + return true; + } + return false; + } + + /** + * postύؽ + * + * @param fields + * @param schoolTaskWid + * @param address + * @return + */ + public static String submit(String[] fields, String schoolTaskWid, String address) { + String formFields = getFields(fields); + String param = new Form(fields[3], address, fields[2], schoolTaskWid, formFields).toString(); + String result = HttpUtil.sendPost(Data.submitForm, param, Data.getSubHeaders()); + return JSONObject.fromObject(result).get("message").toString(); + } } diff --git a/src/auto_release/CpdailyExtension.java b/src/auto_release/CpdailyExtension.java new file mode 100644 index 0000000..958b390 --- /dev/null +++ b/src/auto_release/CpdailyExtension.java @@ -0,0 +1,128 @@ +package auto_release; + +import java.util.Base64; +import java.util.UUID; +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import net.sf.json.JSONObject; + +/** + * + * CpdailyExtension ɼֵĹ + * + * @author kit chen + * @github https://github.com/meethigher + * @blog https://meethigher.top + * + */ +public class CpdailyExtension { + // 㷨ģʽDES3DESAESRC + private static final String MODE_ALGORITHM = "DES"; + // 㷨ı׼ת + private static final String NAME = "DES/CBC/PKCS5Padding"; + // ʽ + private static final String CHARSET = "UTF-8"; + // + private static final String TEXT = "abcde"; + // ԭʼԿ + private static final String KEY = "ST83=@XV"; + // ʼIV + private static byte[] iv = { 1, 2, 3, 4, 5, 6, 7, 8 }; + + /** + * Base64 + * + * @param bytes + * @return String + */ + public static String Base64Encrypt(byte[] bytes) { + return Base64.getEncoder().encodeToString(bytes); + } + + /** + * Base64 + * + * @param bytes + * @return byte[] + */ + public static byte[] Base64Decrypt(byte[] bytes) { + return Base64.getDecoder().decode(bytes); + } + + /** + * DES + * + * @param text + * @param key + * @param charset + * @return String Base64 + * @throws Exception + */ + public static String DESEncrypt(String text, String key, String charset) throws Exception { + // ֽͨ鹹һԿ + SecretKeySpec sks = new SecretKeySpec(key.getBytes(charset), MODE_ALGORITHM); + // ʹIV + IvParameterSpec ivPS = new IvParameterSpec(iv); + // 1.ȡӽܵ㷨 + Cipher cipher = Cipher.getInstance(NAME); + // 2.Թгʼ + cipher.init(Cipher.ENCRYPT_MODE, sks, ivPS); + // 3.üܹĽм + byte[] doFinal = cipher.doFinal(text.getBytes(charset)); + // ֹ룬ԲBase64 + return Base64Encrypt(doFinal); + + } + + /** + * DES + * + * @param text + * @param key + * @param charset + * @return String + * @throws Exception + */ + public static String DESDecrypt(byte[] text, String key, String charset) throws Exception { + // ȽBase64 + text = Base64Decrypt(text); + // ֽͨ鹹һԿ + SecretKeySpec sks = new SecretKeySpec(key.getBytes(charset), MODE_ALGORITHM); + // ʹIV + IvParameterSpec ivPS = new IvParameterSpec(iv); + // 1.ȡӽܵ㷨 + Cipher cipher = Cipher.getInstance(NAME); + // 2.Թгʼ + cipher.init(Cipher.DECRYPT_MODE, sks, ivPS); + // 3.üܹĽн + return new String(cipher.doFinal(text)); + } + + /** + * CpdailyExtension + * + * @param id + * @return String + */ + public static String generateCpdailyExtension(String id) { + JSONObject object = new JSONObject(); + object.put("systemName", "android"); + object.put("systemVersion", "11"); + object.put("model", "MI 11"); + object.put("deviceId", UUID.randomUUID().toString()); + object.put("appVersion", "8.1.11"); + // 廪ѧˮľ껪ľγȣд + object.put("lon", 116.32284422133253); + object.put("lat", 40.00301874717021); + // ѧ + object.put("userId", id); + try { + return DESEncrypt(object.toString(), KEY, CHARSET); + } catch (Exception e) { + e.printStackTrace(); + System.out.println("CpdailyExtension"); + return null; + } + } +} diff --git a/Data.java b/src/auto_release/Data.java similarity index 53% rename from Data.java rename to src/auto_release/Data.java index 5bd0009..e11225b 100644 --- a/Data.java +++ b/src/auto_release/Data.java @@ -1,61 +1,58 @@ - +package auto_release; import java.util.LinkedHashMap; import java.util.Map; /** - * 洢Լӿڵ࣬Լ޸ * + * Data + * * @author kit chen + * @github https://github.com/meethigher + * @blog https://meethigher.top * */ public class Data { + /** - * λĵص - */ - public static final String address = "йxxʡxxxx"; - /** - * ѧУhost - */ - public static final String host = "https://ccut.campusphere.net"; - /** - * session + * session */ - public static final String keepingUrl = host + "/portal/index.html"; + public static String modAuthCas = ""; /** - * ȡϢӿ + * ύʾѡĹؼ */ - public static final String detailCollector = host + "/wec-counselor-collector-apps/stu/collector/detailCollector"; + public static final String key = Config.getKey(); /** - * ѯ±ӿ + * 䣬βԣѶҵȶ */ - public static final String queryCollector = host - + "/wec-counselor-collector-apps/stu/collector/queryCollectorProcessingList"; + public static final String fromMail = Config.getFromail(); + /** - * ȡϸϢӿ + * Ѷҵ */ - public static final String formFields = host + "/wec-counselor-collector-apps/stu/collector/getFormFields"; + public static final String fromMailPw = Config.getFromailPw(); + /** - * ύ±ӿ + * ѧ */ - public static final String submitForm = host + "/wec-counselor-collector-apps/stu/collector/submitForm"; + public static final String id = Config.getId(); /** - * 䣬βԣѶҵȶ + * λĵص */ - public static final String fromMail = "xxx@xxx.onexmail.com"; + public static final String address = Config.getPoi(); /** - * Ѷҵ + * շ */ - public static final String fromMailPw = "xxx"; + public static final String toMail = Config.getTomail(); /** - * շ + * ѧУhost */ - public static final String toMail = "meethigher@qq.com"; + public static final String host = Config.getHost(); /** - * Cpdaily-ExtensionҪʵ + * ύʱõͷ * * @return */ @@ -63,28 +60,46 @@ public static Map getSubHeaders() { Map map = getHeaders(); map.put("CpdailyStandAlone", "0"); map.put("extension", "1"); - map.put("Cpdaily-Extension", - "pHOOGjwfjlaj58u9gy81uhgiydfL42LmpjgBDFcbU+kEqAptH9XxFXqW5Ao8R9c xflkajgiofj9u58ghs788fshgo3My2oySUl8QPIbvbnD/CXOa+Blv01iFxgqgiiy 5clnHfdjlaj1eifd5h/gf+zI8EhyufCpcvfysmZiHyT8NWYNQuEy1nrK Ei2LtZtKxrx+37tNQ2tRHSEI5a+HXrm2Q6Y15+0BHHyg7EjIm1kymMTOcgAm imVlgyaeFHJ05Wd2"); + map.put("Cpdaily-Extension", CpdailyExtension.generateCpdailyExtension(id)); return map; } /** - * CookieҪʵ + * ύʱõͷ * * @return */ public static Map getHeaders() { Map map = new LinkedHashMap(); - map.put("tenantId", "ccut"); map.put("User-Agent", - "Mozilla/5.0 (Linux; Android 10; MI 9 Build/QKQ1.190825.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/33.0.0.0 Mobile Safari/537.36 okhttp/3.8.1"); + "Mozilla/5.0 (Linux; Android 11; MI 11 Build/QKQ1.190825.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/33.0.0.0 Mobile Safari/537.36 okhttp/3.8.1"); map.put("Content-Type", "application/json;charset=utf-8"); - map.put("Host", "ccut.campusphere.net"); map.put("Connection", "Keep-Alive"); map.put("Accept-Encoding", "gzip"); - map.put("Cookie", - "acw_tc=76b20fef15888014645921542e22c988f6643e4fde483d65f1e96045a37fc1; MOD_AUTH_CAS=ST-iap:10146111491819107:ST:895u9820c5-01a0-4763-a33d-b0ca9c9458a1:20200506131817; CASTGC=iap-10146111491819107-TGT-87fafa55-83cf-46e2-b01b-c6c0109754a9; AUTHTGC=iap-10146111491819107-TGT-87fafa55-83cf-46e2-b01b-c6c0109754a9"); + map.put("Cookie", "MOD_AUTH_CAS=" + modAuthCas); return map; } + /** + * session + */ + public static final String keepingUrl = host + "/portal/index.html"; + /** + * ȡϢӿ + */ + public static final String detailCollector = host + "/wec-counselor-collector-apps/stu/collector/detailCollector"; + /** + * ѯ±ӿ + */ + public static final String queryCollector = host + + "/wec-counselor-collector-apps/stu/collector/queryCollectorProcessingList"; + /** + * ȡϸϢӿ + */ + public static final String formFields = host + "/wec-counselor-collector-apps/stu/collector/getFormFields"; + /** + * ύ±ӿ + */ + public static final String submitForm = host + "/wec-counselor-collector-apps/stu/collector/submitForm"; + } diff --git a/Form.java b/src/auto_release/Form.java similarity index 80% rename from Form.java rename to src/auto_release/Form.java index 6f1526b..f217824 100644 --- a/Form.java +++ b/src/auto_release/Form.java @@ -1,25 +1,28 @@ - - +package auto_release; import net.sf.json.JSONObject; /** * - * Form + * Form + * * @author kit chen - * @description ͨ࣬Ҫύjsonַʽı + * @github https://github.com/meethigher + * @blog https://meethigher.top + * */ public class Form { private String formWid; private String address; private String collectWid; private String schoolTaskWid; + private boolean uaIsCpadaily = true; private String form; public Form() { super(); } - + public Form(String formWid, String address, String collectWid, String schoolTaskWid, String form) { super(); this.formWid = formWid; @@ -36,6 +39,7 @@ public String toString() { data.put("address", address); data.put("collectWid", collectWid); data.put("schoolTaskWid", schoolTaskWid); + data.put("uaIsCpadaily", uaIsCpadaily); data.put("form", form); return data.toString(); } diff --git a/HttpUtil.java b/src/auto_release/HttpUtil.java similarity index 50% rename from HttpUtil.java rename to src/auto_release/HttpUtil.java index da42144..9f1321a 100644 --- a/HttpUtil.java +++ b/src/auto_release/HttpUtil.java @@ -1,4 +1,4 @@ - +package auto_release; import java.io.BufferedReader; import java.io.BufferedWriter; @@ -13,53 +13,55 @@ import java.util.Set; /** - * HttpUtil + * + * HttpUtil + * * @author kit chen - * @description ģⷢ + * @github https://github.com/meethigher + * @blog https://meethigher.top + * */ public class HttpUtil { - public static String sendGet(String url,Map headers) { - String result = ""; - BufferedReader in = null; - try { - String urlNameString = url; - URL realUrl = new URL(urlNameString); - URLConnection conn = realUrl.openConnection(); - Set> set=headers.entrySet(); - for(Entry header:set) { + public static String sendGet(String url, Map headers) { + String result = ""; + BufferedReader in = null; + try { + URL realUrl = new URL(url); + URLConnection conn = realUrl.openConnection(); + Set> set = headers.entrySet(); + for (Entry header : set) { conn.setRequestProperty(header.getKey(), header.getValue()); } - conn.connect(); - in = new BufferedReader(new InputStreamReader( - conn.getInputStream(),"utf-8")); - String line; - while ((line = in.readLine()) != null) { - result += line; - } - } catch (Exception e) { - System.out.println("GET쳣" + e); - e.printStackTrace(); - } - finally { - try { - if (in != null) { - in.close(); - } - } catch (Exception e2) { - e2.printStackTrace(); - } - } - return result; - } - public static String sendPost(String url, String param,Map headers) { + conn.connect(); + in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8")); + String line; + while ((line = in.readLine()) != null) { + result += line; + } + } catch (Exception e) { + System.out.println("GET쳣" + e); + e.printStackTrace(); + } finally { + try { + if (in != null) { + in.close(); + } + } catch (Exception e2) { + e2.printStackTrace(); + } + } + return result; + } + + public static String sendPost(String url, String param, Map headers) { BufferedWriter out = null; BufferedReader in = null; String result = ""; try { URL realUrl = new URL(url); URLConnection conn = realUrl.openConnection(); - Set> set=headers.entrySet(); - for(Entry header:set) { + Set> set = headers.entrySet(); + for (Entry header : set) { conn.setRequestProperty(header.getKey(), header.getValue()); } conn.setDoOutput(true); diff --git a/src/auto_release/Main.java b/src/auto_release/Main.java new file mode 100644 index 0000000..2b03c91 --- /dev/null +++ b/src/auto_release/Main.java @@ -0,0 +1,110 @@ +package auto_release; + +import java.util.Calendar; +import java.util.Date; +import java.util.Scanner; + +/** + * + * Main + * + * @author kit chen + * @github https://github.com/meethigher + * @blog https://meethigher.top + * + */ +public class Main { + private static int sh; + private static int eh; + static { + System.out.println("ȡļ.."); + System.out.println("ѧţ"+Data.id); + System.out.println("ַ"+Data.address); + Scanner scanner = new Scanner(System.in); + System.out.print("MOD_AUTH_CAS"); + Data.modAuthCas = scanner.nextLine(); + System.out.print("뿪ʼСʱ"); + sh = scanner.nextInt(); + System.out.print("Сʱ"); + eh = scanner.nextInt(); + scanner.close(); + System.out.println("2021-01-06 05:37汾..."); + } + + public static String submit() { + String[] form = CpDaily.getForm(); + if ("yes".equals(form[0])) { + if ("1".equals(form[1])) { + System.out.println("Ѿύ"); + return "submited"; + } else { + String schoolTaskWid = CpDaily.getSchool(form); + String message = CpDaily.submit(form, schoolTaskWid, Data.address); + if ("SUCCESS".equals(message)) { + System.out.println("ձѳɹύ"); + System.out.println(SendMail.send(new String[] { "ʾύɹ֪ͨ", "ʱ䣺" + new Date().toLocaleString() + + "\n" + "ѧţ" + Data.id + "\nַ" + Data.address + "\nύؼ֣" + Data.key })); + return "success"; + } else { + System.out.println("ձύʧܣʧܱ->" + message); + return "error"; + } + } + } else { + System.out.println("δ±"); + return "noform"; + } + } + + /* + * ȥ1ȥеʱ + */ + public static int getDelay(String result, Calendar c) { + int delay; + if ("success".equals(result) || "submited".equals(result) || "error".equals(result)) { + delay = 1000 * 60 * 60 * 24 - 1000 * 1; + } else if ("noform".equals(result)) { + delay = 1000 * 60 * 30; + } else { + delay = (24 - c.get(Calendar.HOUR_OF_DAY) + sh) * 60 * 60 * 1000; + } + System.out.println("" + delay / 1000 / 60 + "Ӻٴִ"); + return delay; + } + + public static void main(String[] args) { + // ֻỰ߳ + new Thread(() -> { + while (true) { + HttpUtil.sendGet(Data.keepingUrl, Data.getHeaders()); + try { + Thread.sleep(1000 * 60 * 10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }).start(); + // ؼ߳ + new Thread(() -> { + Calendar c; + String result = null; + boolean flag = false; + while (true) { + c = Calendar.getInstance(); + int currentHour = c.get(Calendar.HOUR_OF_DAY); + if (sh <= currentHour && currentHour <= eh) { + flag = true; + } else { + flag = false; + } + if (flag) + result = submit(); + try { + Thread.sleep(getDelay(result, c)); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }).start(); + } +} diff --git a/src/auto_release/SendMail.java b/src/auto_release/SendMail.java new file mode 100644 index 0000000..2bee028 --- /dev/null +++ b/src/auto_release/SendMail.java @@ -0,0 +1,56 @@ +package auto_release; + +import java.util.Date; +import java.util.Properties; + +import javax.mail.Message; +import javax.mail.Session; +import javax.mail.Transport; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeMessage; + + +/** + * + * SendMail + * + * @author kit chen + * @github https://github.com/meethigher + * @blog https://meethigher.top + * + */ +public class SendMail { + public static String send(String[] mail) { + Properties properties = new Properties(); + properties.put("mail.transport.protocol", "smtp");// Э + + // Ѷҵ䣬ʹ + // properties.put("mail.smtp.host", "smtp.exmail.qq.com");// + // properties.put("mail.smtp.port", "587");// ˿ں + + // ҵ䣬https://developer.aliyun.com/ask/6542?scm=20140722.184.2.173 + // 25˿ڷã465ͬ80 + properties.put("mail.smtp.host", "smtp.mxhichina.com");// + properties.put("mail.smtp.port", "80");// ˿ں + + properties.put("mail.smtp.auth", "true");// smtpǷҪ֤ + properties.put("mail.smtp.ssl.enable", "true");// Ƿʹsslȫ ---һ㶼ʹ + properties.put("mail.debug", "false");// ǷʾdebugϢ true ڿ̨ʾϢ + try { + Session session = Session.getInstance(properties); + Message message = new MimeMessage(session); + message.setFrom(new InternetAddress(Data.fromMail)); + message.setRecipient(Message.RecipientType.TO, new InternetAddress(Data.toMail)); + message.setSubject(mail[0]); + message.setText(mail[1]); + message.setSentDate(new Date()); + Transport transport = session.getTransport(); + transport.connect(Data.fromMail, Data.fromMailPw);// ¼˺ + transport.sendMessage(message, message.getAllRecipients()); + transport.close(); + return "ʼͳɹ!"; + } catch (Exception e) { + return "ʼʧ!"; + } + } +} diff --git a/src/collection.properties b/src/collection.properties new file mode 100644 index 0000000..c0305d7 --- /dev/null +++ b/src/collection.properties @@ -0,0 +1,7 @@ +host=你的学校host,如https://ccut.campusphere.net +fromail=你的发件邮箱账号,如meethigher@qq.com +fromailPw=你的发件邮箱密码 +key=37.3\u2103\u4EE5\u4E0B,\u5065\u5EB7,\u5426,中文注意采用unicode编码 +id=20194583 +poi=\u4E2D\u56FD\u5C71\u4E1C\u7701\u6CF0\u5B89\u5E02\u65B0\u6CF0\u5E02,中文注意采用unicode编码 +tomail=你的收件邮箱 \ No newline at end of file