calendar_handler.dart 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. import 'dart:convert';
  2. import 'package:icalserver/data.dart';
  3. import 'package:icalserver/icalendar.dart';
  4. import 'package:supabase/supabase.dart';
  5. import 'package:shelf/shelf.dart';
  6. class CalendarHandler {
  7. SupabaseClient getSupabaseClient(Request request) {
  8. // final supabaseUrl = request.headers['supabase-url'];
  9. // final authHeader = request.headers['authorization'];
  10. // final token = authHeader!.substring(7); // Remove 'Bearer ' prefix
  11. final supabaseUrl = 'http://baas.fares.cyou:8000';
  12. final token =
  13. "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q";
  14. return SupabaseClient(
  15. supabaseUrl,
  16. token,
  17. );
  18. }
  19. // Handler for the /link route
  20. Future<Response> getCalendar(Request request) async {
  21. final credentials = _getBasicAuthCredentials(request);
  22. if (credentials == null) {
  23. return Response.unauthorized('Invalid credentials');
  24. }
  25. final (username, password) = credentials;
  26. if (username != password) {
  27. return Response.unauthorized('Invalid credentials');
  28. }
  29. final supabase = getSupabaseClient(request);
  30. //get licence_csv table into variable
  31. final licences = (await supabase.from('licences_csv').select());
  32. //print(licencesCsv);
  33. // Execute the query
  34. final rosterlist =
  35. await supabase.rpc('get_crew_roster', params: {'_tlc': username});
  36. // Handle the response
  37. print('TLC: $username ... EVENTS: ${rosterlist.length}');
  38. // Create an iCalendar object
  39. final ical = ICalendar();
  40. if (rosterlist is List) {
  41. for (var i = 0; i < rosterlist.length; i++) {
  42. final event = rosterlist[i];
  43. final pnleg = Pnleg(
  44. date: event['date'],
  45. tlc: username,
  46. actype: event['actype'],
  47. al: event['al'],
  48. fnum: event['fnum'],
  49. dep: event['dep'],
  50. arr: event['des'],
  51. depdate: event['ddep'],
  52. deptime: event['hdep'],
  53. arrdate: event['ddes'],
  54. arrtime: event['hdes'],
  55. label: event['label'],
  56. type: event['type']);
  57. final List<List<String>> crewlist = [];
  58. for (var j = 0; j < (event['crew'] as List).length; j++) {
  59. final crewmember = event['crew'][j] as String;
  60. final crewmemberDataAc = licences.firstWhere(
  61. (e) => (e['tlc'] == crewmember) && (e['ac'] == pnleg.ac),
  62. orElse: () => {});
  63. final crewmemberData = licences
  64. .firstWhere((e) => e['tlc'] == crewmember, orElse: () => {});
  65. crewlist.add([
  66. '${([
  67. "F",
  68. "G"
  69. ].contains(event['crewtype'][j]) ? "DH " : null) ?? (crewmemberDataAc["college"] ?? "--")}',
  70. '${crewmemberData["lname"] ?? "------"}',
  71. '${crewmemberData["fname"] ?? "Unknown"}'
  72. ]);
  73. }
  74. final crewlistdisplay = (crewlist
  75. ..sort((a, b) {
  76. const order = {
  77. 'CP': 0,
  78. 'FO': 1,
  79. 'PU': 2,
  80. 'SE': 3,
  81. 'ST': 4,
  82. 'JU': 5
  83. };
  84. return (order[a[0]] ?? 6).compareTo(order[b[0]] ?? 6);
  85. }))
  86. .map((e) => "${e[0]}: ${e[1]}, ${e[2]}")
  87. .join("\n");
  88. switch (pnleg.dutytype) {
  89. case "flight":
  90. ical.addEvent(
  91. summary: "${pnleg.dep}-${pnleg.arr}",
  92. description: """
  93. Flight from ${pnleg.dep} to ${pnleg.arr}
  94. Flight number: ${pnleg.al}${pnleg.fnum}
  95. Aircraft type: ${pnleg.actype}
  96. Departure time: ${pnleg.jdep?.Hm}
  97. Arrival time: ${pnleg.jarr?.Hm}
  98. Crew:
  99. $crewlistdisplay
  100. """
  101. .replaceAll("\n", "\\n"),
  102. startTime: pnleg.jdep!.dateTime,
  103. endTime: pnleg.jarr!.dateTime,
  104. attendees: event['crew'],
  105. );
  106. break;
  107. case "dhflight":
  108. case "dhlimo":
  109. case "standby":
  110. case "ground":
  111. case "day":
  112. default:
  113. }
  114. }
  115. }
  116. // Return the response with the iCalendar content
  117. await supabase.dispose();
  118. return Response.ok(
  119. ical.serialize(),
  120. headers: {'Content-Type': 'text/calendar; charset=utf-8'},
  121. );
  122. }
  123. (String, String)? _getBasicAuthCredentials(Request request) {
  124. // Get Authorization header
  125. String authHeader = request.headers['authorization'] ?? "";
  126. if (!authHeader.startsWith('Basic ')) {
  127. return null;
  128. }
  129. // Extract and decode credentials
  130. try {
  131. String base64Credentials = authHeader.substring('Basic '.length);
  132. String credentials = utf8.decode(base64.decode(base64Credentials));
  133. List<String> userPass = credentials.split(':');
  134. if (userPass.length != 2) return null;
  135. return (userPass[0], userPass[1]);
  136. } catch (e) {
  137. return null;
  138. }
  139. }
  140. }