From 28a3137a7d52c2bbfa919572a20d44206823c6e0 Mon Sep 17 00:00:00 2001 From: Fareez Iqmal <60868965+iqfareez@users.noreply.github.com> Date: Wed, 7 Aug 2024 08:41:01 +0800 Subject: [PATCH] :bug: Improve day parsing. Closes #10 & #8 --- CHANGELOG.md | 7 ++- README.md | 7 +-- lib/src/albiruni_base.dart | 4 +- lib/src/util/date_time_util.dart | 75 +++++++++++++------------- pubspec.yaml | 7 +-- test/src/util/date_time_util_test.dart | 46 ++++++++-------- 6 files changed, 76 insertions(+), 70 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 61832e1..93f2a77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ +## 1.4.1 + +- :bug: Fix issue where some compounded days format (eg: `TWTH`) could not be parse. See [#8](https://github.com/iiumschedule/albiruni/issues/8), [#10](https://github.com/iiumschedule/albiruni/issues/10) +- :pencil2: Update some classes documentation + ## 1.4.0 -- Upgrade package [http](https://pub.dev/packages/http) to `1.1.0` (upgrade major version, might be breaking changes) +- :arrow_up: Upgrade package [http](https://pub.dev/packages/http) to `1.1.0` (upgrade major version, might be breaking changes) ## 1.3.0 diff --git a/README.md b/README.md index 1fe5552..676fc92 100644 --- a/README.md +++ b/README.md @@ -119,10 +119,11 @@ I think that's it for the basic usage of this library, of course, you can always This happens when the albiruni server has some [certificate issues](https://github.com/iqfareez/iium_schedule/issues/10#issuecomment-1086550494). Some clients might reject the requests. If you're in development, try [this answer from SO](https://stackoverflow.com/a/61312927/13617136). -## List of available kulliyyah (as of 31/7/2022) +## List of available kulliyyah (as of 7 August 2024) | Code | Name | | :-----: | ------------------------------------------------------- | +| `IRKHS` | AHAS KIRKHS | | `KAHS` | ALLIED HEALTH SCIENCES | | `AED` | ARCHITECTURE | | `BRIDG` | BRIDGING PROGRAMME | @@ -134,14 +135,14 @@ I think that's it for the basic usage of this library, of course, you can always | `ECONS` | ENMS | | `KICT` | ICT | | `IHART` | INTERNATIONAL INSTITUTE FOR HALAL RESEARCH AND TRAINING | -| `IRKHS` | IRKHS | | `IIBF` | ISLAMIC BANKING AND FINANCE | | `ISTAC` | ISTAC | -| `KLM` | KLM | +| `KLM` | KSTCL KLM | | `LAWS` | LAWS | | `MEDIC` | MEDICINE | | `NURS` | NURSING | | `PHARM` | PHARMACY | +| `PLNET` | PLANETARY SURVIVAL FOR SUSTAINABLE WELL-BEING | | `KOS` | SCIENCE | | `SC4SH` | SEJAHTERA CENTRE FOR SUSTAINABILTY AND HUMANITY | diff --git a/lib/src/albiruni_base.dart b/lib/src/albiruni_base.dart index 03edfec..9b17521 100644 --- a/lib/src/albiruni_base.dart +++ b/lib/src/albiruni_base.dart @@ -44,7 +44,9 @@ class Albiruni { final _baseUrl = 'albiruni.iium.edu.my/myapps/StudentOnline/schedule1.php'; final _proxyUrl = 'corsproxyuia.up.railway.app/'; - /// Fetch a list of subjects based on your specification. + /// Fetch a list of subjects for the given [kulliyah]. + /// + /// See list of [kulliyah] here: https://iiumschedule.iqfareez.com/docs/devs/albiruni#list-of-available-kulliyyah (Look at column "keys") /// /// [course] is optional. Example: "AAD 3190", "MCTE 3312". The 4 digit number can be omitted. Example: "EECE". /// diff --git a/lib/src/util/date_time_util.dart b/lib/src/util/date_time_util.dart index ae5449b..a86141c 100644 --- a/lib/src/util/date_time_util.dart +++ b/lib/src/util/date_time_util.dart @@ -3,8 +3,9 @@ import 'package:intl/intl.dart'; /// Utility classes to parse raw data to proper data class DateTimeUtil { - /// Map day in String to integers - static int _dayMap(String day) { + /// Map day in String to DateTime day integer + /// Return null if cannot parse + static int? _dayMap(String day) { switch (day) { case 'MON': case 'M': @@ -26,54 +27,52 @@ class DateTimeUtil { case 'SUN': return DateTime.sunday; default: - throw DayTimeParseException(message: "Unable to parse day: $day"); + return null; } } - /// Parse the given raw day format and return a Day number + /// Parse the given raw day format and return a Day number. If failed to parse, + /// it will return empty list /// /// Eg: Given 'MON', return [DateTime.monday] static List parseDays(String rawDay) { rawDay = rawDay.trim(); // remove all whitespaces (just in case) + // Attempt to parse single day + final resultDay = _dayMap(rawDay); + if (resultDay != null) return [resultDay]; + + // Attempt to hyphen-seperated compound days + var days = rawDay.split('-'); // split 'M-W' to ['M', 'W'] + final resultDays = + days.map((e) => _dayMap(e)).where((e) => e != null).toList(); + if (resultDays.isNotEmpty) return resultDays.map((e) => e!).toList(); + + // Attempt to non-hyphen-seperated compound days + // check for special cases (https://github.com/iqfareez/albiruni/issues/1) - if (rawDay == 'MTW') { - return [ - DateTime.monday, - DateTime.tuesday, - DateTime.wednesday, - ]; - } - if (rawDay == 'MTWTH') { - return [ - DateTime.monday, - DateTime.tuesday, - DateTime.wednesday, - DateTime.thursday - ]; - } - if (rawDay == 'MTWTHF') { - return [ - DateTime.monday, - DateTime.tuesday, - DateTime.wednesday, - DateTime.thursday, - DateTime.friday - ]; - } - if (rawDay == 'MTTHF') { - return [ - DateTime.monday, - DateTime.tuesday, - DateTime.thursday, - DateTime.friday - ]; + List complexCompoundResult = []; + int i = 0; + + while (i < rawDay.length) { + // Check for two-character day codes first (like 'TH' or 'SU') + if (i < rawDay.length - 1 && + _dayMap(rawDay.substring(i, i + 2)) != null) { + complexCompoundResult.add(_dayMap(rawDay.substring(i, i + 2))!); + i += 2; + } else { + // Otherwise, check for one-character day codes + if (_dayMap(rawDay[i]) != null) { + complexCompoundResult.add(_dayMap(rawDay[i])!); + } + i += 1; + } } - // check for other days - var days = rawDay.split('-'); // split 'M-W' to ['M', 'W'] - return days.map((e) => _dayMap(e)).toList(); + if (complexCompoundResult.isNotEmpty) return complexCompoundResult; + + return []; } /// Parse weirdly formatted time in String to [DayTime] object diff --git a/pubspec.yaml b/pubspec.yaml index a74ad6e..ba57845 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: albiruni -description: A wrapper to easily access IIUM's Course Schedule website data. -version: 1.4.0 +description: A wrapper to easily access IIUM's Course Schedule data. +version: 1.4.1 repository: https://github.com/iqfareez/albiruni issue_tracker: https://github.com/iqfareez/albiruni/issues topics: @@ -14,8 +14,9 @@ environment: sdk: ">=3.0.0 <4.0.0" dev_dependencies: - lints: ^2.0.1 + lints: ^4.0.0 test: ^1.16.0 + dependencies: html: ^0.15.0 http: ^1.1.0 diff --git a/test/src/util/date_time_util_test.dart b/test/src/util/date_time_util_test.dart index a24f26d..7933299 100644 --- a/test/src/util/date_time_util_test.dart +++ b/test/src/util/date_time_util_test.dart @@ -1,14 +1,9 @@ import 'package:albiruni/src/util/date_time_util.dart'; -import 'package:albiruni/src/util/exceptions.dart'; import 'package:test/test.dart'; void main() { - group('Day parsing', () { - test('Parse days from raw', () { - /** - * Single day - */ - + group('Day Parsing', () { + test('Single Day Parse', () { var rawDay = 'MON'; var resDay = DateTimeUtil.parseDays(rawDay); expect(resDay, [DateTime.monday]); @@ -16,13 +11,11 @@ void main() { rawDay = 'FRI'; resDay = DateTimeUtil.parseDays(rawDay); expect(resDay, [DateTime.friday]); + }); - /** - * Compound days - */ - - rawDay = 'M-W'; // Monday & Wednesday - resDay = DateTimeUtil.parseDays(rawDay); + test('Compounded Days Parse (With hyphen)', () { + var rawDay = 'M-W'; // Monday & Wednesday + var resDay = DateTimeUtil.parseDays(rawDay); expect(resDay, [DateTime.monday, DateTime.wednesday]); rawDay = 'T-TH'; // Tuesday & Thursday @@ -49,12 +42,11 @@ void main() { DateTime.friday, ]), ); + }); - /** - * Special cases - */ - rawDay = 'MTWTH'; - resDay = DateTimeUtil.parseDays(rawDay); + test('Compounded Days Parse (Without hyphen)', () { + var rawDay = 'MTWTH'; + var resDay = DateTimeUtil.parseDays(rawDay); expect(resDay, [ DateTime.monday, DateTime.tuesday, @@ -80,12 +72,18 @@ void main() { DateTime.wednesday, ]); - /** - * Invalid - */ - rawDay = 'MEOW'; - expect(() => DateTimeUtil.parseDays(rawDay), - throwsA(isA())); + rawDay = 'TWTH'; + resDay = DateTimeUtil.parseDays(rawDay); + expect(resDay, [ + DateTime.tuesday, + DateTime.wednesday, + DateTime.thursday, + ]); + }); + + test('Invalid day parse', () { + var rawDay = 'XYZ'; + expect(DateTimeUtil.parseDays(rawDay), []); }); });