Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sigarra files api #963

Merged
merged 43 commits into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
be39832
Download feature
DGoiana Sep 23, 2023
30844be
Merge branch 'develop' into feature/sigarra-files
DGoiana Sep 24, 2023
cb4cc3c
Files page redesign
DGoiana Sep 24, 2023
80b4ec0
Merging
DGoiana Sep 24, 2023
560588f
Merge branch 'develop' into feature/sigarra-files
DGoiana Sep 25, 2023
3e057de
Pdf icon and open file support
DGoiana Sep 28, 2023
2c93601
Merge branch 'develop' into feature/sigarra-files
DGoiana Sep 28, 2023
40c2924
Merge branch 'develop' into feature/sigarra-files
DGoiana Sep 30, 2023
b3bbc32
Lint fix
DGoiana Oct 1, 2023
f2e2ae8
Merge branch 'develop' into feature/sigarra-files
DGoiana Oct 1, 2023
776f8a7
Merge
DGoiana Oct 1, 2023
7f2b715
Merge branch 'develop' into feature/sigarra-files
DGoiana Oct 4, 2023
041e365
Merge branch 'develop' into feature/sigarra-files
DGoiana Oct 5, 2023
3fccae6
Opening file fix and dependency update
DGoiana Oct 5, 2023
8ec07b6
Local storage integration
DGoiana Oct 5, 2023
22dba72
Card redesign
DGoiana Oct 5, 2023
9b0cbf5
Merge branch 'develop' into feature/sigarra-files
DGoiana Oct 11, 2023
4613ceb
File name changes
DGoiana Oct 13, 2023
c4b8d9c
Cache clean up flow
DGoiana Oct 20, 2023
6a23a9c
Merge branch 'develop' into feature/sigarra-files
DGoiana Oct 20, 2023
68ef599
Merge branch 'develop' into feature/sigarra-files
DGoiana Nov 18, 2023
c8608ad
Implementing text animation and improving cleaning flow
DGoiana Dec 1, 2023
32325d0
Fixing format
DGoiana Dec 1, 2023
c8c97b4
Catching a timeout error while opening files
DGoiana Dec 8, 2023
ad4991a
Merge branch 'develop' into feature/sigarra-files
DGoiana Dec 8, 2023
5a2df58
Lint fix
DGoiana Dec 8, 2023
d0d8703
Merge branch 'develop' into feature/sigarra-files
DGoiana Dec 9, 2023
7fc226b
Merge branch 'develop' into feature/sigarra-files
DGoiana Dec 24, 2023
ebbc3fe
Translating and abstracting code
DGoiana Jan 4, 2024
b889aba
Merging
DGoiana Jan 5, 2024
172483e
Merging
DGoiana Jan 6, 2024
de8ef9b
Fixing minor url launcher problem
DGoiana Jan 6, 2024
4da11d3
Formatting
DGoiana Jan 6, 2024
39109db
Lint fix
DGoiana Jan 6, 2024
633f182
Typo and synchronous getter
DGoiana Jan 8, 2024
7b70b72
Merge branch 'develop' into feature/sigarra-files
DGoiana Jan 26, 2024
bb86a22
Merge branch 'develop' into feature/sigarra-files
DGoiana Jan 29, 2024
2ebe982
Merge branch 'develop' into feature/sigarra-files
DGoiana Feb 2, 2024
5bf36c6
Solving files format
DGoiana Feb 2, 2024
9d64ed0
Merge branch 'develop' into feature/sigarra-files
DGoiana Feb 8, 2024
c6b8334
Encapsulating pulse animation
DGoiana Feb 9, 2024
87df88e
Handling different opening results
DGoiana Feb 12, 2024
fd5f6de
Merge branch 'develop' into feature/sigarra-files
DGoiana Feb 12, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions uni/lib/controller/cleanup.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,38 @@ Future<void> cleanupStoredData(BuildContext context) async {
directory.deleteSync(recursive: true);
}
}

Future<void> cleanupCachedFiles() async {
final lastCleanupDate = PreferencesController.getLastCleanUpDate();
final daysSinceLastCleanup =
DateTime.now().difference(lastCleanupDate).inDays;

if (daysSinceLastCleanup < 14) {
return;
}

final toCleanDirectory = await getApplicationDocumentsDirectory();
final threshold = DateTime.now().subtract(const Duration(days: 30));
final directories = toCleanDirectory.listSync(followLinks: false);

for (final directory in directories) {
if (directory is Directory) {
final files = directory.listSync(recursive: true, followLinks: false);

final oldFiles = files.where((file) {
try {
final fileDate = File(file.path).lastModifiedSync();
return fileDate.isBefore(threshold);
} catch (e) {
return false;
}
});

for (final file in oldFiles) {
await File(file.path).delete();
}
}
}

await PreferencesController.setLastCleanUpDate(DateTime.now());
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:uni/controller/fetchers/session_dependant_fetcher.dart';
import 'package:uni/controller/networking/network_router.dart';
import 'package:uni/controller/parsers/parser_course_unit_info.dart';
import 'package:uni/model/entities/course_units/course_unit_class.dart';
import 'package:uni/model/entities/course_units/course_unit_directory.dart';
import 'package:uni/model/entities/course_units/course_unit_sheet.dart';
import 'package:uni/model/entities/session.dart';

Expand All @@ -26,6 +27,27 @@ class CourseUnitsInfoFetcher implements SessionDependantFetcher {
return parseCourseUnitSheet(response);
}

Future<List<CourseUnitFileDirectory>> fetchCourseUnitFiles(
Session session,
int occurId,
) async {
final url = '${getEndpoints(session)[0]}mob_ucurr_geral.conteudos';
final response = await NetworkRouter.getWithCookies(
url,
{
'pv_ocorrencia_id': occurId.toString(),
},
session,
);
return parseFiles(response, session);
}

Future<String> getDownloadLink(
Session session,
) async {
return '${getEndpoints(session)[0]}conteudos_service.conteudos_cont';
}

Future<List<CourseUnitClass>> fetchCourseUnitClasses(
Session session,
int occurrId,
Expand Down
6 changes: 4 additions & 2 deletions uni/lib/controller/local_storage/file_offline_storage.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import 'package:uni/model/entities/session.dart';

/// The offline image storage location on the device.
Future<String> get _localPath async {
final directory = await getTemporaryDirectory();
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}

Expand Down Expand Up @@ -66,9 +66,11 @@ Future<File?> _downloadAndSaveFile(
Session? session,
Map<String, String>? headers,
) async {
final header = headers ?? <String, String>{};

final response = session == null
? await http.get(url.toUri(), headers: headers)
: await NetworkRouter.getWithCookies(url, {}, session);
: await NetworkRouter.getWithCookies(url, header, session);

if (response.statusCode == 200) {
return File(filePath).writeAsBytes(response.bodyBytes);
Expand Down
11 changes: 11 additions & 0 deletions uni/lib/controller/local_storage/preferences_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class PreferencesController {
static const String _isDataCollectionBannerViewedKey =
'data_collection_banner';
static const String _locale = 'app_locale';
static const String _lastCacheCleanUpDate = 'last_clean';
static const String _favoriteCards = 'favorite_cards';
static final List<FavoriteWidgetType> _defaultFavoriteCards = [
FavoriteWidgetType.schedule,
Expand Down Expand Up @@ -143,6 +144,16 @@ class PreferencesController {
);
}

static Future<void> setLastCleanUpDate(DateTime date) async {
await prefs.setString(_lastCacheCleanUpDate, date.toString());
}

static DateTime getLastCleanUpDate() {
final date =
prefs.getString(_lastCacheCleanUpDate) ?? DateTime.now().toString();
return DateTime.parse(date);
}

/// Deletes the user's student number and password.
static Future<void> removePersistentUserInfo() async {
await prefs.remove(_userNumber);
Expand Down
39 changes: 39 additions & 0 deletions uni/lib/controller/parsers/parser_course_unit_info.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,46 @@
import 'dart:convert';

import 'package:html/parser.dart';
import 'package:http/http.dart' as http;
import 'package:uni/controller/fetchers/course_units_fetcher/course_units_info_fetcher.dart';
import 'package:uni/model/entities/course_units/course_unit_class.dart';
import 'package:uni/model/entities/course_units/course_unit_directory.dart';
import 'package:uni/model/entities/course_units/course_unit_file.dart';
import 'package:uni/model/entities/course_units/course_unit_sheet.dart';
import 'package:uni/model/entities/session.dart';

Future<List<CourseUnitFileDirectory>> parseFiles(
http.Response response,
Session session,
) async {
final json = jsonDecode(response.body) as List<dynamic>;
final dirs = <CourseUnitFileDirectory>[];
if (json.isEmpty) return [];

for (var item in json) {
item = item as Map<String, dynamic>;
final files = <CourseUnitFile>[];
for (final file in item['ficheiros'] as List<dynamic>) {
if (file is Map<String, dynamic>) {
final fileName = file['nome'];
final fileDate = file['data_actualizacao'];
final fileCode = file['codigo'].toString();
final format = file['filename']
.toString()
.substring(file['filename'].toString().indexOf('.'));
final url = await CourseUnitsInfoFetcher().getDownloadLink(session);
final courseUnitFile = CourseUnitFile(
'${fileName}_$fileDate$format',
url,
fileCode,
);
files.add(courseUnitFile);
}
}
dirs.add(CourseUnitFileDirectory(item['nome'].toString(), files));
}
return dirs;
}

Future<CourseUnitSheet> parseCourseUnitSheet(http.Response response) async {
final document = parse(response.body);
Expand Down
13 changes: 13 additions & 0 deletions uni/lib/generated/intl/messages_en.dart
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ class MessageLookup extends MessageLookupByLibrary {
"D. Beatriz\'s stationery store"),
"dona_bia_building": MessageLookupByLibrary.simpleMessage(
"Floor -1 of building B (B-142)"),
"download_error":
MessageLookupByLibrary.simpleMessage("Error downloading the file"),
"ects": MessageLookupByLibrary.simpleMessage("ECTS performed: "),
"edit_off": MessageLookupByLibrary.simpleMessage("Edit"),
"edit_on": MessageLookupByLibrary.simpleMessage("Finish editing"),
Expand All @@ -130,6 +132,7 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("Deadline for next fee:"),
"fee_notification":
MessageLookupByLibrary.simpleMessage("Fee deadline"),
"files": MessageLookupByLibrary.simpleMessage("Files"),
"first_year_registration": MessageLookupByLibrary.simpleMessage(
"Year of first registration: "),
"floor": MessageLookupByLibrary.simpleMessage("Floor"),
Expand Down Expand Up @@ -165,6 +168,8 @@ class MessageLookup extends MessageLookupByLibrary {
"nav_title": m2,
"news": MessageLookupByLibrary.simpleMessage("News"),
"no": MessageLookupByLibrary.simpleMessage("No"),
"no_app": MessageLookupByLibrary.simpleMessage(
"No app found to open the file"),
"no_bus": MessageLookupByLibrary.simpleMessage("Don\'t miss any bus!"),
"no_bus_stops":
MessageLookupByLibrary.simpleMessage("No configured stops"),
Expand All @@ -187,6 +192,8 @@ class MessageLookup extends MessageLookupByLibrary {
"Looks like you are on vacation!"),
"no_favorite_restaurants":
MessageLookupByLibrary.simpleMessage("No favorite restaurants"),
"no_files_found":
MessageLookupByLibrary.simpleMessage("No files found"),
"no_info": MessageLookupByLibrary.simpleMessage(
"There is no information to display"),
"no_library_info": MessageLookupByLibrary.simpleMessage(
Expand Down Expand Up @@ -214,12 +221,16 @@ class MessageLookup extends MessageLookupByLibrary {
"occurrence_type":
MessageLookupByLibrary.simpleMessage("Type of occurrence"),
"of_month": MessageLookupByLibrary.simpleMessage("of"),
"open_error":
MessageLookupByLibrary.simpleMessage("Error opening the file"),
"other_links": MessageLookupByLibrary.simpleMessage("Other links"),
"pass_change_request": MessageLookupByLibrary.simpleMessage(
"For security reasons, passwords must be changed periodically."),
"password": MessageLookupByLibrary.simpleMessage("password"),
"pendent_references":
MessageLookupByLibrary.simpleMessage("Pending references"),
"permission_denied":
MessageLookupByLibrary.simpleMessage("Permission denied"),
"personal_assistance":
MessageLookupByLibrary.simpleMessage("Face-to-face assistance"),
"press_again":
Expand Down Expand Up @@ -253,6 +264,8 @@ class MessageLookup extends MessageLookupByLibrary {
"student_number":
MessageLookupByLibrary.simpleMessage("student number"),
"success": MessageLookupByLibrary.simpleMessage("Sent with success"),
"successful_open":
MessageLookupByLibrary.simpleMessage("File opened successfully"),
"tele_assistance":
MessageLookupByLibrary.simpleMessage("Telephone assistance"),
"tele_personal_assistance": MessageLookupByLibrary.simpleMessage(
Expand Down
15 changes: 14 additions & 1 deletion uni/lib/generated/intl/messages_pt_PT.dart
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("Papelaria D. Beatriz"),
"dona_bia_building": MessageLookupByLibrary.simpleMessage(
"Piso -1 do edifício B (B-142)"),
"download_error": MessageLookupByLibrary.simpleMessage(
"Erro ao descarregar o ficheiro"),
"ects": MessageLookupByLibrary.simpleMessage("ECTS realizados: "),
"edit_off": MessageLookupByLibrary.simpleMessage("Editar"),
"edit_on": MessageLookupByLibrary.simpleMessage("Concluir edição"),
Expand All @@ -129,6 +131,7 @@ class MessageLookup extends MessageLookupByLibrary {
"Data limite próxima prestação:"),
"fee_notification":
MessageLookupByLibrary.simpleMessage("Data limite de propina"),
"files": MessageLookupByLibrary.simpleMessage("Ficheiros"),
"first_year_registration":
MessageLookupByLibrary.simpleMessage("Ano da primeira inscrição: "),
"floor": MessageLookupByLibrary.simpleMessage("Piso"),
Expand All @@ -152,7 +155,7 @@ class MessageLookup extends MessageLookupByLibrary {
"library_occupation":
MessageLookupByLibrary.simpleMessage("Ocupação da Biblioteca"),
"load_error": MessageLookupByLibrary.simpleMessage(
"Aconteceu um erro ao carregar os dados"),
"Erro ao carregar a informação"),
"loading_terms": MessageLookupByLibrary.simpleMessage(
"Carregando os Termos e Condições..."),
"login": MessageLookupByLibrary.simpleMessage("Entrar"),
Expand All @@ -165,6 +168,8 @@ class MessageLookup extends MessageLookupByLibrary {
"nav_title": m2,
"news": MessageLookupByLibrary.simpleMessage("Notícias"),
"no": MessageLookupByLibrary.simpleMessage("Não"),
"no_app": MessageLookupByLibrary.simpleMessage(
"Nenhuma aplicação encontrada para abrir o ficheiro"),
"no_bus": MessageLookupByLibrary.simpleMessage(
"Não percas nenhum autocarro!"),
"no_bus_stops": MessageLookupByLibrary.simpleMessage(
Expand All @@ -189,6 +194,8 @@ class MessageLookup extends MessageLookupByLibrary {
MessageLookupByLibrary.simpleMessage("Parece que estás de férias!"),
"no_favorite_restaurants":
MessageLookupByLibrary.simpleMessage("Sem restaurantes favoritos"),
"no_files_found":
MessageLookupByLibrary.simpleMessage("Nenhum ficheiro encontrado"),
"no_info": MessageLookupByLibrary.simpleMessage(
"Não existem informações para apresentar"),
"no_library_info":
Expand Down Expand Up @@ -216,12 +223,16 @@ class MessageLookup extends MessageLookupByLibrary {
"occurrence_type":
MessageLookupByLibrary.simpleMessage("Tipo de ocorrência"),
"of_month": MessageLookupByLibrary.simpleMessage("de"),
"open_error":
MessageLookupByLibrary.simpleMessage("Erro ao abrir o ficheiro"),
"other_links": MessageLookupByLibrary.simpleMessage("Outros links"),
"pass_change_request": MessageLookupByLibrary.simpleMessage(
"Por razões de segurança, as palavras-passe têm de ser alteradas periodicamente."),
"password": MessageLookupByLibrary.simpleMessage("palavra-passe"),
"pendent_references":
MessageLookupByLibrary.simpleMessage("Referências pendentes"),
"permission_denied":
MessageLookupByLibrary.simpleMessage("Sem permissão"),
"personal_assistance":
MessageLookupByLibrary.simpleMessage("Atendimento presencial"),
"press_again": MessageLookupByLibrary.simpleMessage(
Expand Down Expand Up @@ -255,6 +266,8 @@ class MessageLookup extends MessageLookupByLibrary {
"student_number":
MessageLookupByLibrary.simpleMessage("número de estudante"),
"success": MessageLookupByLibrary.simpleMessage("Enviado com sucesso"),
"successful_open":
MessageLookupByLibrary.simpleMessage("Ficheiro aberto com sucesso"),
"tele_assistance":
MessageLookupByLibrary.simpleMessage("Atendimento telefónico"),
"tele_personal_assistance": MessageLookupByLibrary.simpleMessage(
Expand Down
Loading
Loading