From 52571565e5032fb544ac2677bc90588b0adce5d7 Mon Sep 17 00:00:00 2001 From: praticamentetilde Date: Mon, 22 Jan 2018 19:27:15 +0100 Subject: [PATCH] Updated code for some format edge cases unnoticed Builds with maven for testing. Work on new methods for different documents. --- .gitignore | 55 ++++++++++++ .idea/compiler.xml | 18 ++++ .idea/misc.xml | 25 ++++++ .idea/modules.xml | 8 ++ .idea/modules/ProvaArgo.iml | 28 ++++++ ProvaArgo.iml | 18 ++-- pom.xml | 41 +++++++++ .../xyz/maggioni/ProvaArgo/ArgoAPI.java | 40 +++++---- .../xyz/maggioni/ProvaArgo/ArgoAPIPlugin.java | 87 ++++++++++++------- .../xyz/maggioni/ProvaArgo/ArgoException.java | 20 +++++ .../xyz/maggioni/ProvaArgo/PluginLOG.java | 20 +++++ 11 files changed, 308 insertions(+), 52 deletions(-) create mode 100644 .gitignore create mode 100644 .idea/compiler.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/modules/ProvaArgo.iml create mode 100644 pom.xml create mode 100644 src/android/xyz/maggioni/ProvaArgo/ArgoException.java create mode 100644 src/android/xyz/maggioni/ProvaArgo/PluginLOG.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b6afcf9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,55 @@ +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff: +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/dictionaries + +# Sensitive or high-churn files: +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.xml +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml + +# Gradle: +.idea/**/gradle.xml +.idea/**/libraries + +# CMake +cmake-build-debug/ +cmake-build-release/ + +# Mongo Explorer plugin: +.idea/**/mongoSettings.xml + +## File-based project format: +*.iws + +## Plugin-specific files: + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Custom +.idea/libraries +/*.jar +target diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..0b7b688 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..161cb92 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,25 @@ + + + + + + + ApexVCS + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..fe7b6fd --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/modules/ProvaArgo.iml b/.idea/modules/ProvaArgo.iml new file mode 100644 index 0000000..571e178 --- /dev/null +++ b/.idea/modules/ProvaArgo.iml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ProvaArgo.iml b/ProvaArgo.iml index 1675b9f..db178e2 100644 --- a/ProvaArgo.iml +++ b/ProvaArgo.iml @@ -1,25 +1,33 @@ - + - + + - + - + - + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..c80b06e --- /dev/null +++ b/pom.xml @@ -0,0 +1,41 @@ + + + xyz.maggioni + ProvaArgo + 0.0.1-SNAPSHOT + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + 4.0.0 + + + + org.jsoup + jsoup + 1.11.2 + + + org.json + json + 20171018 + + + cordova + org.apache + 7.0.0 + system + ${project.basedir}/org.apache.cordova-7.0.0.jar + + + \ No newline at end of file diff --git a/src/android/xyz/maggioni/ProvaArgo/ArgoAPI.java b/src/android/xyz/maggioni/ProvaArgo/ArgoAPI.java index 5829609..66e3207 100644 --- a/src/android/xyz/maggioni/ProvaArgo/ArgoAPI.java +++ b/src/android/xyz/maggioni/ProvaArgo/ArgoAPI.java @@ -22,7 +22,6 @@ import org.jsoup.Connection.*; import org.jsoup.Connection; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; -import org.apache.cordova.LOG; import java.io.IOException; import java.util.HashMap; @@ -31,14 +30,14 @@ import java.util.Map; class ArgoAPI { private ArgoAPI() { } - - private static void logResponse(Response res) throws IOException { - LOG.i("ArgoAPI", "Response URL: " + res.url()); - LOG.i("ArgoAPI","Response code: " + res.statusCode()); - LOG.i("ArgoAPI","Response status: " + res.statusMessage()); + + private static void logResponse(Response res) { + PluginLOG.i("ArgoAPI", "Response URL: " + res.url()); + PluginLOG.i("ArgoAPI", "Response code: " + res.statusCode()); + PluginLOG.i("ArgoAPI", "Response status: " + res.statusMessage()); for (Map.Entry entry : res.cookies().entrySet()) { - LOG.i("ArgoAPI","Response cookie: " + entry.getKey() + "=" + entry.getValue()); + PluginLOG.i("ArgoAPI", "Response cookie: " + entry.getKey() + "=" + entry.getValue()); } } @@ -48,12 +47,23 @@ class ArgoAPI { } } - static Document getMarksDocument(Map cookies) { + enum ArgoDocument { + MARKS("[evt=menu-servizialunno:vot|event|custom]"), + HOMEWORK("[evt=menu-serviziclasse:_idJsp25|event|submit]"), + LESSONS("[evt=menu-serviziclasse:_idJsp27|event|submit]"); + + private String backbaseDelta; + ArgoDocument(String s) { + backbaseDelta = s; + } + } + + static Document getDocument(Map cookies, ArgoDocument d) { try { Response markRes = Jsoup.connect("https://www.portaleargo.it/argoweb/famiglia/index.jsf") .cookies(cookies) .referrer("https://www.portaleargo.it/argoweb/famiglia/index.jsf") - .data("BackbaseClientDelta", "[evt=menu-servizialunno:vot|event|custom]") + .data("BackbaseClientDelta", d.backbaseDelta) .followRedirects(true) .method(Connection.Method.POST) .execute(); @@ -62,7 +72,7 @@ class ArgoAPI { logResponse(markRes); return Jsoup.parse(markRes.body().replaceAll("Â", "")); } catch (IOException e) { - e.printStackTrace(); + PluginLOG.e("ArgoAPI", e.getLocalizedMessage(), e); return null; } } @@ -77,9 +87,9 @@ class ArgoAPI { updateCookies(cookies, initRes.cookies()); logResponse(initRes); - LOG.i("ArgoAPI","Cookie init complete"); + PluginLOG.i("ArgoAPI", "Cookie init complete"); - Map params = new HashMap(); + Map params = new HashMap<>(); params.put("utente", user.getUsername()); params.put("j_password", user.getPassword()); params.put("j_username", user.getUsername() + "#" + user.getSchoolCode()); @@ -96,14 +106,14 @@ class ArgoAPI { updateCookies(cookies, loginRes.cookies()); logResponse(loginRes); - LOG.i("ArgoAPI","login complete"); + PluginLOG.i("ArgoAPI", "login complete"); Document d = loginRes.parse(); return !d.select("html > head > title").isEmpty() && "Argo - Famiglia".equalsIgnoreCase(d.select("html > head > title").first().text()); } catch (IOException e) { - e.printStackTrace(); + PluginLOG.e("ArgoAPI", e.getLocalizedMessage(), e); return false; } } @@ -121,7 +131,7 @@ class ArgoAPI { updateCookies(cookies, loginRes.cookies()); logResponse(loginRes); } catch (IOException e) { - e.printStackTrace(); + PluginLOG.e("ArgoAPI", e.getLocalizedMessage(), e); } } } diff --git a/src/android/xyz/maggioni/ProvaArgo/ArgoAPIPlugin.java b/src/android/xyz/maggioni/ProvaArgo/ArgoAPIPlugin.java index 8c10457..65c0e2c 100644 --- a/src/android/xyz/maggioni/ProvaArgo/ArgoAPIPlugin.java +++ b/src/android/xyz/maggioni/ProvaArgo/ArgoAPIPlugin.java @@ -18,16 +18,13 @@ package xyz.maggioni.ProvaArgo; -import org.apache.cordova.CordovaPlugin; -import org.apache.cordova.CallbackContext; -import org.apache.cordova.LOG; +import org.apache.cordova.*; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; -import org.jsoup.select.Elements; import java.text.SimpleDateFormat; import java.util.HashMap; @@ -37,15 +34,38 @@ import java.util.regex.Pattern; public class ArgoAPIPlugin extends CordovaPlugin { + public static void main(String... args) { + PluginLOG.useCordova = false; + + JSONArray arr = new JSONArray(); + JSONObject obj = new JSONObject(); + obj.put("username", "maggioni"); + obj.put("password", "huuu273j"); + obj.put("schoolCode", "SG26426"); + arr.put(obj); + + ArgoAPIPlugin a = new ArgoAPIPlugin(); + + try { + System.out.println(a.getMarks(arr).toString(2)); + } catch (ArgoException | JSONException e) { + e.printStackTrace(); + } + } + @Override public boolean execute(String action, final JSONArray args, final CallbackContext callbackContext) throws JSONException { if (action.equals("getMarks")) { final ArgoAPIPlugin this__ = this; - new Thread(new Runnable() { - public void run() { - this__.getMarks(args, callbackContext); + new Thread(() -> { + try { + this__.getMarks(args); + } catch (ArgoException e) { + callbackContext.error(e.getResponse()); + } catch (JSONException e1) { + callbackContext.error(e1.getLocalizedMessage()); } }).start(); @@ -54,7 +74,7 @@ public class ArgoAPIPlugin extends CordovaPlugin { return false; } - private void getMarks(JSONArray args, CallbackContext c) { + private JSONObject getMarks(JSONArray args) throws JSONException, ArgoException { JSONObject response = new JSONObject(); JSONArray subjects = new JSONArray(); @@ -69,13 +89,13 @@ public class ArgoAPIPlugin extends CordovaPlugin { jsonObject.getString("password"), jsonObject.getString("schoolCode")); - Map cookies = new HashMap(); + Map cookies = new HashMap<>(); if (!ArgoAPI.login(cookies, user)) { throw new IllegalStateException("Login on Argo failed"); } - Document marksDocument = ArgoAPI.getMarksDocument(cookies); + Document marksDocument = ArgoAPI.getDocument(cookies, ArgoAPI.ArgoDocument.MARKS); if (marksDocument == null) { throw new IllegalStateException("Failed to get marks document"); } @@ -89,24 +109,26 @@ public class ArgoAPIPlugin extends CordovaPlugin { subject.put("name", el.select("legend").first().text()); subject.put("marks", marks); + String lastDate = null; for (Element el2 : el.select("table > tbody > tr")) { - Elements cells = el2.select("td"); - Element[] cellsArr = cells.toArray(new Element[3]); - JSONObject mark = new JSONObject(); - mark.put("date", new SimpleDateFormat("yyyy-MM-dd").parse(cellsArr[1].text())); - String markStr = cellsArr[2].text(); - - Pattern regMark = Pattern.compile("Voto ((?:[Ss]critto)|(?:[Oo]rale)|(?:[Pp]ratico)) .*\\(([0-9.]+)\\)"); - Matcher m = regMark.matcher(markStr); - - if (m.find()) { - mark.put("type", m.group(1)); - mark.put("value", Double.parseDouble(m.group(2))); + Pattern p = Pattern.compile("\\d\\d\\d\\d-\\d\\d-\\d\\d"); + Matcher m2 = p.matcher(el2.text()); + if (!m2.find()) { + if (lastDate == null) throw new IllegalStateException("Date not found in: \"" + el2.text() + "\""); + // if date has not been written, assume the date is equal to the last known date + // (already in last date) } else { - throw new IllegalStateException("Regex for mark does not match with markStr \"" + markStr + "\""); + lastDate = m2.group(0); } + mark.put("date", new SimpleDateFormat("yyyy-MM-dd").parse(lastDate)); + + Pattern regMark = Pattern.compile("((?:[Ss]critto)|(?:[Oo]rale)|(?:[Pp]ratico)).*\\(([0-9.]+)\\)"); + Matcher m = regMark.matcher(el2.text()); + if (!m.find()) throw new IllegalStateException("Mark not found in: \"" + mark + "\""); + mark.put("type", m.group(1)); + mark.put("value", Double.parseDouble(m.group(2))); marks.put(mark); } @@ -117,26 +139,27 @@ public class ArgoAPIPlugin extends CordovaPlugin { ArgoAPI.logout(cookies); } catch (Exception e) { - LOG.e("ArgoAPIPlugin", e.getMessage(), e); + PluginLOG.e("ArgoAPIPlugin", e.getMessage(), e); try { response.put("success", false); response.put("subjects", new JSONArray()); response.put("message", e.getLocalizedMessage()); } catch (JSONException e1) { - LOG.e("ArgoAPIPlugin", e1.getMessage(), e1); - c.error(e1.getMessage()); + PluginLOG.e("ArgoAPIPlugin", e1.getMessage(), e1); + throw e1; } } try { if (response.get("success").equals(true)) { - c.success(response); + return response; } else { - c.error(response); + throw new ArgoException(response); } - } catch (JSONException e) { - LOG.e("ArgoAPIPlugin", e.getMessage(), e); - c.error(e.getMessage()); + } catch (JSONException | ArgoException e) { + PluginLOG.e("ArgoAPIPlugin", e.getMessage(), e); + throw e; } } -} \ No newline at end of file +} + diff --git a/src/android/xyz/maggioni/ProvaArgo/ArgoException.java b/src/android/xyz/maggioni/ProvaArgo/ArgoException.java new file mode 100644 index 0000000..fcffecf --- /dev/null +++ b/src/android/xyz/maggioni/ProvaArgo/ArgoException.java @@ -0,0 +1,20 @@ +package xyz.maggioni.ProvaArgo; + +import org.json.JSONObject; + +public class ArgoException extends Exception { + private JSONObject response; + + ArgoException(JSONObject response) { + this.response = response; + } + + public JSONObject getResponse() { + return response; + } + + @Override + public String getMessage() { + return "Marks fetch failed with the following data: "+response.toString(); + } +} diff --git a/src/android/xyz/maggioni/ProvaArgo/PluginLOG.java b/src/android/xyz/maggioni/ProvaArgo/PluginLOG.java new file mode 100644 index 0000000..2bf6385 --- /dev/null +++ b/src/android/xyz/maggioni/ProvaArgo/PluginLOG.java @@ -0,0 +1,20 @@ +package xyz.maggioni.ProvaArgo; + +import org.apache.cordova.LOG; + +public class PluginLOG { + public static boolean useCordova = true; + + public static void i(String tag, String message) { + if (useCordova) LOG.i(tag, message); + else System.out.println("INFO (" + tag + "): " + message); + } + + public static void e(String tag, String s, Throwable e) { + if (useCordova) LOG.e(tag, s, e); + else { + System.err.println("ERROR (" + tag + "): " + s); + e.printStackTrace(System.err); + } + } +}