Skip to content

Commit

Permalink
Add logout button to dualis; Add cancelable requests to dualis
Browse files Browse the repository at this point in the history
  • Loading branch information
Bennik2000 committed Aug 12, 2020
1 parent 1565c89 commit 3a11e85
Show file tree
Hide file tree
Showing 20 changed files with 496 additions and 121 deletions.
Binary file added fonts/CustomIcons.ttf
Binary file not shown.
2 changes: 0 additions & 2 deletions lib/common/appstart/app_initializer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ import 'package:dhbwstudentapp/common/appstart/localization_initialize.dart';
import 'package:dhbwstudentapp/common/appstart/notification_schedule_changed_initialize.dart';
import 'package:dhbwstudentapp/common/appstart/notifications_initialize.dart';
import 'package:dhbwstudentapp/common/appstart/service_injector.dart';
import 'package:dhbwstudentapp/common/util/platform_util.dart';
import 'package:dhbwstudentapp/schedule/business/schedule_source_setup.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:kiwi/kiwi.dart';

bool isInitialized = false;
Expand Down
4 changes: 2 additions & 2 deletions lib/common/background/background_work_scheduler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import 'package:dhbwstudentapp/common/background/work_scheduler_service.dart';
import 'package:kiwi/kiwi.dart';
import 'package:workmanager/workmanager.dart';

class BackgroundWorkScheduler extends WorkSchedulerService{
class BackgroundWorkScheduler extends WorkSchedulerService {
Map<String, TaskCallback> _taskCallbacks = {};

BackgroundWorkScheduler() {
Expand Down Expand Up @@ -74,7 +74,7 @@ class BackgroundWorkScheduler extends WorkSchedulerService{

await initializeApp(true);

BackgroundWorkScheduler scheduler = KiwiContainer().resolve();
WorkSchedulerService scheduler = KiwiContainer().resolve();

await scheduler.executeTask(taskId);
} catch (e, trace) {
Expand Down
9 changes: 9 additions & 0 deletions lib/common/data/preferences/preferences_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class PreferencesProvider {
static const String DualisStoreCredentials = "StoreDualisCredentials";
static const String DualisUsername = "DualisUsername";
static const String DualisPassword = "DualisPassword";
static const String LastViewedSemester = "LastViewedSemester";

final PreferencesAccess _preferencesAccess;
final SecureStorageAccess _secureStorageAccess;
Expand Down Expand Up @@ -108,4 +109,12 @@ class PreferencesProvider {
Future<void> setStoreDualisCredentials(bool value) async {
await _preferencesAccess.set(DualisStoreCredentials, value ?? false);
}

Future<String> getLastViewedSemester() async {
return await _preferencesAccess.get<String>(LastViewedSemester);
}

Future<void> setLastViewedSemester(String lastViewedSemester) async {
await _preferencesAccess.set(LastViewedSemester, lastViewedSemester);
}
}
29 changes: 29 additions & 0 deletions lib/common/ui/custom_icons_icons.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/// Flutter icons CustomIcons
/// Copyright (C) 2020 by original authors @ fluttericon.com, fontello.com
/// This font was generated by FlutterIcon.com, which is derived from Fontello.
///
/// To use this font, place it in your fonts/ directory and include the
/// following in your pubspec.yaml
///
/// flutter:
/// fonts:
/// - family: CustomIcons
/// fonts:
/// - asset: fonts/CustomIcons.ttf
///
///
/// * Font Awesome 4, Copyright (C) 2016 by Dave Gandy
/// Author: Dave Gandy
/// License: SIL ()
/// Homepage: http://fortawesome.github.com/Font-Awesome/
///
import 'package:flutter/widgets.dart';

class CustomIcons {
CustomIcons._();

static const _kFontFam = 'CustomIcons';
static const _kFontPkg = null;

static const IconData logout = IconData(0xe800, fontFamily: _kFontFam, fontPackage: _kFontPkg);
}
27 changes: 27 additions & 0 deletions lib/common/util/cancelable_mutex.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import 'package:mutex/mutex.dart';
import 'cancellation_token.dart';

class CancelableMutex {
Mutex _mutex = Mutex();
CancellationToken _token;
CancellationToken get token => _token;

void cancel() {
_token?.cancel();
}

Future acquireAndCancelOther() async {
if (!(token?.isCancelled() ?? false)) {
token?.cancel();
}

_token = CancellationToken();

await _mutex.acquire();
}

void release() {
_mutex.release();
_token = null;
}
}
4 changes: 1 addition & 3 deletions lib/common/util/cancellation_token.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class CancellationToken {

void throwIfCancelled() {
if (_isCancelled) {
throw TokenCancelledException;
throw OperationCancelledException();
}
}

Expand All @@ -25,6 +25,4 @@ class CancellationToken {
}
}

class TokenCancelledException implements Exception {}

class OperationCancelledException implements Exception {}
42 changes: 32 additions & 10 deletions lib/dualis/service/cache_dualis_service_decorator.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:dhbwstudentapp/common/util/cancellation_token.dart';
import 'package:dhbwstudentapp/dualis/model/module.dart';
import 'package:dhbwstudentapp/dualis/model/semester.dart';
import 'package:dhbwstudentapp/dualis/model/study_grades.dart';
Expand All @@ -17,55 +18,68 @@ class CacheDualisServiceDecorator extends DualisService {
CacheDualisServiceDecorator(this._service);

@override
Future<bool> login(String username, String password) {
return _service.login(username, password);
Future<bool> login(
String username,
String password, [
CancellationToken cancellationToken,
]) {
return _service.login(username, password, cancellationToken);
}

@override
Future<List<Module>> queryAllModules() async {
Future<List<Module>> queryAllModules([
CancellationToken cancellationToken,
]) async {
if (_allModulesCached != null) {
return Future.value(_allModulesCached);
}

var allModules = await _service.queryAllModules();
var allModules = await _service.queryAllModules(cancellationToken);

_allModulesCached = allModules;

return allModules;
}

@override
Future<Semester> querySemester(String name) async {
Future<Semester> querySemester(
String name, [
CancellationToken cancellationToken,
]) async {
if (_semestersCached.containsKey(name)) {
return Future.value(_semestersCached[name]);
}
var semester = await _service.querySemester(name);
var semester = await _service.querySemester(name, cancellationToken);

_semestersCached[name] = semester;

return semester;
}

@override
Future<List<String>> querySemesterNames() async {
Future<List<String>> querySemesterNames([
CancellationToken cancellationToken,
]) async {
if (_allSemesterNamesCached != null) {
return Future.value(_allSemesterNamesCached);
}

var allSemesterNames = await _service.querySemesterNames();
var allSemesterNames = await _service.querySemesterNames(cancellationToken);

_allSemesterNamesCached = allSemesterNames;

return allSemesterNames;
}

@override
Future<StudyGrades> queryStudyGrades() async {
Future<StudyGrades> queryStudyGrades([
CancellationToken cancellationToken,
]) async {
if (_studyGradesCached != null) {
return Future.value(_studyGradesCached);
}

var studyGrades = await _service.queryStudyGrades();
var studyGrades = await _service.queryStudyGrades(cancellationToken);

_studyGradesCached = studyGrades;

Expand All @@ -78,4 +92,12 @@ class CacheDualisServiceDecorator extends DualisService {
_semestersCached = {};
_studyGradesCached = null;
}

@override
Future<void> logout([
CancellationToken cancellationToken,
]) async {
await _service.logout(cancellationToken);
clearCache();
}
}
99 changes: 76 additions & 23 deletions lib/dualis/service/dualis_scraper.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:dhbwstudentapp/common/util/cancellation_token.dart';
import 'package:dhbwstudentapp/dualis/model/study_grades.dart';
import 'package:dhbwstudentapp/dualis/service/dualis_session.dart';
import 'package:dhbwstudentapp/dualis/service/dualis_website_model.dart';
Expand All @@ -13,10 +14,19 @@ import 'package:http/http.dart';
class DualisScraper {
static final String dualisEndpoint = "https://dualis.dhbw.de";

Future<DualisSession> login(String user, String password) async {
Future<DualisSession> login(
String user,
String password, [
CancellationToken cancellationToken,
]) async {
var session = DualisSession();

var loginResponse = await _makeLoginRequest(user, password, session);
var loginResponse = await _makeLoginRequest(
user,
password,
session,
cancellationToken,
);

if (loginResponse.statusCode != 200) return null;
if (!loginResponse.headers.containsKey("refresh")) return null;
Expand All @@ -29,7 +39,11 @@ class DualisScraper {

if (refreshUrl == null) return null;

var redirectResponse = await session.get(refreshUrl);
var redirectResponse = await session.get(
refreshUrl,
cancellationToken,
);

var redirectUrl = LoginRedirectUrlExtract().readRedirectUrl(
redirectResponse,
dualisEndpoint,
Expand All @@ -44,8 +58,9 @@ class DualisScraper {
Future<Response> _makeLoginRequest(
String user,
String password,
DualisSession session,
) async {
DualisSession session, [
CancellationToken cancellationToken,
]) async {
var loginUrl = dualisEndpoint + "/scripts/mgrqispi.dll";

var data = {
Expand All @@ -59,12 +74,22 @@ class DualisScraper {
"menu_type": "classic",
};

var loginResponse = await session.post(loginUrl, data);
var loginResponse = await session.post(
loginUrl,
data,
cancellationToken,
);
return loginResponse;
}

Future<DualisUrls> requestMainPage(DualisSession session) async {
var mainPageResponse = await session.get(session.mainPageUrl);
Future<DualisUrls> requestMainPage(
DualisSession session, [
CancellationToken cancellationToken,
]) async {
var mainPageResponse = await session.get(
session.mainPageUrl,
cancellationToken,
);

return UrlsFromMainPageExtract().parseMainPage(
mainPageResponse,
Expand All @@ -74,18 +99,26 @@ class DualisScraper {

Future<List<DualisModule>> loadAllModules(
DualisSession session,
String studentResultsUrl,
) async {
var allModulesPageResponse = await session.get(studentResultsUrl);
String studentResultsUrl, [
CancellationToken cancellationToken,
]) async {
var allModulesPageResponse = await session.get(
studentResultsUrl,
cancellationToken,
);

return AllModulesExtract().extractAllModules(allModulesPageResponse);
}

Future<List<DualisExam>> loadModuleExams(
String moduleDetailsUrl,
DualisSession session,
) async {
var detailsResponse = await session.get(moduleDetailsUrl);
DualisSession session, [
CancellationToken cancellationToken,
]) async {
var detailsResponse = await session.get(
moduleDetailsUrl,
cancellationToken,
);

return ExamsFromModuleDetailsExtract().extractExamsFromModuleDetails(
detailsResponse,
Expand All @@ -94,9 +127,13 @@ class DualisScraper {

Future<List<DualisSemester>> loadSemesters(
DualisSession session,
DualisUrls mainPage,
) async {
var courseResultsResponse = await session.get(mainPage.courseResultUrl);
DualisUrls mainPage, [
CancellationToken cancellationToken,
]) async {
var courseResultsResponse = await session.get(
mainPage.courseResultUrl,
cancellationToken,
);

return SemestersFromCourseResultPageExtract()
.extractSemestersFromCourseResults(
Expand All @@ -107,21 +144,37 @@ class DualisScraper {

Future<List<DualisModule>> loadSemesterModules(
DualisSession session,
String semesterCourseResultsUrl,
) async {
var coursePage = await session.get(semesterCourseResultsUrl);
String semesterCourseResultsUrl, [
CancellationToken cancellationToken,
]) async {
var coursePage = await session.get(
semesterCourseResultsUrl,
cancellationToken,
);

return ModulesFromCourseResultPageExtract()
.extractModulesFromCourseResultPage(coursePage, dualisEndpoint);
}

Future<StudyGrades> loadStudyGrades(
DualisSession session,
String studentResultsUrl,
) async {
var studentsResultsPage = await session.get(studentResultsUrl);
String studentResultsUrl, [
CancellationToken cancellationToken,
]) async {
var studentsResultsPage = await session.get(
studentResultsUrl,
cancellationToken,
);

return StudyGradesFromStudentResultsPageExtract()
.extractStudyGradesFromStudentsResultsPage(studentsResultsPage);
}

Future<void> logout(
DualisSession session,
DualisUrls urls, [
CancellationToken cancellationToken,
]) async {
await session.get(urls.logoutUrl, cancellationToken);
}
}
Loading

0 comments on commit 3a11e85

Please sign in to comment.