Skip to content

Commit

Permalink
Merge branch 'develop' into fix/translate-day-title
Browse files Browse the repository at this point in the history
  • Loading branch information
DGoiana authored Oct 4, 2023
2 parents f731b81 + 7d54a9b commit f0c0d56
Show file tree
Hide file tree
Showing 34 changed files with 416 additions and 419 deletions.
28 changes: 22 additions & 6 deletions .github/workflows/deploy.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
on:
push:
branches: [ master, develop ]
branches: [master, develop]

jobs:
bump_version:
permissions:
actions: "write"
name: "Bump pubspec version"
runs-on: ubuntu-latest
env:
Expand All @@ -14,12 +16,19 @@ jobs:
with:
token: ${{ secrets.NIAEFEUPBOT_PAT }}

- name: Get develop hash
if: github.ref == 'refs/heads/master'
run: |
git fetch origin develop
current_hash=$(git rev-parse origin/develop)
echo "DEVELOPHASH=$current_hash" >> $GITHUB_ENV
- name: Bump flutter patch version
if: github.ref == 'refs/heads/develop'
if: github.ref == 'refs/heads/develop' || github.sha != env.DEVELOPHASH
run: perl -i -pe 's/^(\d+\.\d+\.)(\d+)(\+)(\d+)$/$1.($2+1).($3).($4+1)/e' ${{ env.APP_VERSION_PATH }}

- name: Bump flutter minor version
if: github.ref == 'refs/heads/master'
if: github.ref == 'refs/heads/master' && github.sha == env.DEVELOPHASH
run: perl -i -pe 's/^(\d+)(\.)(\d+)(\.)(\d+)(\+)(\d+)$/$1.($2).($3+1).($4).(0).($6).($7+1)/e' ${{ env.APP_VERSION_PATH }}

- name: Copy app version to pubspec
Expand All @@ -29,9 +38,16 @@ jobs:
with:
commit_message: "Bump app version [no ci]"

- name: Propagate master version bump to develop
- name: Propagate master version bump to develop if master version is aad
if: github.ref == 'refs/heads/master'
run: git push --force-with-lease origin HEAD:develop
run: |
git fetch origin develop
if [[ $(git diff --quiet HEAD~1 origin/develop) ]]; then
echo "Master version does not match develop version"
else
echo "Master version matches develop version"
git push --force-with-lease origin HEAD:develop
fi
build:
name: "Build App Bundle"
Expand All @@ -49,7 +65,7 @@ jobs:
- uses: actions/setup-java@v3
with:
java-version: ${{env.JAVA_VERSION}}
distribution: 'zulu'
distribution: "zulu"
- uses: subosito/flutter-action@v2
with:
flutter-version: ${{ env.FLUTTER_VERSION }}
Expand Down
2 changes: 1 addition & 1 deletion uni/app_version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.7.0+190
1.7.9+199
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,17 @@ import 'package:uni/model/entities/session.dart';
class AllCourseUnitsFetcher {
Future<List<CourseUnit>?> getAllCourseUnitsAndCourseAverages(
List<Course> courses,
Session session,
) async {
Session session, {
List<CourseUnit>? currentCourseUnits,
}) async {
final allCourseUnits = <CourseUnit>[];

for (final course in courses) {
try {
final courseUnits = await _getAllCourseUnitsAndCourseAveragesFromCourse(
course,
session,
currentCourseUnits: currentCourseUnits,
);
allCourseUnits.addAll(courseUnits.where((c) => c.enrollmentIsValid()));
} catch (e) {
Expand All @@ -30,8 +32,9 @@ class AllCourseUnitsFetcher {

Future<List<CourseUnit>> _getAllCourseUnitsAndCourseAveragesFromCourse(
Course course,
Session session,
) async {
Session session, {
List<CourseUnit>? currentCourseUnits,
}) async {
final url = '${NetworkRouter.getBaseUrl(course.faculty!)}'
'fest_geral.curso_percurso_academico_view';
final response = await NetworkRouter.getWithCookies(
Expand All @@ -41,6 +44,10 @@ class AllCourseUnitsFetcher {
},
session,
);
return parseCourseUnitsAndCourseAverage(response, course);
return parseCourseUnitsAndCourseAverage(
response,
course,
currentCourseUnits: currentCourseUnits,
);
}
}
18 changes: 13 additions & 5 deletions uni/lib/controller/fetchers/departures_fetcher.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import 'dart:convert';
import 'dart:io';

import 'package:html/dom.dart';
import 'package:html/parser.dart';
import 'package:http/http.dart' as http;
import 'package:http/io_client.dart' as http;
import 'package:uni/controller/networking/network_router.dart';
import 'package:uni/model/entities/bus.dart';
import 'package:uni/model/entities/bus_stop.dart';
Expand All @@ -13,12 +14,17 @@ class DeparturesFetcher {

final String _stopCode;
final BusStopData _stopData;
static final _client = http.IOClient(
HttpClient(context: SecurityContext())
..badCertificateCallback =
(cert, host, port) => host == 'www.stcp.pt' && port == 443,
);

Future<String> _getCSRFToken() async {
final url =
'https://www.stcp.pt/en/travel/timetables/?paragem=$_stopCode&t=smsbus';

final response = await http.get(url.toUri());
final response = await _client.get(url.toUri());
final htmlResponse = parse(response.body);

final scriptText = htmlResponse
Expand Down Expand Up @@ -50,7 +56,7 @@ class DeparturesFetcher {
final url =
'https://www.stcp.pt/pt/itinerarium/soapclient.php?codigo=$_stopCode&hash123=$csrfToken';

final response = await http.get(url.toUri());
final response = await _client.get(url.toUri());
final htmlResponse = parse(response.body);

final tableEntries =
Expand Down Expand Up @@ -111,7 +117,8 @@ class DeparturesFetcher {
// Search by approximate name
final url =
'https://www.stcp.pt/pt/itinerarium/callservice.php?action=srchstoplines&stopname=$stopCode';
final response = await http.post(url.toUri());

final response = await _client.post(url.toUri());
final json = jsonDecode(response.body) as List<dynamic>;
for (final busKey in json) {
final bus = busKey as Map<String, dynamic>;
Expand All @@ -134,7 +141,8 @@ class DeparturesFetcher {
static Future<List<Bus>> getBusesStoppingAt(String stop) async {
final url =
'https://www.stcp.pt/pt/itinerarium/callservice.php?action=srchstoplines&stopcode=$stop';
final response = await http.post(url.toUri());

final response = await _client.post(url.toUri());

final json = jsonDecode(response.body) as List<dynamic>;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:http/http.dart';
import 'package:tuple/tuple.dart';
import 'package:uni/controller/fetchers/schedule_fetcher/schedule_fetcher.dart';
import 'package:uni/controller/networking/network_router.dart';
import 'package:uni/controller/parsers/parser_schedule_html.dart';
Expand All @@ -20,10 +21,13 @@ class ScheduleFetcherHtml extends ScheduleFetcher {
@override
Future<List<Lecture>> getLectures(Session session, Profile profile) async {
final dates = getDates();
final urls = getEndpoints(session);
final lectureResponses = <Response>[];
for (final course in profile.courses) {
for (final url in urls) {
final baseUrls = NetworkRouter.getBaseUrlsFromSession(session);

final lectureResponses = <Tuple2<Response, String>>[];
for (final baseUrl in baseUrls) {
final url = '${baseUrl}hor_geral.estudantes_view';

for (final course in profile.courses) {
final response = await NetworkRouter.getWithCookies(
url,
{
Expand All @@ -34,13 +38,14 @@ class ScheduleFetcherHtml extends ScheduleFetcher {
},
session,
);
lectureResponses.add(response);
lectureResponses.add(Tuple2(response, baseUrl));
}
}

final lectures = await Future.wait(
lectureResponses
.map((response) => getScheduleFromHtml(response, session)),
lectureResponses.map(
(e) => getScheduleFromHtml(e.item1, session, e.item2),
),
).then((schedules) => schedules.expand((schedule) => schedule).toList());

lectures.sort((l1, l2) => l1.compare(l2));
Expand Down
13 changes: 10 additions & 3 deletions uni/lib/controller/parsers/parser_course_units.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:collection/collection.dart';
import 'package:html/parser.dart';
import 'package:http/http.dart' as http;
import 'package:uni/model/entities/course.dart';
Expand All @@ -6,8 +7,9 @@ import 'package:uni/utils/url_parser.dart';

List<CourseUnit> parseCourseUnitsAndCourseAverage(
http.Response response,
Course course,
) {
Course course, {
List<CourseUnit>? currentCourseUnits,
}) {
final document = parse(response.body);
final table = document.getElementById('tabelapercurso');
if (table == null) {
Expand Down Expand Up @@ -68,11 +70,16 @@ List<CourseUnit> parseCourseUnitsAndCourseAverage(
continue;
}

final matchingCurrentCourseUnit = currentCourseUnits
?.firstWhereOrNull((element) => element.code == codeName);

final courseUnit = CourseUnit(
schoolYear:
'${firstSchoolYear + yearIncrement}/${firstSchoolYear + yearIncrement + 1}',
occurrId: int.parse(occurId),
abbreviation: codeName,
code: codeName,
abbreviation: matchingCurrentCourseUnit?.abbreviation ??
codeName, // FIXME: this is not the abbreviation
status: status,
grade: grade,
ects: double.parse(ects),
Expand Down
13 changes: 9 additions & 4 deletions uni/lib/controller/parsers/parser_schedule.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,15 @@ Future<List<Lecture>> parseSchedule(http.Response response) async {
final secBegin = lecture['hora_inicio'] as int;
final subject = lecture['ucurr_sigla'] as String;
final typeClass = lecture['tipo'] as String;
// TODO(luisd): this was marked as a double on the develop branch but the
// tests' example api returns an integer. At the moment there are no
// classes so I can't test this.
final blocks = (lecture['aula_duracao'] as int) * 2;

// Note: aula_duracao is an integer when the lecture is 1 hour long
// or 2 hours long and so on. When the lecture is 1.5 hours long, it
// returns a double, with the value 1.5.
final lectureDuration = lecture['aula_duracao'];
final blocks = lectureDuration is double
? (lectureDuration * 2).toInt()
: (lectureDuration as int) * 2;

final room =
(lecture['sala_sigla'] as String).replaceAll(RegExp(r'\+'), '\n');
final teacher = lecture['doc_sigla'] as String;
Expand Down
31 changes: 23 additions & 8 deletions uni/lib/controller/parsers/parser_schedule_html.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import 'package:uni/model/entities/time_utilities.dart';
Future<List<Lecture>> getOverlappedClasses(
Session session,
Document document,
String faculty,
) async {
final lecturesList = <Lecture>[];

Expand All @@ -21,7 +22,7 @@ Future<List<Lecture>> getOverlappedClasses(
final subject = element.querySelector('acronym > a')?.text;
final typeClass = element
.querySelector('td[headers=t1]')
?.nodes[2]
?.nodes[1]
.text
?.trim()
.replaceAll(RegExp('[()]+'), '');
Expand All @@ -37,22 +38,33 @@ Future<List<Lecture>> getOverlappedClasses(
final classNumber = element.querySelector('td[headers=t6] > a')?.text;

try {
final startTimeList = startTime?.split(':') ?? [];
if (startTimeList.isEmpty) {
throw FormatException(
'Overlapping class $subject has invalid startTime',
);
}
final fullStartTime = monday.add(
Duration(
days: day,
hours: int.parse(startTime!.substring(0, 2)),
minutes: int.parse(startTime.substring(3, 5)),
hours: int.parse(startTimeList[0]),
minutes: int.parse(startTimeList[1]),
),
);
final link =
final href =
element.querySelector('td[headers=t6] > a')?.attributes['href'];

if (link == null) {
if (href == null) {
throw Exception();
}
final response = await NetworkRouter.getWithCookies(link, {}, session);
final response = await NetworkRouter.getWithCookies(
'$faculty$href',
{},
session,
);

final classLectures = await getScheduleFromHtml(response, session);
final classLectures =
await getScheduleFromHtml(response, session, faculty);

lecturesList.add(
classLectures
Expand Down Expand Up @@ -88,6 +100,7 @@ Future<List<Lecture>> getOverlappedClasses(
Future<List<Lecture>> getScheduleFromHtml(
http.Response response,
Session session,
String faculty,
) async {
final document = parse(response.body);
var semana = [0, 0, 0, 0, 0, 0];
Expand Down Expand Up @@ -148,7 +161,9 @@ Future<List<Lecture>> getScheduleFromHtml(
});

lecturesList
..addAll(await getOverlappedClasses(session, document))
..addAll(
await getOverlappedClasses(session, document, faculty),
)
..sort((a, b) => a.compare(b));

return lecturesList;
Expand Down
5 changes: 3 additions & 2 deletions uni/lib/model/entities/lecture.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,11 @@ class Lecture {
String classNumber,
int occurrId,
) {
final startTimeList = startTimeString.split(':');
final startTime = day.add(
Duration(
hours: int.parse(startTimeString.substring(0, 2)),
minutes: int.parse(startTimeString.substring(3, 5)),
hours: int.parse(startTimeList[0]),
minutes: int.parse(startTimeList[1]),
),
);
final endTime = startTime.add(Duration(minutes: 30 * blocks));
Expand Down
Loading

0 comments on commit f0c0d56

Please sign in to comment.