-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathcalendar_service.dart
More file actions
99 lines (82 loc) · 3.02 KB
/
calendar_service.dart
File metadata and controls
99 lines (82 loc) · 3.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import 'dart:convert';
import 'package:intl/intl.dart';
import 'package:riverpod/riverpod.dart';
import 'package:tattoo/services/portal_service.dart';
import 'package:tattoo/utils/http.dart';
/// Represents a calendar event from the NTUT Portal.
///
/// Events come in two flavors:
/// - **Named events** with [id], [calTitle], [ownerName], [creatorName]
/// (e.g., exam periods, registration deadlines)
/// - **Holiday markers** with [isHoliday] = "1" and an empty title
/// (weekends and national holidays)
typedef CalendarEventDto = ({
/// Event ID (absent for holiday markers).
int? id,
/// Event start time (epoch milliseconds).
int? calStart,
/// Event end time (epoch milliseconds).
int? calEnd,
/// Whether this is an all-day event ("1" = yes).
String? allDay,
/// Event title / description.
String? calTitle,
/// Event location.
String? calPlace,
/// Event content / details.
String? calContent,
/// Owner name (e.g., "學校行事曆").
String? ownerName,
/// Creator name (e.g., "教務處").
String? creatorName,
/// Whether this is a holiday ("1" = yes).
String? isHoliday,
});
/// Provides the singleton [CalendarService] instance.
final calendarServiceProvider = Provider<CalendarService>(
(ref) => CalendarService(ref.read(portalServiceProvider)),
);
/// Service for fetching NTUT academic calendar events.
///
/// Uses the `calModeApp.do` JSON API on the NTUT Portal host.
/// Requires an active portal session (shared cookie jar from [PortalService.login]).
class CalendarService {
final Dio _dio;
CalendarService(PortalService portalService) : _dio = portalService.portalDio;
/// Fetches academic calendar events within a date range.
///
/// Returns a list of calendar events (e.g., holidays, exam periods,
/// registration deadlines) between [startDate] and [endDate] inclusive.
///
/// Requires an active portal session (call [PortalService.login] first).
Future<List<CalendarEventDto>> getCalendar(
DateTime startDate,
DateTime endDate,
) async {
final formatter = DateFormat('yyyy/MM/dd');
final response = await _dio.get(
'calModeApp.do',
queryParameters: {
'startDate': formatter.format(startDate),
'endDate': formatter.format(endDate),
},
);
final List<dynamic> events = jsonDecode(response.data);
String? normalizeEmpty(String? value) =>
value?.isNotEmpty == true ? value : null;
return events.map<CalendarEventDto>((e) {
return (
id: e['id'] as int?,
calStart: e['calStart'] as int?,
calEnd: e['calEnd'] as int?,
allDay: normalizeEmpty(e['allDay'] as String?),
calTitle: normalizeEmpty(e['calTitle'] as String?),
calPlace: normalizeEmpty(e['calPlace'] as String?),
calContent: normalizeEmpty(e['calContent'] as String?),
ownerName: normalizeEmpty(e['ownerName'] as String?),
creatorName: normalizeEmpty(e['creatorName'] as String?),
isHoliday: normalizeEmpty(e['isHoliday'] as String?),
);
}).toList();
}
}