migrated custom timetable events to Marianum-Connect and refactored push notification handling
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:localstore/localstore.dart';
|
||||
|
||||
import '../../../../model/account_data.dart';
|
||||
import '../../../demo/demo_mode.dart';
|
||||
import '../../../mhsl/custom_timetable_event/get/get_custom_timetable_event.dart';
|
||||
import '../../../mhsl/custom_timetable_event/get/get_custom_timetable_event_params.dart';
|
||||
import '../../../mhsl/custom_timetable_event/remove/remove_custom_timetable_event.dart';
|
||||
import '../../../mhsl/custom_timetable_event/remove/remove_custom_timetable_event_params.dart';
|
||||
import 'timetable_custom_events_add.dart';
|
||||
|
||||
/// One-time migration of the user's custom timetable events from the legacy
|
||||
/// MHSL backend to Marianum-Connect. Runs at most once per install, guarded by
|
||||
/// a persisted flag.
|
||||
///
|
||||
/// The MHSL identity is `sha512(username:password)` — computed here exactly as
|
||||
/// the app always did, so the fetch matches the user's own events perfectly.
|
||||
/// Each event is POSTed to Marianum-Connect and then deleted from MHSL, which
|
||||
/// makes the whole run idempotent and resumable: a re-run after a mid-way
|
||||
/// failure only sees the events that were not yet moved, so nothing is
|
||||
/// duplicated. The flag is set only once MHSL reports no remaining events.
|
||||
class CustomEventsMigration {
|
||||
static const String _collection = 'MarianumMobile';
|
||||
static const String _document = 'customEventsMigration';
|
||||
static const String _doneKey = 'migratedToMc';
|
||||
|
||||
const CustomEventsMigration._();
|
||||
|
||||
static Future<void> runOnce() async {
|
||||
if (DemoMode.active) return;
|
||||
if (await _isDone()) return;
|
||||
|
||||
try {
|
||||
final response = await GetCustomTimetableEvent(
|
||||
GetCustomTimetableEventParams(AccountData().getUserSecret()),
|
||||
).run();
|
||||
|
||||
for (final event in response.events) {
|
||||
await TimetableCustomEventsAdd().run(event);
|
||||
await RemoveCustomTimetableEvent(
|
||||
RemoveCustomTimetableEventParams(event.id),
|
||||
).run();
|
||||
}
|
||||
|
||||
await _markDone();
|
||||
log('Custom events migration: moved ${response.events.length} event(s) to Marianum-Connect.');
|
||||
} catch (e) {
|
||||
// Leave the flag unset so the next launch retries; the delete-after-post
|
||||
// above keeps a partial run duplicate-free.
|
||||
log('Custom events migration failed, will retry on next launch: $e');
|
||||
}
|
||||
}
|
||||
|
||||
static Future<bool> _isDone() async {
|
||||
final data = await Localstore.instance
|
||||
.collection(_collection)
|
||||
.doc(_document)
|
||||
.get();
|
||||
return data != null && data[_doneKey] == true;
|
||||
}
|
||||
|
||||
static Future<void> _markDone() async {
|
||||
await Localstore.instance.collection(_collection).doc(_document).set({
|
||||
_doneKey: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
import 'package:dio/dio.dart';
|
||||
|
||||
import '../../../mhsl/custom_timetable_event/custom_timetable_event.dart';
|
||||
import '../../errors/marianumconnect_error.dart';
|
||||
import '../../marianumconnect_api.dart';
|
||||
import '../../marianumconnect_endpoint.dart';
|
||||
|
||||
class TimetableCustomEventsAdd {
|
||||
final Dio _dio;
|
||||
|
||||
TimetableCustomEventsAdd({Dio? dio}) : _dio = dio ?? MarianumConnectApi.dio();
|
||||
|
||||
Future<void> run(CustomTimetableEvent event) async {
|
||||
try {
|
||||
await _dio.post<void>(
|
||||
MarianumConnectEndpoint.resolve('timetable/custom-events'),
|
||||
data: event.toJson(),
|
||||
);
|
||||
} on DioException catch (e) {
|
||||
throw mapMarianumConnectError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
import '../../../mhsl/custom_timetable_event/get/get_custom_timetable_event_response.dart';
|
||||
import '../../../request_cache.dart';
|
||||
import 'timetable_custom_events_get.dart';
|
||||
|
||||
class TimetableCustomEventsCache
|
||||
extends SimpleCache<GetCustomTimetableEventResponse> {
|
||||
TimetableCustomEventsCache({super.onUpdate, super.onError, super.renew})
|
||||
: super(
|
||||
cacheTime: RequestCache.cacheMinute,
|
||||
loader: () => TimetableCustomEventsGet().run(),
|
||||
fromJson: GetCustomTimetableEventResponse.fromJson,
|
||||
) {
|
||||
start('customTimetableEvents');
|
||||
}
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
import 'package:dio/dio.dart';
|
||||
|
||||
import '../../../mhsl/custom_timetable_event/get/get_custom_timetable_event_response.dart';
|
||||
import '../../errors/marianumconnect_error.dart';
|
||||
import '../../marianumconnect_api.dart';
|
||||
import '../../marianumconnect_endpoint.dart';
|
||||
|
||||
class TimetableCustomEventsGet {
|
||||
final Dio _dio;
|
||||
|
||||
TimetableCustomEventsGet({Dio? dio}) : _dio = dio ?? MarianumConnectApi.dio();
|
||||
|
||||
Future<GetCustomTimetableEventResponse> run() async {
|
||||
try {
|
||||
final response = await _dio.get<Map<String, dynamic>>(
|
||||
MarianumConnectEndpoint.resolve('timetable/custom-events'),
|
||||
);
|
||||
return GetCustomTimetableEventResponse.fromJson(response.data!);
|
||||
} on DioException catch (e) {
|
||||
throw mapMarianumConnectError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import 'package:dio/dio.dart';
|
||||
|
||||
import '../../errors/marianumconnect_error.dart';
|
||||
import '../../marianumconnect_api.dart';
|
||||
import '../../marianumconnect_endpoint.dart';
|
||||
|
||||
class TimetableCustomEventsRemove {
|
||||
final Dio _dio;
|
||||
|
||||
TimetableCustomEventsRemove({Dio? dio})
|
||||
: _dio = dio ?? MarianumConnectApi.dio();
|
||||
|
||||
Future<void> run(String id) async {
|
||||
try {
|
||||
await _dio.delete<void>(
|
||||
MarianumConnectEndpoint.resolve('timetable/custom-events/$id'),
|
||||
);
|
||||
} on DioException catch (e) {
|
||||
throw mapMarianumConnectError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
import 'package:dio/dio.dart';
|
||||
|
||||
import '../../../mhsl/custom_timetable_event/custom_timetable_event.dart';
|
||||
import '../../errors/marianumconnect_error.dart';
|
||||
import '../../marianumconnect_api.dart';
|
||||
import '../../marianumconnect_endpoint.dart';
|
||||
|
||||
class TimetableCustomEventsUpdate {
|
||||
final Dio _dio;
|
||||
|
||||
TimetableCustomEventsUpdate({Dio? dio})
|
||||
: _dio = dio ?? MarianumConnectApi.dio();
|
||||
|
||||
Future<void> run(String id, CustomTimetableEvent event) async {
|
||||
try {
|
||||
await _dio.put<void>(
|
||||
MarianumConnectEndpoint.resolve('timetable/custom-events/$id'),
|
||||
data: event.toJson(),
|
||||
);
|
||||
} on DioException catch (e) {
|
||||
throw mapMarianumConnectError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user