From 4c150fa8aafd77a474de0ee97578ccf3d2c79dc0 Mon Sep 17 00:00:00 2001
From: Nitorac <nitorac.r@gmail.com>
Date: Thu, 6 May 2021 13:31:27 +0200
Subject: [PATCH] Minor fixed + added grades tab

---
 app/build.gradle                              |  20 +++---
 .../fr/nitorac/aurionweb/MainActivity.java    |  18 +++--
 .../aurionweb/aurionweb/AurionManager.java    |  67 +++++++++++++++++-
 .../aurionweb/aurionweb/AurionSession.java    |  46 ++++++++++--
 .../fragments/AurionViewFragment.java         |   4 +-
 .../fragments/calendar/CalendarFragment.java  |   1 +
 .../fragments/calendar/CalendarViewModel.java |  19 -----
 .../fragments/home/HomeViewModel.java         |  19 -----
 .../notifications/NotificationsFragment.java  |  11 ---
 .../notifications/NotificationsViewModel.java |  19 -----
 .../fragments/results/ResultsFragment.java    |  50 +++++++++++++
 app/src/main/res/drawable-anydpi/ic_grade.xml |  11 +++
 app/src/main/res/drawable-hdpi/ic_grade.png   | Bin 0 -> 436 bytes
 app/src/main/res/drawable-mdpi/ic_grade.png   | Bin 0 -> 283 bytes
 app/src/main/res/drawable-xhdpi/ic_grade.png  | Bin 0 -> 520 bytes
 app/src/main/res/drawable-xxhdpi/ic_grade.png | Bin 0 -> 1032 bytes
 ...notifications.xml => fragment_results.xml} |   2 +-
 app/src/main/res/menu/bottom_nav_menu.xml     |   4 +-
 .../main/res/navigation/mobile_navigation.xml |   6 +-
 app/src/main/res/values-fr-rFR/strings.xml    |   1 +
 app/src/main/res/values/strings.xml           |   2 +-
 build.gradle                                  |  13 ++--
 gradle.properties                             |   6 +-
 gradle/wrapper/gradle-wrapper.properties      |   4 +-
 local.properties                              |   8 +--
 25 files changed, 216 insertions(+), 115 deletions(-)
 delete mode 100644 app/src/main/java/fr/nitorac/aurionweb/fragments/calendar/CalendarViewModel.java
 delete mode 100644 app/src/main/java/fr/nitorac/aurionweb/fragments/home/HomeViewModel.java
 delete mode 100644 app/src/main/java/fr/nitorac/aurionweb/fragments/notifications/NotificationsFragment.java
 delete mode 100644 app/src/main/java/fr/nitorac/aurionweb/fragments/notifications/NotificationsViewModel.java
 create mode 100644 app/src/main/java/fr/nitorac/aurionweb/fragments/results/ResultsFragment.java
 create mode 100644 app/src/main/res/drawable-anydpi/ic_grade.xml
 create mode 100644 app/src/main/res/drawable-hdpi/ic_grade.png
 create mode 100644 app/src/main/res/drawable-mdpi/ic_grade.png
 create mode 100644 app/src/main/res/drawable-xhdpi/ic_grade.png
 create mode 100644 app/src/main/res/drawable-xxhdpi/ic_grade.png
 rename app/src/main/res/layout/{fragment_notifications.xml => fragment_results.xml} (93%)

diff --git a/app/build.gradle b/app/build.gradle
index 3c64ccb..3c67f76 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -2,13 +2,13 @@ apply plugin: 'com.android.application'
 apply plugin: 'kotlin-android'
 
 android {
-    compileSdkVersion 29
-    buildToolsVersion "30.0.2"
+    compileSdkVersion 30
+    buildToolsVersion "30.0.3"
 
     defaultConfig {
         applicationId "fr.nitorac.aurionweb"
         minSdkVersion 19
-        targetSdkVersion 29
+        targetSdkVersion 30
         versionCode 4
         versionName "1.1.2"
         multiDexEnabled true
@@ -33,18 +33,18 @@ android {
 dependencies {
     implementation fileTree(dir: "libs", include: ["*.jar"])
     implementation 'androidx.appcompat:appcompat:1.2.0'
-    implementation 'com.google.android.material:material:1.2.1'
-    implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
+    implementation 'com.google.android.material:material:1.3.0'
+    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
     implementation 'androidx.vectordrawable:vectordrawable:1.1.0'
-    implementation 'androidx.navigation:navigation-fragment:2.3.0'
-    implementation 'androidx.navigation:navigation-ui:2.3.0'
+    implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5'
+    implementation 'androidx.navigation:navigation-ui-ktx:2.3.5'
     implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
     implementation 'org.jsoup:jsoup:1.13.1'
     implementation 'com.google.code.gson:gson:2.8.6'
     implementation 'org.projectlombok:lombok:1.18.12'
     annotationProcessor 'org.projectlombok:lombok:1.18.12'
 
-    implementation "androidx.webkit:webkit:1.4.0-alpha01"
+    implementation "androidx.webkit:webkit:1.4.0"
 
     implementation 'com.github.lzyzsd:circleprogress:1.2.1'
     implementation 'com.mindorks.android:prdownloader:0.6.0'
@@ -57,9 +57,9 @@ dependencies {
     androidTestImplementation 'androidx.test.ext:junit:1.1.2'
     androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
 
-    coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.10'
+    coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
     implementation "androidx.core:core-ktx:1.3.2"
-    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"
+    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1"
     implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
 }
 repositories {
diff --git a/app/src/main/java/fr/nitorac/aurionweb/MainActivity.java b/app/src/main/java/fr/nitorac/aurionweb/MainActivity.java
index d1e48ad..b1d52c6 100644
--- a/app/src/main/java/fr/nitorac/aurionweb/MainActivity.java
+++ b/app/src/main/java/fr/nitorac/aurionweb/MainActivity.java
@@ -56,17 +56,15 @@ public class MainActivity extends AppCompatActivity {
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-            case R.id.connect_menuitem:
-                try{
-                    AurionManager.getInstance().spawnLoginDialog(this);
-                }catch (Exception e){
-                    Toast.makeText(this, "Impossible d'afficher la connexion (Erreur : " + e.getLocalizedMessage() + ")", Toast.LENGTH_LONG).show();
-                }
-                return true;
-            default:
-                return super.onOptionsItemSelected(item);
+        if (item.getItemId() == R.id.connect_menuitem){
+            try{
+                AurionManager.getInstance().spawnLoginDialog(this);
+            }catch (Exception e){
+                Toast.makeText(this, "Impossible d'afficher la connexion (Erreur : " + e.getLocalizedMessage() + ")", Toast.LENGTH_LONG).show();
+            }
+            return true;
         }
+        return super.onOptionsItemSelected(item);
     }
 
 
diff --git a/app/src/main/java/fr/nitorac/aurionweb/aurionweb/AurionManager.java b/app/src/main/java/fr/nitorac/aurionweb/aurionweb/AurionManager.java
index d4f32c3..3b99ec8 100644
--- a/app/src/main/java/fr/nitorac/aurionweb/aurionweb/AurionManager.java
+++ b/app/src/main/java/fr/nitorac/aurionweb/aurionweb/AurionManager.java
@@ -81,6 +81,33 @@ public class AurionManager {
         return respDoc;
     }
 
+    public Document reachMyResultsFromInit(AurionSession session) throws IOException, GeneralSecurityException {
+        // On charge une fois la page pour valider un affichage fictif (cote server aurion)
+        // Requête effective permettant la validation de l'authentification sur CAS
+        Connection.Response resp = Utils.wrapSSL("https://aurionweb.ensiie.fr/faces/MainMenuPage.xhtml")
+                .method(Connection.Method.POST)
+                .followRedirects(true)
+                .header("Cache-Control", "max-age=0")
+                .header("Content-Type", "application/x-www-form-urlencoded")
+                .header("Host", "aurionweb.ensiie.fr")
+                .header("Origin", "https://aurionweb.ensiie.fr")
+                .header("Referer", "https://aurionweb.ensiie.fr/")
+                .header("Upgrade-Insecure-Requests", "1")
+                .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36")
+                .cookie("JSESSIONID", session.getJSESSIONID())
+                .data("form", "form")
+                //.data("form:largeurDivCenter", "1219")
+                //.data("form:sauvegarde", "")
+                .data("form:sidebar", "form:sidebar")
+                .data("form:sidebar_menuid", session.getSubmenuResId())
+                .data("javax.faces.ViewState", session.getViewState())
+                .execute();
+        Document respDoc = resp.parse();
+        session.parseViewState(respDoc);
+
+        return respDoc;
+    }
+
     // Instancie une connection vers AurionWeb
     public Document initConnection(AurionSession session, String username, String pwd) throws IOException, GeneralSecurityException {
         session.clear();
@@ -91,7 +118,7 @@ public class AurionManager {
                 .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36")
                 .execute();
         String execution = initRes.parse().getElementsByAttributeValue("name", "execution").get(0).attr("value");
-        //Requête effective permettant la validation de l'authentification sur CAS
+
         Connection secConn = Utils.wrapSSL("https://cas.ensiie.fr/login?service=https%3A%2F%2Faurionweb.ensiie.fr%2F%2Flogin%2Fcas")
                 .method(Connection.Method.POST)
                 .followRedirects(true)
@@ -117,6 +144,44 @@ public class AurionManager {
         session.parseConnectMenuFormId(doc1);
         //On trouve l'ID du bouton Emploi du temps (pour les requêtes)
         session.parseConnectMenuId(doc1);
+        //On trouve l'ID du bouton Resultats (pour les requêtes)
+        session.parseConnectMenuResId(doc1);
+
+        return doc1;
+    }
+
+    public Document initResultsSection(AurionSession session) throws GeneralSecurityException, IOException {
+        Connection.Response tmp = Utils.wrapSSL("https://aurionweb.ensiie.fr/faces/MainMenuPage.xhtml")
+                .method(Connection.Method.POST)
+                .followRedirects(true)
+                .header("Cache-Control", "max-age=0")
+                .header("Content-Type", "application/x-www-form-urlencoded")
+                .header("Host", "aurionweb.ensiie.fr")
+                .header("Origin", "https://aurionweb.ensiie.fr")
+                .header("Referer", "https://aurionweb.ensiie.fr/")
+                .header("Faces-Request", "partial/ajax")
+                .header("Upgrade-Insecure-Requests", "1")
+                .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36")
+                .cookie("JSESSIONID", session.getJSESSIONID())
+                .data("javax.faces.partial.ajax", "true")
+                .data("javax.faces.source", session.getMenuFormId())
+                .data("javax.faces.partial.execute", session.getMenuFormId())
+                .data("javax.faces.partial.render", "form:sidebar")
+                .data(session.getMenuFormId(), session.getMenuFormId())
+                .data("webscolaapp.Sidebar.ID_SUBMENU", session.getMenuResId())
+                .data("form", "form")
+                //.data("form:largeurDivCenter", "1219")
+                //.data("form:sauvegarde", "")
+                .data("javax.faces.ViewState", session.getViewState())
+                .execute();
+        Document doc2 = tmp.parse();
+        session.parseViewState(doc2);
+        session.parseConnectSubmenuResId(doc2);
+
+        return doc2;
+    }
+
+    public Document initEdtSection(AurionSession session) throws GeneralSecurityException, IOException {
         //Requête effective permettant la validation de l'authentification sur CAS
         Connection.Response tmp = Utils.wrapSSL("https://aurionweb.ensiie.fr/faces/MainMenuPage.xhtml")
                 .method(Connection.Method.POST)
diff --git a/app/src/main/java/fr/nitorac/aurionweb/aurionweb/AurionSession.java b/app/src/main/java/fr/nitorac/aurionweb/aurionweb/AurionSession.java
index a7db5bb..afa7e38 100644
--- a/app/src/main/java/fr/nitorac/aurionweb/aurionweb/AurionSession.java
+++ b/app/src/main/java/fr/nitorac/aurionweb/aurionweb/AurionSession.java
@@ -41,11 +41,17 @@ public class AurionSession {
     private String viewState = "";
     @Setter(AccessLevel.NONE)
     private String menuFormId = "";
+
+    //Variables ID pour les Résultats
     @Setter(AccessLevel.NONE)
-    private String menuId = "";
+    private String menuResId = "";
+    @Setter(AccessLevel.NONE)
+    private String submenuResId = "";
 
     //Variables ID pour le ChoixPlanning
     @Setter(AccessLevel.NONE)
+    private String menuId = "";
+    @Setter(AccessLevel.NONE)
     private String submenuId = "";
     @Setter(AccessLevel.NONE)
     private String choixpFormId = "";
@@ -95,7 +101,7 @@ public class AurionSession {
         doc = setLastDoc(doc);
         //Maintenant on va récupérer l'ID du menu qu'on souhaite, c'est à dire Emploi du temps
         // (Oui c'est bien un menu même si on cherche une balise avec submenu_... comme classe x) (c'est aurionweb)
-        Element menuClass = doc.getElementsByAttributeValueContaining("class", "submenu_").stream().filter(e -> e.text().contains("Emploi du temps")).findFirst().orElse(null);
+        Element menuClass = doc.getElementsByAttributeValueContaining("class", "submenu_").stream().filter(e -> Utils.stripAccents(e.text()).toLowerCase().contains("emploi du temps")).findFirst().orElse(null);
         menuId = menuClass != null ? menuClass.classNames().stream().filter(c -> c.startsWith("submenu_")).findFirst().orElse("") : null;
         if (menuId == null) {
             Log.e(TAG, "Impossible de trouver un menu avec 'Emploi du temps' comme texte !");
@@ -104,10 +110,23 @@ public class AurionSession {
         return true;
     }
 
+    public boolean parseConnectMenuResId(Document doc) {
+        doc = setLastDoc(doc);
+        //Maintenant on va récupérer l'ID du menu qu'on souhaite, c'est à dire Résultats
+        // (Oui c'est bien un menu même si on cherche une balise avec submenu_... comme classe x) (c'est aurionweb)
+        Element menuClass = doc.getElementsByAttributeValueContaining("class", "submenu_").stream().filter(e -> Utils.stripAccents(e.text()).toLowerCase().trim().contains("resultat")).findFirst().orElse(null);
+        menuResId = menuClass != null ? menuClass.classNames().stream().filter(c -> c.startsWith("submenu_")).findFirst().orElse("") : null;
+        if (menuResId == null) {
+            Log.e(TAG, "Impossible de trouver un menu avec 'Résultat' comme texte !");
+            return false;
+        }
+        return true;
+    }
+
     public boolean parseConnectSubmenuId(Document doc) {
         doc = setLastDoc(doc);
         //On va maintenant trouver un ID de la forme '2_1' qui correspond à l'ID du lien "Planning d'un étudiant au choix"
-        Element liSubmenuID = Jsoup.parse(doc.getElementById("form:sidebar").text()).getElementsByTag("li").stream().filter(e -> e.childNodeSize() == 1 && Utils.stripAccents(e.text()).contains("Mon planning")).findFirst().orElse(null);
+        Element liSubmenuID = Jsoup.parse(doc.getElementById("form:sidebar").text()).getElementsByTag("li").stream().filter(e -> e.childNodeSize() == 1 && Utils.stripAccents(e.text()).toLowerCase().contains("mon planning")).findFirst().orElse(null);
         if (liSubmenuID != null) {
             String onclickAttr = liSubmenuID.child(0).attr("onclick");
             Matcher submenuMatcher = liSubmenuPattern.matcher(onclickAttr);
@@ -115,7 +134,7 @@ public class AurionSession {
                 submenuId = submenuMatcher.group(1);
                 return true;
             }else{
-                Log.e(TAG, "Impossible de trouver le submenuID dans l'attribut");
+                Log.e(TAG, "Impossible de trouver le submenuID dans l'attribut (Section Planning)");
             }
         } else {
             Log.e(TAG, "Impossible de trouver un sous menu de tag 'li' avec 'Mon planning' comme texte !");
@@ -123,6 +142,25 @@ public class AurionSession {
         return false;
     }
 
+    public boolean parseConnectSubmenuResId(Document doc) {
+        doc = setLastDoc(doc);
+        //On va maintenant trouver un ID de la forme '2_1' qui correspond à l'ID du lien "Planning d'un étudiant au choix"
+        String t = doc.getElementById("form:sidebar").text();
+        Element liSubmenuID = Jsoup.parse(t).getElementsByTag("li").stream().filter(e -> e.childNodeSize() == 1 && Utils.stripAccents(e.text()).toLowerCase().trim().contains("epreuves annee en cours")).findFirst().orElse(null);
+        if (liSubmenuID != null) {
+            String onclickAttr = liSubmenuID.child(0).attr("onclick");
+            Matcher submenuMatcher = liSubmenuPattern.matcher(onclickAttr);
+            if (submenuMatcher.find()) {
+                submenuResId = submenuMatcher.group(1);
+                return true;
+            }else{
+                Log.e(TAG, "Impossible de trouver le submenuID dans l'attribut (Section annee en cours)");
+            }
+        } else {
+            Log.e(TAG, "Impossible de trouver un sous menu de tag 'li' avec 'année en cours' comme texte !");
+        }
+        return false;
+    }
 
     public boolean parseChoixPlanningFormId(Document doc) {
         doc = setLastDoc(doc);
diff --git a/app/src/main/java/fr/nitorac/aurionweb/fragments/AurionViewFragment.java b/app/src/main/java/fr/nitorac/aurionweb/fragments/AurionViewFragment.java
index a6bebd7..447b54c 100644
--- a/app/src/main/java/fr/nitorac/aurionweb/fragments/AurionViewFragment.java
+++ b/app/src/main/java/fr/nitorac/aurionweb/fragments/AurionViewFragment.java
@@ -45,11 +45,11 @@ public abstract class AurionViewFragment extends Fragment {
     public abstract void preload();
 
     public void pageFinished(WebView view, String url){
-
+        //Overridable empty func
     }
 
     public void networkInit(AurionSession session){
-
+        //Overridable empty func
     }
 
     protected void initLoad(){
diff --git a/app/src/main/java/fr/nitorac/aurionweb/fragments/calendar/CalendarFragment.java b/app/src/main/java/fr/nitorac/aurionweb/fragments/calendar/CalendarFragment.java
index bcbb0b0..f2efe60 100644
--- a/app/src/main/java/fr/nitorac/aurionweb/fragments/calendar/CalendarFragment.java
+++ b/app/src/main/java/fr/nitorac/aurionweb/fragments/calendar/CalendarFragment.java
@@ -25,6 +25,7 @@ public class CalendarFragment extends AurionViewFragment {
     @Override
     public void networkInit(AurionSession session) {
         try {
+            AurionManager.getInstance().initEdtSection(currentSession);
             AurionManager.getInstance().reachMyEdtFromInit(currentSession);
         } catch (IOException | GeneralSecurityException e) {
             e.printStackTrace();
diff --git a/app/src/main/java/fr/nitorac/aurionweb/fragments/calendar/CalendarViewModel.java b/app/src/main/java/fr/nitorac/aurionweb/fragments/calendar/CalendarViewModel.java
deleted file mode 100644
index a6ba66c..0000000
--- a/app/src/main/java/fr/nitorac/aurionweb/fragments/calendar/CalendarViewModel.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package fr.nitorac.aurionweb.fragments.calendar;
-
-import androidx.lifecycle.LiveData;
-import androidx.lifecycle.MutableLiveData;
-import androidx.lifecycle.ViewModel;
-
-public class CalendarViewModel extends ViewModel {
-
-    private MutableLiveData<String> mText;
-
-    public CalendarViewModel() {
-        mText = new MutableLiveData<>();
-        mText.setValue("This is dashboard fragment");
-    }
-
-    public LiveData<String> getText() {
-        return mText;
-    }
-}
\ No newline at end of file
diff --git a/app/src/main/java/fr/nitorac/aurionweb/fragments/home/HomeViewModel.java b/app/src/main/java/fr/nitorac/aurionweb/fragments/home/HomeViewModel.java
deleted file mode 100644
index e0b9add..0000000
--- a/app/src/main/java/fr/nitorac/aurionweb/fragments/home/HomeViewModel.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package fr.nitorac.aurionweb.fragments.home;
-
-import androidx.lifecycle.LiveData;
-import androidx.lifecycle.MutableLiveData;
-import androidx.lifecycle.ViewModel;
-
-public class HomeViewModel extends ViewModel {
-
-    private MutableLiveData<String> mText;
-
-    public HomeViewModel() {
-        mText = new MutableLiveData<>();
-        mText.setValue("This is home fragment");
-    }
-
-    public LiveData<String> getText() {
-        return mText;
-    }
-}
\ No newline at end of file
diff --git a/app/src/main/java/fr/nitorac/aurionweb/fragments/notifications/NotificationsFragment.java b/app/src/main/java/fr/nitorac/aurionweb/fragments/notifications/NotificationsFragment.java
deleted file mode 100644
index fda5e95..0000000
--- a/app/src/main/java/fr/nitorac/aurionweb/fragments/notifications/NotificationsFragment.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package fr.nitorac.aurionweb.fragments.notifications;
-
-import fr.nitorac.aurionweb.fragments.AurionViewFragment;
-
-public class NotificationsFragment extends AurionViewFragment {
-
-    @Override
-    public void preload() {
-
-    }
-}
\ No newline at end of file
diff --git a/app/src/main/java/fr/nitorac/aurionweb/fragments/notifications/NotificationsViewModel.java b/app/src/main/java/fr/nitorac/aurionweb/fragments/notifications/NotificationsViewModel.java
deleted file mode 100644
index 56008ed..0000000
--- a/app/src/main/java/fr/nitorac/aurionweb/fragments/notifications/NotificationsViewModel.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package fr.nitorac.aurionweb.fragments.notifications;
-
-import androidx.lifecycle.LiveData;
-import androidx.lifecycle.MutableLiveData;
-import androidx.lifecycle.ViewModel;
-
-public class NotificationsViewModel extends ViewModel {
-
-    private MutableLiveData<String> mText;
-
-    public NotificationsViewModel() {
-        mText = new MutableLiveData<>();
-        mText.setValue("This is notifications fragment");
-    }
-
-    public LiveData<String> getText() {
-        return mText;
-    }
-}
\ No newline at end of file
diff --git a/app/src/main/java/fr/nitorac/aurionweb/fragments/results/ResultsFragment.java b/app/src/main/java/fr/nitorac/aurionweb/fragments/results/ResultsFragment.java
new file mode 100644
index 0000000..180e6de
--- /dev/null
+++ b/app/src/main/java/fr/nitorac/aurionweb/fragments/results/ResultsFragment.java
@@ -0,0 +1,50 @@
+package fr.nitorac.aurionweb.fragments.results;
+
+import android.util.Log;
+import android.webkit.WebView;
+import android.widget.Toast;
+
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+
+import fr.nitorac.aurionweb.aurionweb.AurionManager;
+import fr.nitorac.aurionweb.aurionweb.AurionSession;
+import fr.nitorac.aurionweb.fragments.AurionViewFragment;
+import fr.nitorac.aurionweb.fragments.home.HomeFragment;
+
+public class ResultsFragment extends AurionViewFragment {
+
+    public static final String AURION_RES_URL = "https://aurionweb.ensiie.fr/faces/LearnerNotationListPage.xhtml";
+    private boolean failed = false;
+
+    @Override
+    public void pageFinished(WebView view, String url) {
+        view.evaluateJavascript("$('#form\\\\:headerSubview\\\\:header,.divCurrentUser,.CardBigTopic,.EmptyBox20.cacherImpression').remove();$('#layout-container').css('padding-top', '0rem');$('.CardBigTopic').remove();$('.ui-column-title:contains(Date)').map(function(){return $(this).parent();}).get().forEach(function(e){ $(e).remove();});$('head').append('<style type=\"text/css\">.learnerNotationListPage .dataTable td { white-space: initial; }</style>');var grades = $('td > .ui-column-title:contains(Code)').map(function(){return {'id':$(this).parent().contents().get(1).nodeValue, 'el':$(this).parent().parent()[0]};}).get().sort(function(a,b){var an = parseInt(a['id'].replace(/(^.+?)(\\d+).*$/i,'$2'));var bn = parseInt(b['id'].replace(/(^.+?)(\\d+).*$/i,'$2'));return an==bn?a['id'].localeCompare(b['id']):bn-an;});var table = $('tbody.ui-datatable-data')[0];table.innerHTML='';grades.forEach(function(e){table.append(e['el'])});", paRes -> {});
+    }
+
+    @Override
+    public void networkInit(AurionSession session) {
+        try {
+            AurionManager.getInstance().initResultsSection(currentSession);
+            AurionManager.getInstance().reachMyResultsFromInit(currentSession);
+        } catch (IOException | GeneralSecurityException e) {
+            e.printStackTrace();
+            failed = true;
+            Log.e(getClass().getSimpleName(), "Impossible de charger le chemin vers les résultats (" + e.getLocalizedMessage() + ")");
+            if(getActivity() != null){
+                getActivity().runOnUiThread(() -> {
+                    Toast.makeText(getContext(), "Impossible de charger le chemin vers les résultats (" + e.getLocalizedMessage() + ")", Toast.LENGTH_LONG).show();
+                    webView.loadUrl(HomeFragment.AURIONURL, getHeaders());
+                });
+            }
+
+        }
+    }
+
+    @Override
+    public void preload() {
+        if(!failed){
+            webView.loadUrl(AURION_RES_URL, getHeaders());
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/res/drawable-anydpi/ic_grade.xml b/app/src/main/res/drawable-anydpi/ic_grade.xml
new file mode 100644
index 0000000..3095df4
--- /dev/null
+++ b/app/src/main/res/drawable-anydpi/ic_grade.xml
@@ -0,0 +1,11 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24"
+    android:tint="#FFFFFF"
+    android:alpha="0.8">
+  <path
+      android:fillColor="@android:color/white"
+      android:pathData="M5,13.18v4L12,21l7,-3.82v-4L12,17l-7,-3.82zM12,3L1,9l11,6 9,-4.91V17h2V9L12,3z"/>
+</vector>
diff --git a/app/src/main/res/drawable-hdpi/ic_grade.png b/app/src/main/res/drawable-hdpi/ic_grade.png
new file mode 100644
index 0000000000000000000000000000000000000000..d9e980cc34cb411608d3e10b3761074413c6dbfd
GIT binary patch
literal 436
zcmV;l0ZaagP)<h;3K|Lk000e1NJLTq001Na001Ni1^@s6;Q*MJ0004dNkl<ZcwX&R
z(Q(2s3}pcpU=0??0I&c9utpdl9iVHJ0n!23=~eG6_l%+hr?Epn^6uW9V@uEPj3vC=
zZP@S+0N_a4`PCsN4#H0OP;z{*an&K4?uBh)#FA@!n^zoa<SOhP6PAo&Y#n1Fe9AOp
z$()nb`!htW5q>!v%_TJ&tDg;o%K3DJmy(+K6^UWx)MAIJip1;6sl^ud;v<~O-3eZc
zJ?#BLIH8*pycVxdh9VG7>%&PXP41B%fNv-QD^wXm<Bapuh9VI9P>K6RjmButHxwZW
zXW_TA(JM0NZ1o7tH3U<R{8o`1V~iR6m!;pjKFbgjI+zAVQA}4P*Q}A)aDO*e{n>_M
zLOZfaT9F)k=9xR#m}75#6efY}b<P?aycijyvCK&|iW*9djXo*3rZG0JnxV+2Ck4kk
zXXA<)x;TO!+3a$g=q1tTPfb%~-jf6s8{;CNLStME6ljc9pvG>FiAb*1H)4T|#`qS%
eX^a~-ybC|Lv$_8ZJuz1R0000<MNUMnLSTXjvA<IQ

literal 0
HcmV?d00001

diff --git a/app/src/main/res/drawable-mdpi/ic_grade.png b/app/src/main/res/drawable-mdpi/ic_grade.png
new file mode 100644
index 0000000000000000000000000000000000000000..78963b8a2b3d3669de42f08146116dae875e9dc2
GIT binary patch
literal 283
zcmV+$0p$LPP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv0002uNkl<ZcwX(4
z(Gh|$5JYK!255i+XhYke4Q;~$v;Zvt3$Um277`|&3rPr{?9BUt-Ms-WRMnxqBqFVH
zbF}vUW@%ZYT$GOi*Ba|jmWFGkC&d<cYMWn`3k{@f33z+k^CvZ(l_x1k1=*ABMRBLx
zNnk7J>g<3AF%}U#!#oJD=w*!=Ad3z@z)Pl&{3ZoUz&n5B=m1Cx)-*aG49RrRuA~^(
z#)AegGC@8%0EWSY=&u4E=bZ~v2YBdi3pq2vy{rMAakm}x%-DR``6DUZq9jSd7G+5i
hwrCg0!WJDW))&lNbs0vfGc5oB002ovPDHLkV1f^FZ$1D3

literal 0
HcmV?d00001

diff --git a/app/src/main/res/drawable-xhdpi/ic_grade.png b/app/src/main/res/drawable-xhdpi/ic_grade.png
new file mode 100644
index 0000000000000000000000000000000000000000..3a4eaa619c0d1b05d64ccff79f0953a90942fc03
GIT binary patch
literal 520
zcmV+j0{8uiP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm0005cNkl<ZcwX(7
z(Q(2s5JcSo4bT7u&<3<Y8>WpEkQ9&<U<yc2n>!E*S)X*ak!&ZUH?u!F-Rd$EuSC;S
zDwWE=1i()8613y`YLQ{LqE_@t(zPw`Ukx(cMszX;XX%~|_b*BqsxyX-N%x-EXLe+W
zgXrBDaHzERz`n(iL-(RrW1y*0uRWiW9sDE<50Fb`5)1KUDWw)U5(~qVrIe;8R%q@F
z)4A1QOk&~rWGSU|Vj+LBl#-oTx+r=x8dfQu{~IYDMIYR-Hu2m&aQlca+_->rhF%i#
zye3#tjB<@<O@iA+c4m`;(zAYDWW49GHW)1Ul;FKw9|iI!mU{K0@d57P`XumtVrlP@
zeJ!|`>n=##f*7Az*JNRzJJwn3!F89=Xy1a(sKkms(9}De(HoF`xb8v*sgEs|Sh{9D
zk<}}BMh9d+uDh^7Pz!%3?~hdv_U#Sm)m_+t6#cib(7mCDeWC+;br&`;)FJU<-qAf_
zFZU-0^y)5bkdXOq*R@dN{iclmWZi`g2I!htL8E_Xc;|E71$MHO(wWcC0*tuJtY~6o
z1q-}|ihvp4LPbI5x6mSBz~vM)>e8DXOn3{e5)60?RVtOr-{%Vh)a5S4wvAT+0000<
KMNUMnLSTZPh4D%N

literal 0
HcmV?d00001

diff --git a/app/src/main/res/drawable-xxhdpi/ic_grade.png b/app/src/main/res/drawable-xxhdpi/ic_grade.png
new file mode 100644
index 0000000000000000000000000000000000000000..c31eb310b82eca75573919d0e097ad84fc1c586c
GIT binary patch
literal 1032
zcmV+j1o!)iP)<h;3K|Lk000e1NJLTq002k;002k`1^@s6RqeA!000BeNkl<ZcwX(A
zy=xRf7{(Jx&_D=;5D1bcB-jQb#6oP+h}hWJ_<@C$f(kY^B5Gk_rGkP*N(BoGKR^&v
z1V8ZOe|ml1-C5jwnA@4z+qvDnn+JYy+&=TpI|Fym?as~2Bqb#!B_$;#B_(xPBC-jd
z88-R))C!xi2JVAD;IBbn>w9bLpBiEDi{J+MQQ8<ruc>E|$4{)V*m-afe70=JFx0DK
z=DFU)2#cEqr@=eR2Kb_5wZ<&h@3pX?9q`Js;JRq79iFFm!Xmc7Q_BLILThjFyq%ZW
zlPMPcNj&jOrdV`0@uXfd#iBcjC(R^NEZR*xX+D`^G2X<J_{kKDxQQp@O{Q2hpLo)4
zGR0!_#FK6%Q!K(0Pr98<vG7Yg=}$7nqB`+#ao3o5;8el;G9a1GkJtdbCsxUHd`Vm3
zy{HrhEP?A>WCFNqc`t+az)Lb2KNNq1J7CqUiLYny+Jhwd@yv5B+5;Yg4O$C(GRmIX
zLZM^e1sCri+T%9&ud;YE*jHQ9?ZkTnPD;g(Kg*a5_Khs*R^ojE=fE8I$+C>iU|(aB
zJn`DPvHcFNNx%)LrA7w(8kdYW@idw4ib<vrS!!jlFPbEN;ysZO9)elwWw5WdWJo%&
z;5#nO-s8OlyF8CgQqiNOZU*~m%M^SF*7+Jsnn}F3;FMG(Qz3ZPCGTzMf-Utk*jHPn
zqQAf`u*@Eo)Jr@~rVBcj>#^Wjmb@43sdB-Vc`E(E;=<r7xC{=lmnD9Qr^%%EfzD*o
zInCVKgV%!D=kf=O3zzr+&VU0vh9&mI^M1IlbC|hwPVS>}!R&MSgT;j{=oj+|9%qyM
zPdvrzFL+wp%)#?|Etq{Sf3Uc41^eI#kFP7OWoq&~R(O0N_PPAQ;=&H}WAgwU<~qL8
zv8G1Q4^XaCh<z@9u(+@%Kfz6~#Px<ry=IJ#<$6xIULp3m{K4YFfqVg%z(KBCNUs@>
zdU?DzT(=PWT>fBj;hMY`I+N1Z<~_Z}{$R>Im&HDpKUiFNL^O?#N`$jH?z<5CT>fB5
zK$5h`KKDIVp@BW{+R|9tXit0GZ!1D0bKoraXlZoZXb;+p^NHfvg{Bt374Xf{cx-e|
zoqK`%>YUKz3b-w$JL-t&96Hwu_tANw=?(D6vZ$ue+5=}@y%ZL)EzO>x4L$4Xtt9{P
zr{`39Ud0Rc#d+4%dr6*n=Ouqi$Qv*W_3D`JB~vU({^wAATBuJAc|!`kpD0eOu=rJQ
zPxAAvVq^5Rz88GfHL;Q!PZX1ql9G~=l9G~=TGKygRKz^##;K100000<MNUMnLSTXj
CYzg-O

literal 0
HcmV?d00001

diff --git a/app/src/main/res/layout/fragment_notifications.xml b/app/src/main/res/layout/fragment_results.xml
similarity index 93%
rename from app/src/main/res/layout/fragment_notifications.xml
rename to app/src/main/res/layout/fragment_results.xml
index 258653d..369ea47 100644
--- a/app/src/main/res/layout/fragment_notifications.xml
+++ b/app/src/main/res/layout/fragment_results.xml
@@ -4,7 +4,7 @@
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    tools:context=".fragments.notifications.NotificationsFragment">
+    tools:context=".fragments.results.ResultsFragment">
 
     <TextView
         android:id="@+id/text_notifications"
diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml
index 994b53a..d5f7480 100644
--- a/app/src/main/res/menu/bottom_nav_menu.xml
+++ b/app/src/main/res/menu/bottom_nav_menu.xml
@@ -13,7 +13,7 @@
 
     <item
         android:id="@+id/navigation_notifications"
-        android:icon="@drawable/ic_notifications_black_24dp"
-        android:title="@string/title_notifications" />
+        android:icon="@drawable/ic_grade"
+        android:title="@string/title_results" />
 
 </menu>
\ No newline at end of file
diff --git a/app/src/main/res/navigation/mobile_navigation.xml b/app/src/main/res/navigation/mobile_navigation.xml
index 75afbe9..d831d68 100644
--- a/app/src/main/res/navigation/mobile_navigation.xml
+++ b/app/src/main/res/navigation/mobile_navigation.xml
@@ -19,7 +19,7 @@
 
     <fragment
         android:id="@+id/navigation_notifications"
-        android:name="fr.nitorac.aurionweb.fragments.notifications.NotificationsFragment"
-        android:label="@string/title_notifications"
-        tools:layout="@layout/fragment_notifications" />
+        android:name="fr.nitorac.aurionweb.fragments.results.ResultsFragment"
+        android:label="@string/title_results"
+        tools:layout="@layout/fragment_results" />
 </navigation>
\ No newline at end of file
diff --git a/app/src/main/res/values-fr-rFR/strings.xml b/app/src/main/res/values-fr-rFR/strings.xml
index 86ad9fe..4f308dc 100644
--- a/app/src/main/res/values-fr-rFR/strings.xml
+++ b/app/src/main/res/values-fr-rFR/strings.xml
@@ -2,6 +2,7 @@
 <resources>
     <string name="app_name">AurionWeb</string>
     <string name="title_home">Accueil</string>
+    <string name="title_results">Notes</string>
     <string name="dialog_update_title">Mise à jour</string>
     <string name="dialog_update_msg">Une mise à jour est disponible !\n(%1$s -> %2$s)\n\nChangements :\n%3$s\n\nVoulez-vous mettre à jour ?</string>
     <string name="login_login">Nom d\'utilisateur</string>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 6dd0345..1bded9c 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -2,7 +2,7 @@
     <string name="app_name">AurionWeb</string>
     <string name="title_home">Home</string>
     <string name="title_calendar">Calendar</string>
-    <string name="title_notifications">Notifications</string>
+    <string name="title_results">Grades</string>
     <string name="dialog_update_title">Update</string>
     <string name="dialog_update_msg">An update is available !\n(%1$s -> %2$s)\n\nChangelogs:\n%3$s\n\nDo you want to update ?</string>
     <string name="login_login">Login</string>
diff --git a/build.gradle b/build.gradle
index bfb75dc..345ea8d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,12 +1,12 @@
 // Top-level build file where you can add configuration options common to all sub-projects/modules.
 buildscript {
-    ext.kotlin_version = '1.4.10'
+    ext.kotlin_version = '1.4.32'
     repositories {
         google()
-        jcenter()
+        mavenCentral()
     }
     dependencies {
-        classpath "com.android.tools.build:gradle:4.0.1"
+        classpath 'com.android.tools.build:gradle:4.2.0'
         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
 
         // NOTE: Do not place your application dependencies here; they belong
@@ -17,7 +17,12 @@ buildscript {
 allprojects {
     repositories {
         google()
-        jcenter()
+        mavenCentral()
+        jcenter() {
+            content {
+                includeModule("com.mindorks.android", "prdownloader")
+            }
+        }
         maven { url 'https://jitpack.io' }
     }
 }
diff --git a/gradle.properties b/gradle.properties
index c52ac9b..3ae7944 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -6,7 +6,7 @@
 # http://www.gradle.org/docs/current/userguide/build_environment.html
 # Specifies the JVM arguments used for the daemon process.
 # The setting is particularly useful for tweaking memory settings.
-org.gradle.jvmargs=-Xmx2048m
+org.gradle.jvmargs=-Xmx4096m -XX:MaxPermSize=1024m
 # When configured, Gradle will run in incubating parallel mode.
 # This option should only be used with decoupled projects. More details, visit
 # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
@@ -16,4 +16,6 @@ org.gradle.jvmargs=-Xmx2048m
 # https://developer.android.com/topic/libraries/support-library/androidx-rn
 android.useAndroidX=true
 # Automatically convert third-party libraries to use AndroidX
-android.enableJetifier=true
\ No newline at end of file
+android.enableJetifier=true
+org.gradle.daemon=true
+org.gradle.parallel=true
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 919be2f..63203a9 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Fri Oct 02 17:31:26 CEST 2020
+#Sat Mar 13 22:36:21 CET 2021
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
diff --git a/local.properties b/local.properties
index ee4e8c4..a782750 100644
--- a/local.properties
+++ b/local.properties
@@ -1,10 +1,8 @@
-## This file is automatically generated by Android Studio.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file should *NOT* be checked into Version Control Systems,
+## This file must *NOT* be checked into Version Control Systems,
 # as it contains information specific to your local configuration.
 #
 # Location of the SDK. This is only used by Gradle.
 # For customization when using a Version Control System, please read the
 # header note.
-sdk.dir=D\:\\Users\\Nitorac\\AppData\\Local\\sdk
\ No newline at end of file
+#Sat Mar 13 22:34:16 CET 2021
+sdk.dir=D\:\\Users\\Nitorac\\AppData\\Local\\Android\\sdk
-- 
GitLab