155 lines
4.2 KiB
Dart
155 lines
4.2 KiB
Dart
import 'package:http/http.dart' as http;
|
|
|
|
class CalendarEvent {
|
|
final String? summary;
|
|
final String? description;
|
|
final String? location;
|
|
final DateTime? startTime;
|
|
final DateTime? endTime;
|
|
final bool isAllDay;
|
|
|
|
CalendarEvent({
|
|
this.summary,
|
|
this.description,
|
|
this.location,
|
|
this.startTime,
|
|
this.endTime,
|
|
this.isAllDay = false,
|
|
});
|
|
}
|
|
|
|
class GoogleCalendarService {
|
|
static const String calendarId =
|
|
'b9c267252d5be63d5cdc880be499885a88421eefd0e34e1392890daba0d8471e@group.calendar.google.com';
|
|
|
|
final http.Client _httpClient = http.Client();
|
|
|
|
Future<List<CalendarEvent>> getEvents({
|
|
DateTime? startDate,
|
|
DateTime? endDate,
|
|
}) async {
|
|
try {
|
|
// Use the public iCal feed URL
|
|
final url = Uri.parse(
|
|
'https://calendar.google.com/calendar/ical/$calendarId/public/basic.ics');
|
|
|
|
final response = await _httpClient.get(url);
|
|
|
|
if (response.statusCode == 200) {
|
|
return _parseICalendar(response.body);
|
|
} else {
|
|
throw Exception('Failed to load calendar: ${response.statusCode}');
|
|
}
|
|
} catch (e) {
|
|
throw Exception('Error fetching events: $e');
|
|
}
|
|
}
|
|
|
|
List<CalendarEvent> _parseICalendar(String icalData) {
|
|
final events = <CalendarEvent>[];
|
|
final lines = icalData.split('\n');
|
|
|
|
String? summary;
|
|
String? description;
|
|
String? location;
|
|
DateTime? startTime;
|
|
DateTime? endTime;
|
|
bool isAllDay = false;
|
|
|
|
for (var i = 0; i < lines.length; i++) {
|
|
var line = lines[i].trim();
|
|
|
|
// Handle line continuations
|
|
while (i + 1 < lines.length && lines[i + 1].startsWith(' ')) {
|
|
i++;
|
|
line += lines[i].trim();
|
|
}
|
|
|
|
if (line.startsWith('BEGIN:VEVENT')) {
|
|
summary = null;
|
|
description = null;
|
|
location = null;
|
|
startTime = null;
|
|
endTime = null;
|
|
isAllDay = false;
|
|
} else if (line.startsWith('SUMMARY:')) {
|
|
summary = _unescapeText(line.substring(8));
|
|
} else if (line.startsWith('DESCRIPTION:')) {
|
|
description = _unescapeText(line.substring(12));
|
|
} else if (line.startsWith('LOCATION:')) {
|
|
location = _unescapeText(line.substring(9));
|
|
} else if (line.startsWith('DTSTART')) {
|
|
final dateStr = line.split(':')[1];
|
|
if (line.contains('VALUE=DATE')) {
|
|
isAllDay = true;
|
|
startTime = _parseDate(dateStr);
|
|
} else {
|
|
startTime = _parseDateTime(dateStr);
|
|
}
|
|
} else if (line.startsWith('DTEND')) {
|
|
final dateStr = line.split(':')[1];
|
|
if (line.contains('VALUE=DATE')) {
|
|
endTime = _parseDate(dateStr);
|
|
} else {
|
|
endTime = _parseDateTime(dateStr);
|
|
}
|
|
} else if (line.startsWith('END:VEVENT')) {
|
|
events.add(CalendarEvent(
|
|
summary: summary,
|
|
description: description,
|
|
location: location,
|
|
startTime: startTime,
|
|
endTime: endTime,
|
|
isAllDay: isAllDay,
|
|
));
|
|
}
|
|
}
|
|
|
|
return events;
|
|
}
|
|
|
|
String _unescapeText(String text) {
|
|
return text
|
|
.replaceAll('\\n', '\n')
|
|
.replaceAll('\\,', ',')
|
|
.replaceAll('\\;', ';')
|
|
.replaceAll('\\\\', '\\');
|
|
}
|
|
|
|
DateTime? _parseDate(String dateStr) {
|
|
try {
|
|
// Format: YYYYMMDD
|
|
final year = int.parse(dateStr.substring(0, 4));
|
|
final month = int.parse(dateStr.substring(4, 6));
|
|
final day = int.parse(dateStr.substring(6, 8));
|
|
return DateTime(year, month, day);
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
DateTime? _parseDateTime(String dateStr) {
|
|
try {
|
|
// Format: YYYYMMDDTHHMMSSZ or YYYYMMDDTHHMMSS
|
|
final year = int.parse(dateStr.substring(0, 4));
|
|
final month = int.parse(dateStr.substring(4, 6));
|
|
final day = int.parse(dateStr.substring(6, 8));
|
|
final hour = int.parse(dateStr.substring(9, 11));
|
|
final minute = int.parse(dateStr.substring(11, 13));
|
|
final second = int.parse(dateStr.substring(13, 15));
|
|
|
|
if (dateStr.endsWith('Z')) {
|
|
return DateTime.utc(year, month, day, hour, minute, second);
|
|
} else {
|
|
return DateTime(year, month, day, hour, minute, second);
|
|
}
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
void dispose() {
|
|
_httpClient.close();
|
|
}
|
|
}
|