From 4df78ec6185b0a099afade2a7e1aac87ed16c00f Mon Sep 17 00:00:00 2001 From: Nathan Demers Date: Mon, 1 Nov 2021 18:42:21 +0100 Subject: [PATCH 1/5] add lvs api --- lib/core/apis/lvs.dart | 181 +++++++++++++++++ lib/core/apis/lvs/README.md | 32 +++ lib/core/apis/lvs/converters/account.dart | 56 ++++++ lib/core/apis/lvs/converters/disciplines.dart | 74 +++++++ lib/core/apis/lvs/converters/homework.dart | 58 ++++++ lib/core/apis/lvs/converters_exporter.dart | 10 + lib/core/apis/lvs/lvs_client.dart | 183 ++++++++++++++++++ lib/core/apis/lvs/lvs_methods.dart | 133 +++++++++++++ lib/core/apis/lvs/session_client.dart | 108 +++++++++++ lib/core/apis/model.dart | 2 +- lib/core/apis/model.g.dart | 15 +- 11 files changed, 846 insertions(+), 6 deletions(-) create mode 100644 lib/core/apis/lvs.dart create mode 100644 lib/core/apis/lvs/README.md create mode 100644 lib/core/apis/lvs/converters/account.dart create mode 100644 lib/core/apis/lvs/converters/disciplines.dart create mode 100644 lib/core/apis/lvs/converters/homework.dart create mode 100644 lib/core/apis/lvs/converters_exporter.dart create mode 100644 lib/core/apis/lvs/lvs_client.dart create mode 100644 lib/core/apis/lvs/lvs_methods.dart create mode 100644 lib/core/apis/lvs/session_client.dart diff --git a/lib/core/apis/lvs.dart b/lib/core/apis/lvs.dart new file mode 100644 index 00000000..456061d2 --- /dev/null +++ b/lib/core/apis/lvs.dart @@ -0,0 +1,181 @@ +import 'dart:convert'; + +import 'package:flutter_secure_storage/flutter_secure_storage.dart'; +import 'package:ynotes/core/apis/lvs/lvs_methods.dart'; +import 'package:ynotes/core/logic/models_exporter.dart'; +import 'package:ynotes/core/logic/shared/models.dart'; +import 'package:ynotes/core/logic/agenda/models.dart'; + +import 'package:http/src/request.dart'; +import 'package:ynotes/core/offline/data/disciplines/disciplines.dart'; +import 'package:ynotes/core/offline/data/homework/homework.dart'; +import 'package:ynotes/core/offline/offline.dart'; +import 'package:ynotes/core/utils/logging_utils/logging_utils.dart'; +import 'package:ynotes/globals.dart'; + +import 'lvs/lvs_client.dart'; +import 'lvs/converters/account.dart'; +import 'model.dart'; + +final storage = new FlutterSecureStorage(); + +void createStorage(String key, String? data) async { + await storage.write(key: key, value: data); +} + +class APILVS extends API { + LvsClient client = LvsClient(); + APILVS(Offline offlineController) : super(offlineController, apiName: "Lvs"); + + @override + Future login(username, password, {Map? additionnalSettings}) async { + CustomLogger.saveLog(object: 'LVS', text: 'Login called'); + if (username == null) { + username = ""; + } + if (password == null) { + password = ""; + } + // if (url == null) { + // url = ""; + // } + + var url = 'https://institutsaintpierresaintpaul28.la-vie-scolaire.fr'; + + Map credentials = { + 'url': Uri.parse(url), + 'username': username, + 'password': password + }; + + List res = await this.client.start(credentials); + + if (res[0] == 1) { + try { + var req_infos = await this + .client + .get(Uri.parse('/vsn.main/WSMenu/infosPortailUser')); + + Map raw_infos = jsonDecode(req_infos.body); + /* raw_infos = { + "infoUser": { + "logo": "https://institut.la-vie-scolaire.fr/vsn.main/WSMenu/logo", + "etabName": "Intitut", + "userPrenom": "Inom", + "userNom": "Iom", + "profil": "Elève" + }, + "plateform": "" + }; */ + appSys.account = LvsAccountConverter.account(raw_infos); + + if (appSys.account != null && + appSys.account!.managableAccounts != null) { + await storage.write( + key: "appAccount", value: jsonEncode(appSys.account!.toJson())); + appSys.currentSchoolAccount = appSys.account!.managableAccounts![0]; + } else { + return [0, "Impossible de collecter les comptes."]; + } + createStorage("password", password ?? ""); + createStorage("username", username ?? ""); + this.loggedIn = true; + return ([1, "Bienvenue ${appSys.account?.name ?? "Invité"}!"]); + } catch (e) { + CustomLogger.error( + 'An error occured while registering the account: ' + e.toString()); + } + return [ + 0, + "Erreur à l'inscription du compte. Seuls les comptes élèves sont supportés." + ]; + } + return [0, "Erreur à la connection"]; + } + + @override + Future apiStatus() async { + return [1, "Pas de problème connu."]; + } + + @override + app(String appname, {String? args, String? action, CloudItem? folder}) { + switch (appname) { + } + ; + } + + @override + Future?> getHomeworkFor(DateTime? dateHomework, + {bool? forceReload}) async { + return await fetch( + () async => LvsMethods(await this.getClient(), this.offlineController) + .homeworkFor(dateHomework!), + () async => + HomeworkOffline(offlineController).getHomeworkFor(dateHomework!), + forceFetch: forceReload ?? false); + } + + @override + Future?> getNextHomework({bool? forceReload}) async { + return await fetch( + () async => LvsMethods(await this.getClient(), this.offlineController) + .nextHomework(), + () => HomeworkOffline(offlineController).getAllHomework(), + forceFetch: forceReload ?? false); + } + + @override + Future downloadRequest(Document document) async { + var cl = await this.getClient(); + var hw_client = await cl.getHwClient(); + var url = hw_client.base_url + + "/fichier/afficherFichier" + + hw_client.token + + '?fichierId=' + + document.id; + return new Request('GET', Uri.parse(url)); + } + + @override + Future?> getGrades({bool? forceReload}) async { + return await fetch( + () async => + LvsMethods(await this.getClient(), this.offlineController).grades(), + () => DisciplinesOffline(offlineController).getDisciplines(), + forceFetch: forceReload ?? false); + } + + @override + Future?> getNextLessons(DateTime from, + {bool? forceReload}) async { + // TODO: implement getNextLessons + throw UnimplementedError(); + } + + @override + Future?> getSchoolLife( + {bool forceReload = false}) async { + // TODO: implement getSchoolLife + throw UnimplementedError(); + } + + @override + Future testNewGrades() async { + // TODO: implement testNewGrades + return (true); + } + + @override + Future uploadFile(String context, String id, String filepath) async { + // Not available + throw UnimplementedError(); + } + + getClient() async { + if (!this.client.started) { + throw ('Client is called but not started.'); + } + return this.client; + } +} diff --git a/lib/core/apis/lvs/README.md b/lib/core/apis/lvs/README.md new file mode 100644 index 00000000..8b236aa7 --- /dev/null +++ b/lib/core/apis/lvs/README.md @@ -0,0 +1,32 @@ +# Introduction ✨ +Api apportant l'intégration du service scolaire "La Vie Scolaire" à l'application Ynotes. Se référer aux conditions d'utilisation de celle-ci. +Seuls les devoirs, notes et informations de l'élève sont disponibles pour l'instant. + +# Fonctionnement 🧙🏻 +## Clients +Implementant `SessionClient.dart`, les clients permettent de gérer une session en apportant des méthodes facilitant l'authentification, la gestion de token et les requêtes. Si configuré à cet effet, le client peut assurer le rafraichissement automatique de la session. + +## Methods +```nextHomework()```: donne les devoirs sur les 23 prochains jours. + +## Converters +Permettent de convertir les données brutes renvoyées par le service scolaire sous forme d'instance d'objets définis par l'application. +- ### Account Converter +Exemple de données attendues pour `account()`: +```json{ + "infoUser": { + "logo": + "https://etablissement.la-vie-scolaire.fr/vsn.main/WSMenu/logo", + "etabName": "Inserer Etablissement", + "userPrenom": "Inserer prenom", + "userNom": "Inserer nom", + "profil": "Elève" + }, + "plateform": "" + } +``` +- ### Homework Converter +Un contenu json est attendu. + +- ### Disciplines Converter +Un contenu html est attendu. \ No newline at end of file diff --git a/lib/core/apis/lvs/converters/account.dart b/lib/core/apis/lvs/converters/account.dart new file mode 100644 index 00000000..1e1a52fd --- /dev/null +++ b/lib/core/apis/lvs/converters/account.dart @@ -0,0 +1,56 @@ +import 'package:ynotes/core/apis/model.dart'; +import 'package:ynotes/core/apis/utils.dart'; +import 'package:ynotes/core/logic/models_exporter.dart'; +import 'package:ynotes/core/utils/null_safe_map_getter.dart'; +import 'package:uuid/uuid.dart'; + +class LvsAccountConverter { + static AppAccount account(Map accountData) { + if (accountData["infoUser"]["profil"] != 'Elève') { + throw ('Account type must be "Elève"'); + } + SchoolAccount _account = singleSchoolAccount(accountData); + String? name = _account.name; + String? surname = _account.surname; + String? id = Uuid().v1(); + bool isParentMainAccount = false; + return AppAccount( + name: name, + surname: surname, + id: id, + managableAccounts: [_account], + isParentMainAccount: isParentMainAccount, + apiType: API_TYPE.Lvs); + } + + static List availableTabs() { + List tabs = []; + tabs.add(appTabs.homework); + tabs.add(appTabs.summary); + tabs.add(appTabs.grades); + tabs.add(appTabs.files); + return tabs; + } + + static SchoolAccount singleSchoolAccount( + Map schoolAccountData) { + schoolAccountData = mapGet(schoolAccountData, ["infoUser"]); + String? name = utf8convert(mapGet(schoolAccountData, ["userPrenom"])); + String? surname = utf8convert(mapGet(schoolAccountData, ["userNom"])); + String? schoolName = utf8convert(mapGet(schoolAccountData, ["etabName"])); + String? studentClass = ""; + String? studentID = mapGet(schoolAccountData, ["id"]).toString(); + List tabs = availableTabs(); + if (schoolName.length > 37) { + schoolName = schoolName.substring(0, 35) + '...'; + //quick fix if name is too long + } + return SchoolAccount( + name: name, + surname: surname, + studentClass: studentClass, + studentID: studentID, + availableTabs: tabs, + schoolName: schoolName); + } +} diff --git a/lib/core/apis/lvs/converters/disciplines.dart b/lib/core/apis/lvs/converters/disciplines.dart new file mode 100644 index 00000000..45b5fc2a --- /dev/null +++ b/lib/core/apis/lvs/converters/disciplines.dart @@ -0,0 +1,74 @@ +import 'package:ynotes/core/logic/models_exporter.dart'; +import 'package:html/parser.dart' show parse; + +//https://institutsaintpierresaintpaul28.la-vie-scolaire.fr/vsn.main/dossierRecapEleve/afficheDetailNotes + +class LvsDisciplineConverter { + static get_disciplines(html) { + List disciplines = []; + parse(html).querySelectorAll("tr.odd, tr.even").forEach((element) { + var grades = + get_grades(element.querySelector("td.tdReleveRight")!.innerHtml); + var title = element.querySelector("td.tdReleveLeft"); + var name = title!.querySelector('strong')!.innerHtml; + var teacher = + (title.innerHtml.substring(title.innerHtml.lastIndexOf('>') + 1)) + .replaceAll(' ', ''); + var average = element.querySelector("td.tdReleveMoy")!.innerHtml; + disciplines.add(Discipline( + // classGeneralAverage: '', one day... + average: average, + teachers: [teacher], + disciplineName: name, + periodName: 'periodeName', + classNumber: 'classNumber', + gradesList: grades, + subdisciplineCodes: [], + subdisciplineNames: [])); + }); + return disciplines; + } + + static get_grades(html) { + List grades = []; + html.split("").forEach((grade) { + if (grade.replaceAll(' ', '').toString().length > 1) { + var name = grade.split(' :')[0]; + if (grade.substring(0, 3) == ' - ') { + name = grade + .split(' :')[0] + .substring(0, grade.split(' :')[0].length - 13); + } + var value = grade.substring(grade.lastIndexOf('">') + ('">').length); + + grades.add(Grade( + value: value.substring(0, value.indexOf('/')), + testName: name, + letters: true, + weight: '', + scale: value.substring(value.indexOf('/') + 1), + min: '15', + max: '20', + classAverage: '20', + date: new DateTime(2021), + notSignificant: false, + entryDate: new DateTime(2021), + countAsZero: false)); + } + }); + return grades; + } + + static getPeriods(html) { + List urls = []; + html = parse(html); + html + .querySelector("ul.periodes")! + .querySelectorAll('li.periode') + .forEach((period) { + var url = period.querySelector('a')!.attributes['href'].toString(); + urls.add(url); + }); + return urls; + } +} diff --git a/lib/core/apis/lvs/converters/homework.dart b/lib/core/apis/lvs/converters/homework.dart new file mode 100644 index 00000000..913ca08b --- /dev/null +++ b/lib/core/apis/lvs/converters/homework.dart @@ -0,0 +1,58 @@ +import 'dart:convert'; +import 'package:intl/intl.dart'; +import 'package:ynotes/core/logic/models_exporter.dart'; + +class LvsHomeworkConverter { + static List homework(hwsData) { + List hws = json.decode(hwsData); + + List hwList = []; + hws.forEach((hw) { + String discipline = hw['subject']; + DateTime date = DateFormat('yyyy-MM-dd').parse(hw['start_date']); + bool done = false; + String teacherName = hw['text']; + hw['activitesData'].forEach((hwContent) { + String id = hwContent['id'].toString(); + String rawContent = hwContent['description']; + bool toReturn = false; + bool isATest = false; + bool loaded = true; + + if (['SURV', 'EVAL', 'PSURV'].contains(hwContent['code'])) { + isATest = true; + } + + hwList.add(Homework( + discipline: discipline, + id: id, + rawContent: rawContent, + date: date, + done: done, + toReturn: toReturn, + teacherName: teacherName, + loaded: loaded, + isATest: isATest, + )); + }); + }); + return hwList; + } + + static get_af(List af, hw_client) { + var text = ''; + List docs = []; + if (!af.isEmpty) { + text = text + '

Pièces jointes:

'; + af.forEach((file) { + var f_url = file['url']; + docs.add(Document( + documentName: file['nom'], + id: f_url.substring( + f_url.lastIndexOf('fichierId=') + 'fichierId='.length))); + }); + } + print(docs); + return docs; + } +} diff --git a/lib/core/apis/lvs/converters_exporter.dart b/lib/core/apis/lvs/converters_exporter.dart new file mode 100644 index 00000000..d32d4db2 --- /dev/null +++ b/lib/core/apis/lvs/converters_exporter.dart @@ -0,0 +1,10 @@ +//converters +export 'package:ynotes/core/apis/lvs/converters/account.dart'; +export 'package:ynotes/core/apis/lvs/converters/homework.dart'; +export 'package:ynotes/core/apis/lvs/converters/disciplines.dart'; +export 'package:ynotes/core/offline/data/homework/homework.dart'; +//models +export 'package:ynotes/core/logic/homework/models.dart'; +export 'package:ynotes/core/logic/grades/models.dart'; +export 'package:ynotes/core/logic/cloud/models.dart'; +export 'package:ynotes/core/logic/agenda/models.dart'; diff --git a/lib/core/apis/lvs/lvs_client.dart b/lib/core/apis/lvs/lvs_client.dart new file mode 100644 index 00000000..19bb00f6 --- /dev/null +++ b/lib/core/apis/lvs/lvs_client.dart @@ -0,0 +1,183 @@ +import 'dart:convert'; +import 'package:http/http.dart' as http; +import 'package:http/http.dart'; +import 'package:ynotes/core/utils/logging_utils/logging_utils.dart'; +import 'session_client.dart'; + +class LvsClient extends SessionClient { + HwClient hw_client = new HwClient(); + + Future init(credentials) async { + if (credentials['username'] is! String || + credentials['password'] is! String) { + throw ('Lvs credentials username and password must be string'); + } + if (credentials['url'] is! Uri) { + throw ('Lvs credentials url must be Uri'); + } + var data = { + 'login': credentials['username'], + 'password': credentials['password'] + }; + + this.setUser_agent(); + var rep = await this.post( + Uri.parse(credentials['url'].toString() + '/vsn.main/WSAuth/connexion'), + body: json.encode(data), + headers: {"Content-Type": "application/json"}, + token: false, + baseUrl: false); + CustomLogger.saveLog(object: 'LVS', text: rep.body.toString()); + if (rep.statusCode == 200) { + CustomLogger.log('LVS', 'successful authentication for Lvs'); + this.token = rep.headers['set-cookie'].toString(); + this.base_url = credentials['url'].toString(); + this.hw_client.started = false; + return [1, "success"]; + } + return [0, "error"]; + } + + @override + Future get(Uri url, + {Map? headers, bool token = true, baseUrl = true}) async { + Map? theheaders = {}; + if (token) { + var thetoken = await this.getToken(); + if (thetoken == '') { + return http.Response('', 401); + } + thetoken = thetoken.replaceAll(RegExp(r','), ';'); + theheaders["Cookie"] = thetoken; + } + + if (headers == Map) { + theheaders.addAll(headers!); + } + + return await super.get(url, headers: theheaders, baseUrl: baseUrl); + } + + @override + Future post(Uri url, + {Map? headers, + Object? body, + Encoding? encoding, + bool token = true, + baseUrl = true}) async { + Map? theheaders = {}; + + if (token) { + var thetoken = await this.getToken(); + if (thetoken == '') { + return http.Response('', 401); + } + thetoken = thetoken.replaceAll(RegExp(r','), ';'); + theheaders["Cookie"] = thetoken; + } + + if (headers == Map) { + theheaders.addAll(headers!); + } + return await super + .post(url, body: body, headers: theheaders, baseUrl: baseUrl); + } + + getHwClient() async { + if (!this.hw_client.started) { + var theclient = new HwClient(); + await theclient.start({ + 'method': this.get, + 'args': Uri.parse( + '/vsn.main/WSMenu/getModuleUrl?mod=CDT&minuteEcartGMTClient=-120&add=123'), + 'named': {} + }); + this.hw_client = theclient; + } + return this.hw_client; + } +} + +class HwClient extends SessionClient { + HwClient() : super(); + Future init(Map credentials) async { + var entry = + await Function.apply(credentials['method'], [credentials['args']]); + var entry_url = jsonDecode(entry.body)['location']; + CustomLogger.saveLog(object: 'Entry Url for Hw', text: entry_url); + if (entry.statusCode == 200) { + this.base_url = entry_url.substring(0, entry_url.indexOf('.fr') + 3) + + '/eliot-textes'; + + var request = new Request('GET', Uri.parse(entry_url)) + ..followRedirects = false; + var response = await client.send(request); + + var i = 1; + while (i < 6 && response.statusCode == 302) { + request = new Request('GET', Uri.parse(response.headers['location']!)) + ..followRedirects = false; + response = await client.send(request); + i++; + } + + var raw_token = response.headers['location']!; + + var debut = raw_token.indexOf(';'); + var end = raw_token.indexOf('?'); + var token = raw_token.substring(debut, end); + + if (token != '') { + this.token = token; + /* var resp = await this.post( + Uri.parse('/rechercheActivite/rechercheJournaliere'), + headers: { + "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" + }, + body: + "params=%7B%22start%22%3A0%2C%22limit%22%3A100%2C%22contexteId%22%3A-1%2C%22typeId%22%3A-1%2C%22cdtId%22%3A-1%2C%22matiereId%22%3A-1%2C%22groupeId%22%3A-1%2C%22dateDebut%22%3A%2208%2F06%2F2021%22%2C%22dateFin%22%3A%2208%2F06%2F2021%22%2C%22actionRecherche%22%3Atrue%2C%22activeTab%22%3A%22idlisteTab%22%7D&xaction=read"); + */ + + CustomLogger.log('LVS_HW', 'successful authentication for Lvs Hw'); + return [1, "success"]; + } + return [0, "invalid token for Lvs Hw"]; + } + return [0, "error while retrieving homeworks"]; + } + + @override + Future get(Uri url, + {Map? headers, + bool token = true, + baseUrl = true, + params = ''}) async { + if (token) { + var thetoken = await this.getToken(); + if (thetoken == '') { + return http.Response('', 401); + } + String requrl = url.toString(); + url = Uri.parse(requrl + thetoken + params); + } + return super.get(url, headers: headers, baseUrl: baseUrl); + } + + @override + Future post(Uri url, + {Map? headers, + Object? body, + Encoding? encoding, + bool token = true, + baseUrl = true}) async { + if (token) { + var thetoken = await this.getToken(); + if (thetoken == '') { + return http.Response('', 401); + } + String requrl = url.toString(); + url = Uri.parse(requrl + thetoken); + } + return super.post(url, body: body, headers: headers, baseUrl: baseUrl); + } +} diff --git a/lib/core/apis/lvs/lvs_methods.dart b/lib/core/apis/lvs/lvs_methods.dart new file mode 100644 index 00000000..247c4dce --- /dev/null +++ b/lib/core/apis/lvs/lvs_methods.dart @@ -0,0 +1,133 @@ +import 'dart:convert'; + +import 'package:connectivity_plus/connectivity_plus.dart'; +import 'package:ynotes/core/apis/lvs/converters_exporter.dart'; +import 'package:ynotes/core/apis/lvs/lvs_client.dart'; +import 'package:ynotes/core/logic/models_exporter.dart'; +import 'package:ynotes/core/offline/data/disciplines/disciplines.dart'; +import 'package:ynotes/core/offline/offline.dart'; +import 'package:ynotes/core/utils/logging_utils/logging_utils.dart'; + +import '../../../globals.dart'; +import '../../../useful_methods.dart'; + +Future fetch(Function onlineFetch, Function offlineFetch, + {bool forceFetch = false}) async { + var connectivityResult = await (Connectivity().checkConnectivity()); + if (connectivityResult == ConnectivityResult.none) { + return await offlineFetch(); + } else if (forceFetch) { + try { + await onlineFetch(); + return await offlineFetch(); + } catch (e) { + CustomLogger.error("Error while fetching: " + e.toString()); + return await offlineFetch(); + } + } +} + +class LvsMethods { + LvsClient client; + final Offline _offlineController; + + LvsMethods(this.client, this._offlineController); + + Future?> grades() async { + List disciplines = []; + var req = + await this.client.get(Uri.parse('/vsn.main/releveNote/releveNotes')); + List periods = ['1er Trimestre', '2nd Trimestre', '3ème Trimestre']; + var periodsData = LvsDisciplineConverter.getPeriods(req.body); + + for (var index = 0; index < periodsData.length; index++) { + var resp = + await this.client.get(Uri.parse(periodsData[index].toString())); + var dis = LvsDisciplineConverter.get_disciplines(resp.body); + dis.forEach((element) { + element.periodName = periods[index]; + element.periodCode = periods[index]; + }); + disciplines.addAll(dis); + } + await DisciplinesOffline(_offlineController).updateDisciplines(disciplines); + appSys.settings.system.lastGradeCount = + (getAllGrades(disciplines, overrideLimit: true) ?? []).length; + appSys.saveSettings(); + } + + Future?> homeworkFor(DateTime date) async { + HwClient hwClient = await this.client.getHwClient(); + var h = await searchHw(hwClient, date, date.add(Duration(days: 2))); + } + + nextHomework() async { + var date = new DateTime.now(); + var end_date = date.add(Duration(days: 25)); + HwClient hwClient = await this.client.getHwClient(); + await searchHw(hwClient, date, end_date); + } + + searchHw(HwClient hwClient, DateTime date, DateTime end_date) async { + CustomLogger.log('LVS_HW', 'searching hw'); + + DateTime search_date = end_date.subtract(const Duration(days: 2)); + + var search = await hwClient.post( + Uri.parse('/rechercheActivite/rechercheJournaliere'), + headers: { + "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" + }, + body: "params=%7B%22start%22%3A0%2C%22limit%22%3A100%2C%22contexteId%22%3A-1%2C%22typeId%22%3A-1%2C%22cdtId%22%3A-1%2C%22matiereId%22%3A-1%2C%22groupeId%22%3A-1%2C%22dateDebut%22%3A%22" + + date.day.toString() + + "%2F" + + date.month.toString() + + "%2F" + + date.year.toString() + + "%22%2C%22dateFin%22%3A%22" + + search_date.day.toString() + + "%2F" + + search_date.month.toString() + + "%2F" + + search_date.year.toString() + + "%22%2C%22actionRecherche%22%3Atrue%2C%22activeTab%22%3A%22idlisteTab%22%7D&xaction=read"); + + List searchIds = []; + Map af = {}; //attached files + json.decode(search.body)['activites'].forEach((element) { + af[element['activiteId'].toString()] = element['activiteDocuments']; + searchIds.add(element['activiteId'].toString()); + }); + + var req = await hwClient.get(Uri.parse('/vueCalendaire/eleve'), + params: '?timeshift=-120&from=' + + date.year.toString() + + '-' + + date.month.toString() + + '-' + + date.day.toString() + + '&to=' + + end_date.year.toString() + + '-' + + end_date.month.toString() + + '-' + + end_date.day.toString()); + List? hw = LvsHomeworkConverter.homework(req.body); + (hw).removeWhere((element) => !searchIds.contains(element.id)); + + var ids = []; + hw.reversed.toList().forEach((element) { + if (ids.contains(element.id)) { + hw.remove(element); + } else { + element.files + .addAll(LvsHomeworkConverter.get_af(af[element.id], hwClient)); + ids.add(element.id); + } + }); + if (hw.length > 0) { + await HomeworkOffline(_offlineController).updateHomework(hw); + CustomLogger.log('LVS_HW', "Hw updated"); + } + } +} diff --git a/lib/core/apis/lvs/session_client.dart b/lib/core/apis/lvs/session_client.dart new file mode 100644 index 00000000..074cd8ef --- /dev/null +++ b/lib/core/apis/lvs/session_client.dart @@ -0,0 +1,108 @@ +import 'dart:convert'; + +import 'package:http/http.dart' as http; +import 'dart:math'; + +abstract class SessionClient { + http.Client client = new http.Client(); + String token = ''; + String base_url = ''; + bool started = false; + String? user_agent; + int last_refresh = 0; + int limit_refresh = 5000; + int token_expiration = 1200000; + int req = 0; + late Map credentials; + + Future init(Map credentials); + + Future start(Map credentials) async { + this.credentials = credentials; + var res = await this.init(credentials); + this.started = true; + var now = new DateTime.now(); + this.last_refresh = now.millisecondsSinceEpoch; + return res; + } + + Future get(Uri url, + {Map? headers, bool token = true, baseUrl = true}) async { + if (baseUrl) { + String requrl = url.toString(); + url = Uri.parse(this.base_url + requrl); + } + + if (this.user_agent != null) { + if (headers == null) { + headers = {}; + } + headers['User-Agent'] = this.user_agent!; + } + return await await client.get(url, headers: headers); + } + + Future post(Uri url, + {Map? headers, + Object? body, + Encoding? encoding, + bool token = true, + baseUrl = true}) async { + if (baseUrl) { + String requrl = url.toString(); + url = Uri.parse(this.base_url + requrl); + } + if (this.user_agent != null) { + if (headers == null) { + headers = {}; + } + headers['User-Agent'] = this.user_agent!; + } + return client.post(url, body: body, headers: headers); + } + + Future getToken([refresh = false]) async { + if (!this.started) { + return ''; + } + var now = new DateTime.now(); + + if (refresh && + now.millisecondsSinceEpoch - this.last_refresh > + this.limit_refresh || + now.millisecondsSinceEpoch - this.last_refresh > + this.token_expiration) { + var previous_token = this.token; + await this.start(this.credentials); + if (this.token == previous_token) { + return ''; + } + } + return this.token; + } + + String setUser_agent({String agent = ''}) { + if (agent != '') { + Random random = new Random(); + int randomNumber = random.nextInt(15); + return this.user_agent = [ + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36", + "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36", + "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0", + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36", + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/603.2.4 (KHTML, like Gecko) Version/10.1.1 Safari/603.2.4", + "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0", + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36", + "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0", + "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36", + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36", + "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36", + "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:53.0) Gecko/20100101 Firefox/53.0", + "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36", + "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko", + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:53.0) Gecko/20100101 Firefox/53.0" + ][randomNumber]; + } + return this.user_agent = agent; + } +} diff --git a/lib/core/apis/model.dart b/lib/core/apis/model.dart index aeea33b3..2fa1fb6d 100644 --- a/lib/core/apis/model.dart +++ b/lib/core/apis/model.dart @@ -105,7 +105,7 @@ abstract class API { Future uploadFile(String context, String id, String filepath); } -enum API_TYPE { ecoleDirecte, pronote } +enum API_TYPE { ecoleDirecte, pronote, Lvs } @JsonSerializable() class AppAccount { diff --git a/lib/core/apis/model.g.dart b/lib/core/apis/model.g.dart index 271a7593..b61dd421 100644 --- a/lib/core/apis/model.g.dart +++ b/lib/core/apis/model.g.dart @@ -20,7 +20,8 @@ AppAccount _$AppAccountFromJson(Map json) { ); } -Map _$AppAccountToJson(AppAccount instance) => { +Map _$AppAccountToJson(AppAccount instance) => + { 'name': instance.name, 'surname': instance.surname, 'id': instance.id, @@ -56,10 +57,10 @@ K _$enumDecode( ).key; } -// ignore: constant_identifier_names const _$API_TYPEEnumMap = { API_TYPE.ecoleDirecte: 'ecoleDirecte', API_TYPE.pronote: 'pronote', + API_TYPE.Lvs: 'Lvs', }; SchoolAccount _$SchoolAccountFromJson(Map json) { @@ -67,21 +68,25 @@ SchoolAccount _$SchoolAccountFromJson(Map json) { name: json['name'] as String?, studentClass: json['studentClass'] as String?, studentID: json['studentID'] as String?, - availableTabs: (json['availableTabs'] as List).map((e) => _$enumDecode(_$appTabsEnumMap, e)).toList(), + availableTabs: (json['availableTabs'] as List) + .map((e) => _$enumDecode(_$appTabsEnumMap, e)) + .toList(), surname: json['surname'] as String?, schoolName: json['schoolName'] as String?, profilePicture: json['profilePicture'] as String?, )..credentials = json['credentials'] as Map?; } -Map _$SchoolAccountToJson(SchoolAccount instance) => { +Map _$SchoolAccountToJson(SchoolAccount instance) => + { 'name': instance.name, 'surname': instance.surname, 'schoolName': instance.schoolName, 'studentClass': instance.studentClass, 'studentID': instance.studentID, 'profilePicture': instance.profilePicture, - 'availableTabs': instance.availableTabs.map((e) => _$appTabsEnumMap[e]).toList(), + 'availableTabs': + instance.availableTabs.map((e) => _$appTabsEnumMap[e]).toList(), 'credentials': instance.credentials, }; From c43889e7e12ca8f3eab829acb4a39e887cf10adc Mon Sep 17 00:00:00 2001 From: Nathan Demers Date: Mon, 1 Nov 2021 18:46:12 +0100 Subject: [PATCH 2/5] add lvs to the apiManager --- lib/core/apis/utils.dart | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/lib/core/apis/utils.dart b/lib/core/apis/utils.dart index 9f4cb889..4660045d 100644 --- a/lib/core/apis/utils.dart +++ b/lib/core/apis/utils.dart @@ -11,6 +11,8 @@ import 'package:ynotes/core/utils/kvs.dart'; import 'package:ynotes/core/utils/logging_utils/logging_utils.dart'; import 'package:ynotes/globals.dart'; +import 'lvs.dart'; + //Return the good API (will be extended to Pronote) List colorList = [ "#f07aa0", @@ -37,6 +39,9 @@ apiManager(Offline _offline) { case 1: return APIPronote(_offline); + + case 2: + return APILVS(_offline); } } @@ -47,7 +52,8 @@ String getInfoUrl(String url) { Future checkPronoteURL(String url) async { try { - var response = await http.get(Uri.parse(getInfoUrl(url))).catchError((e) {}); + var response = + await http.get(Uri.parse(getInfoUrl(url))).catchError((e) {}); if (response.statusCode == 200) { return true; } else { @@ -85,7 +91,8 @@ Future getColor(String? disciplineCode) async { ///Generate lesson ID using, the next scheme : week parity (1 or 2), day of week (1-7) and an hashcode ///composed of the lesson start datetime, the lesson end datetime and the discipline name -Future getLessonID(DateTime start, DateTime end, String disciplineName) async { +Future getLessonID( + DateTime start, DateTime end, String disciplineName) async { int parity = ((await getWeek(start)).isEven) ? 1 : 2; int weekDay = start.weekday; TimeOfDay startTimeOfDay = TimeOfDay.fromDateTime(start); @@ -96,7 +103,8 @@ Future getLessonID(DateTime start, DateTime end, String disciplineName) asy endTimeOfDay.minute.toString(); int endHash = (parsedStartAndEnd + disciplineName).hashCode; - int finalID = int.parse(parity.toString() + weekDay.toString() + endHash.toString()); + int finalID = + int.parse(parity.toString() + weekDay.toString() + endHash.toString()); return finalID; } @@ -111,14 +119,23 @@ List getRootAddress(String address) { getWeek(DateTime date) async { if (await (KVS.read(key: "startday")) != null) { - return (1 + (date.difference(DateTime.parse(await (KVS.read(key: "startday")) ?? "")).inDays / 7).floor()).round(); + return (1 + + (date + .difference(DateTime.parse( + await (KVS.read(key: "startday")) ?? "")) + .inDays / + 7) + .floor()) + .round(); } else { return 0; } } String linkify(String link) { - return link.replaceAllMapped(RegExp(r'(>|\s)+(https?.+?)(<|\s)', multiLine: true, caseSensitive: false), (match) { + return link.replaceAllMapped( + RegExp(r'(>|\s)+(https?.+?)(<|\s)', + multiLine: true, caseSensitive: false), (match) { return '${match.group(1)}${match.group(2)}${match.group(3)}'; }); } From 39628a76af5306fc8d0a919ccd76bf0db3d9c88f Mon Sep 17 00:00:00 2001 From: Nathan Demers Date: Mon, 1 Nov 2021 19:29:50 +0100 Subject: [PATCH 3/5] work on login --- .../screens/login/content/login_content.dart | 5 ++ lib/ui/screens/login/login.dart | 12 +++- lib/ui/screens/login/routes.dart | 55 ++++++++++++++++--- lib/ui/screens/login/sub_pages/lvs.dart | 12 ++++ 4 files changed, 73 insertions(+), 11 deletions(-) create mode 100644 lib/ui/screens/login/sub_pages/lvs.dart diff --git a/lib/ui/screens/login/content/login_content.dart b/lib/ui/screens/login/content/login_content.dart index da282b4d..96849358 100644 --- a/lib/ui/screens/login/content/login_content.dart +++ b/lib/ui/screens/login/content/login_content.dart @@ -10,6 +10,7 @@ class LoginContent { static final widgets = _Widgets(); static final login = _Login(); static final ecoleDirecte = _EcoleDirecte(); + static final lvs = _Lvs(); static final demos = _Demos(); static final pronote = _Pronote(); } @@ -25,6 +26,10 @@ class _EcoleDirecte { final subtitle = "EcoleDirecte"; } +class _Lvs { + final subtitle = "La vie scolaire"; +} + class _Demos { final subtitle = "Choisis ton service scolaire"; } diff --git a/lib/ui/screens/login/login.dart b/lib/ui/screens/login/login.dart index c233bce2..4870a2a4 100644 --- a/lib/ui/screens/login/login.dart +++ b/lib/ui/screens/login/login.dart @@ -12,7 +12,8 @@ class LoginPage extends StatelessWidget { // This is only temporary and should be stored in the [API] class static final List _services = [ SchoolServiceBox( - image: const AssetImage('assets/images/icons/ecoledirecte/EcoleDirecteIcon.png'), + image: const AssetImage( + 'assets/images/icons/ecoledirecte/EcoleDirecteIcon.png'), imageColor: theme.colors.foregroundColor, name: 'Ecole Directe', route: '/login/ecoledirecte', @@ -22,6 +23,12 @@ class LoginPage extends StatelessWidget { name: 'Pronote', route: '/login/pronote', parser: 1), + const SchoolServiceBox( + name: 'La vie scolaire', + route: '/login/lvs', + image: AssetImage( + 'assets/images/icons/pronote/PronoteIcon.png'), //temporary + parser: 2), // LA VIE SCOLAIRE, beta = true const SchoolServiceBox(name: "Démonstrations", route: "/login/demos") ]; @@ -43,7 +50,8 @@ class LoginPage extends StatelessWidget { context, YInfoDialog( title: LoginContent.login.missingService, - body: Text(LoginContent.login.dialogBody, style: theme.texts.body1), + body: Text(LoginContent.login.dialogBody, + style: theme.texts.body1), confirmLabel: "OK", )); }, diff --git a/lib/ui/screens/login/routes.dart b/lib/ui/screens/login/routes.dart index a12658ca..f1344db6 100644 --- a/lib/ui/screens/login/routes.dart +++ b/lib/ui/screens/login/routes.dart @@ -2,6 +2,7 @@ import 'package:ynotes/router.dart'; import 'package:ynotes/ui/screens/login/login.dart'; import 'package:ynotes/ui/screens/login/sub_pages/demos.dart'; import 'package:ynotes/ui/screens/login/sub_pages/ecoledirecte.dart'; +import 'package:ynotes/ui/screens/login/sub_pages/lvs.dart'; import 'package:ynotes/ui/screens/login/sub_pages/pronote/geolocation/geolocation.dart'; import 'package:ynotes/ui/screens/login/sub_pages/pronote/geolocation/results.dart'; import 'package:ynotes/ui/screens/login/sub_pages/pronote/geolocation/search.dart'; @@ -13,16 +14,48 @@ import 'package:ynotes/ui/screens/login/sub_pages/pronote/url/webview.dart'; /// Contains all routes concerning user authentification (`/login/...`) final List loginRoutes = [ - CustomRoute(path: "/login", page: const LoginPage(), relatedApi: -1, show: false), - CustomRoute(path: "/login/demos", page: const LoginDemosPage(), relatedApi: -1, show: false), - CustomRoute(path: "/login/ecoledirecte", page: const LoginEcoleDirectePage(), relatedApi: -1, show: false), - CustomRoute(path: "/login/pronote", page: const LoginPronotePage(), relatedApi: -1, show: false), - CustomRoute(path: "/login/pronote/url", page: const LoginPronoteUrlPage(), relatedApi: -1, show: false), - CustomRoute(path: "/login/pronote/url/form", page: const LoginPronoteUrlFormPage(), relatedApi: -1, show: false), CustomRoute( - path: "/login/pronote/url/webview", page: const LoginPronoteUrlWebviewPage(), relatedApi: -1, show: false), + path: "/login", page: const LoginPage(), relatedApi: -1, show: false), CustomRoute( - path: "/login/pronote/geolocation", page: const LoginPronoteGeolocationPage(), relatedApi: -1, show: false), + path: "/login/demos", + page: const LoginDemosPage(), + relatedApi: -1, + show: false), + CustomRoute( + path: "/login/ecoledirecte", + page: const LoginEcoleDirectePage(), + relatedApi: -1, + show: false), + CustomRoute( + path: "/login/lvs", + page: const LoginLvsPage(), + relatedApi: -1, + show: false), + CustomRoute( + path: "/login/pronote", + page: const LoginPronotePage(), + relatedApi: -1, + show: false), + CustomRoute( + path: "/login/pronote/url", + page: const LoginPronoteUrlPage(), + relatedApi: -1, + show: false), + CustomRoute( + path: "/login/pronote/url/form", + page: const LoginPronoteUrlFormPage(), + relatedApi: -1, + show: false), + CustomRoute( + path: "/login/pronote/url/webview", + page: const LoginPronoteUrlWebviewPage(), + relatedApi: -1, + show: false), + CustomRoute( + path: "/login/pronote/geolocation", + page: const LoginPronoteGeolocationPage(), + relatedApi: -1, + show: false), CustomRoute( path: "/login/pronote/geolocation/results", page: const LoginPronoteGeolocationResultsPage(), @@ -33,5 +66,9 @@ final List loginRoutes = [ page: const LoginPronoteGeolocationSearchPage(), relatedApi: -1, show: false), - CustomRoute(path: "/login/pronote/qrcode", page: const LoginPronoteQrcodePage(), relatedApi: -1, show: false), + CustomRoute( + path: "/login/pronote/qrcode", + page: const LoginPronoteQrcodePage(), + relatedApi: -1, + show: false), ]; diff --git a/lib/ui/screens/login/sub_pages/lvs.dart b/lib/ui/screens/login/sub_pages/lvs.dart new file mode 100644 index 00000000..897ab919 --- /dev/null +++ b/lib/ui/screens/login/sub_pages/lvs.dart @@ -0,0 +1,12 @@ +import 'package:flutter/material.dart'; +import 'package:ynotes/ui/screens/login/content/login_content.dart'; +import 'package:ynotes/ui/screens/login/widgets/widgets.dart'; + +class LoginLvsPage extends StatelessWidget { + const LoginLvsPage({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return LoginForm(subtitle: LoginContent.lvs.subtitle); + } +} From 31ac375a1593191bca4e336c910721e49318e58c Mon Sep 17 00:00:00 2001 From: Nathan Codes <71457241+nathan179@users.noreply.github.com> Date: Mon, 8 Nov 2021 23:50:03 +0100 Subject: [PATCH 4/5] Last minutes changew --- lib/core/apis/lvs.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/apis/lvs.dart b/lib/core/apis/lvs.dart index 456061d2..5b6e5e24 100644 --- a/lib/core/apis/lvs.dart +++ b/lib/core/apis/lvs.dart @@ -40,7 +40,7 @@ class APILVS extends API { // url = ""; // } - var url = 'https://institutsaintpierresaintpaul28.la-vie-scolaire.fr'; + var url = 'https://institut.la-vie-scolaire.fr'; Map credentials = { 'url': Uri.parse(url), From 4baf7f27d8c31c6a8ea96ece94189c2e4e840b3a Mon Sep 17 00:00:00 2001 From: Nathan Demers Date: Wed, 17 Nov 2021 18:10:04 +0100 Subject: [PATCH 5/5] functionnal --- ios/Podfile.lock | 56 ++++++++++++++----------------- lib/core/apis/lvs.dart | 5 +-- lib/core/apis/lvs/lvs_client.dart | 4 +-- 3 files changed, 31 insertions(+), 34 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 672b8e1b..b25dcead 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,6 +1,4 @@ PODS: - - "app_settings (3.0.0+1)": - - Flutter - awesome_notifications (0.0.2): - Flutter - background_fetch (1.0.0-nullsafety.2): @@ -26,37 +24,36 @@ PODS: - Flutter - flutter_secure_storage (3.3.1): - Flutter - - FMDB (2.7.5): - - FMDB/standard (= 2.7.5) - - FMDB/standard (2.7.5) - geolocator (6.2.0): - Flutter + - MTBBarcodeScanner (5.0.11) - open_file (0.0.1): - Flutter - OrderedSet (5.0.0) - - package_info (0.0.1): + - package_info_plus (0.4.5): - Flutter - path_provider (0.0.1): - Flutter - "permission_handler (5.1.0+2)": - Flutter + - qr_code_scanner (0.2.0): + - Flutter + - MTBBarcodeScanner - Reachability (3.2) - - sensors (0.0.1): + - Shake (15.0.2) + - shake_flutter (0.0.1): - Flutter + - Shake (~> 15.0.0-rc) - share (0.0.1): - Flutter - shared_preferences (0.0.1): - Flutter - - sqflite (0.0.2): - - Flutter - - FMDB (>= 2.7.5) - url_launcher (0.0.1): - Flutter - webview_flutter (0.0.1): - Flutter DEPENDENCIES: - - app_settings (from `.symlinks/plugins/app_settings/ios`) - awesome_notifications (from `.symlinks/plugins/awesome_notifications/ios`) - background_fetch (from `.symlinks/plugins/background_fetch/ios`) - battery_optimization (from `.symlinks/plugins/battery_optimization/ios`) @@ -69,25 +66,24 @@ DEPENDENCIES: - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`) - geolocator (from `.symlinks/plugins/geolocator/ios`) - open_file (from `.symlinks/plugins/open_file/ios`) - - package_info (from `.symlinks/plugins/package_info/ios`) + - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - path_provider (from `.symlinks/plugins/path_provider/ios`) - permission_handler (from `.symlinks/plugins/permission_handler/ios`) - - sensors (from `.symlinks/plugins/sensors/ios`) + - qr_code_scanner (from `.symlinks/plugins/qr_code_scanner/ios`) + - shake_flutter (from `.symlinks/plugins/shake_flutter/ios`) - share (from `.symlinks/plugins/share/ios`) - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`) - - sqflite (from `.symlinks/plugins/sqflite/ios`) - url_launcher (from `.symlinks/plugins/url_launcher/ios`) - webview_flutter (from `.symlinks/plugins/webview_flutter/ios`) SPEC REPOS: trunk: - - FMDB + - MTBBarcodeScanner - OrderedSet - Reachability + - Shake EXTERNAL SOURCES: - app_settings: - :path: ".symlinks/plugins/app_settings/ios" awesome_notifications: :path: ".symlinks/plugins/awesome_notifications/ios" background_fetch: @@ -112,49 +108,49 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/geolocator/ios" open_file: :path: ".symlinks/plugins/open_file/ios" - package_info: - :path: ".symlinks/plugins/package_info/ios" + package_info_plus: + :path: ".symlinks/plugins/package_info_plus/ios" path_provider: :path: ".symlinks/plugins/path_provider/ios" permission_handler: :path: ".symlinks/plugins/permission_handler/ios" - sensors: - :path: ".symlinks/plugins/sensors/ios" + qr_code_scanner: + :path: ".symlinks/plugins/qr_code_scanner/ios" + shake_flutter: + :path: ".symlinks/plugins/shake_flutter/ios" share: :path: ".symlinks/plugins/share/ios" shared_preferences: :path: ".symlinks/plugins/shared_preferences/ios" - sqflite: - :path: ".symlinks/plugins/sqflite/ios" url_launcher: :path: ".symlinks/plugins/url_launcher/ios" webview_flutter: :path: ".symlinks/plugins/webview_flutter/ios" SPEC CHECKSUMS: - app_settings: d103828c9f5d515c4df9ee754dabd443f7cedcf3 awesome_notifications: 74462bc8e68b11f8235d78422266886759e9da61 background_fetch: 67b227578932e795dbe3ea6d3f7c006e45f3ce66 battery_optimization: 2cfe96337f15b292912db1d874c317962fda5635 connectivity_plus: 5f0eb61093bec56935f21a1699dd2758bc895587 ext_storage: 4eaf3a84d5594106e2ebcc2502248cfde53c8fa1 - Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c - flutter_file_dialog: 34ab8c55c460c69cb70e75a8d74bfe8b5c852824 + Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a + flutter_file_dialog: 4c014a45b105709a27391e266c277d7e588e9299 flutter_inappwebview: bfd58618f49dc62f2676de690fc6dcda1d6c3721 flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069 flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec - FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a geolocator: f5e3de65e241caba7ce3e8a618803387bda73384 + MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb open_file: 02eb5cb6b21264bd3a696876f5afbfb7ca4f4b7d OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c - package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62 + package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c permission_handler: ccb20a9fad0ee9b1314a52b70b76b473c5f8dab0 + qr_code_scanner: bb67d64904c3b9658ada8c402e8b4d406d5d796e Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96 - sensors: 84eb7a30e47a649e4172b71d6e81be614c280336 + Shake: 56265204198c497ceb35b614e32d22268af003d0 + shake_flutter: 8ed3dd3100e61d616d4eb1921c96cffa604f38fc share: 0b2c3e82132f5888bccca3351c504d0003b3b410 shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d - sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef webview_flutter: 9f491a9b5a66f2573946a389b2677987b0ff8c0b diff --git a/lib/core/apis/lvs.dart b/lib/core/apis/lvs.dart index 5b6e5e24..6de38171 100644 --- a/lib/core/apis/lvs.dart +++ b/lib/core/apis/lvs.dart @@ -29,7 +29,8 @@ class APILVS extends API { @override Future login(username, password, {Map? additionnalSettings}) async { - CustomLogger.saveLog(object: 'LVS', text: 'Login called'); + print('wooow'); + // CustomLogger.saveLog(object: 'LVS', text: 'Login called'); if (username == null) { username = ""; } @@ -40,7 +41,7 @@ class APILVS extends API { // url = ""; // } - var url = 'https://institut.la-vie-scolaire.fr'; + var url = 'https://institut'; Map credentials = { 'url': Uri.parse(url), diff --git a/lib/core/apis/lvs/lvs_client.dart b/lib/core/apis/lvs/lvs_client.dart index 19bb00f6..b5c81653 100644 --- a/lib/core/apis/lvs/lvs_client.dart +++ b/lib/core/apis/lvs/lvs_client.dart @@ -27,7 +27,7 @@ class LvsClient extends SessionClient { headers: {"Content-Type": "application/json"}, token: false, baseUrl: false); - CustomLogger.saveLog(object: 'LVS', text: rep.body.toString()); + // CustomLogger.saveLog(object: 'LVS', text: rep.body.toString()); if (rep.statusCode == 200) { CustomLogger.log('LVS', 'successful authentication for Lvs'); this.token = rep.headers['set-cookie'].toString(); @@ -104,7 +104,7 @@ class HwClient extends SessionClient { var entry = await Function.apply(credentials['method'], [credentials['args']]); var entry_url = jsonDecode(entry.body)['location']; - CustomLogger.saveLog(object: 'Entry Url for Hw', text: entry_url); + // CustomLogger.saveLog(object: 'Entry Url for Hw', text: entry_url); if (entry.statusCode == 200) { this.base_url = entry_url.substring(0, entry_url.indexOf('.fr') + 3) + '/eliot-textes';