calendar_handler copy.bak 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  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. final requester =
  38. licences.firstWhere((e) => e['tlc'] == username, orElse: () => {});
  39. print(
  40. 'TLC: $username ... EVENTS: ${rosterlist.length} ... Name: ${requester['lname']}, ${requester['fname']}');
  41. // Create an iCalendar object
  42. final ical = ICalendar();
  43. if (rosterlist is List) {
  44. for (var i = 0; i < rosterlist.length; i++) {
  45. final event = rosterlist[i];
  46. final pnleg = Pnleg(
  47. date: event['date'],
  48. tlc: username,
  49. actype: event['actype'],
  50. al: event['al'],
  51. fnum: event['fnum'],
  52. dep: event['dep'],
  53. arr: event['des'],
  54. depdate: event['ddep'],
  55. deptime: event['hdep'],
  56. arrdate: event['ddes'],
  57. arrtime: event['hdes'],
  58. label: event['label'],
  59. type: event['type']);
  60. final List<List<String>> crewlist = [];
  61. for (var j = 0; j < (event['crew'] as List).length; j++) {
  62. final crewmember = event['crew'][j] as String;
  63. final crewmemberDataAc = licences.firstWhere(
  64. (e) => (e['tlc'] == crewmember) && (e['ac'] == pnleg.ac),
  65. orElse: () => {});
  66. final crewmemberData = licences
  67. .firstWhere((e) => e['tlc'] == crewmember, orElse: () => {});
  68. crewlist.add([
  69. '${([
  70. "F",
  71. "G"
  72. ].contains(event['crewtype'][j]) ? "DH " : null) ?? (crewmemberDataAc["college"] ?? "--")}',
  73. '${crewmemberData["lname"] ?? "------"}',
  74. '${crewmemberData["fname"] ?? "Unknown"}'
  75. ]);
  76. }
  77. final crewlistdisplay = (crewlist
  78. ..sort((a, b) {
  79. const order = {
  80. 'CP': 0,
  81. 'FO': 1,
  82. 'PU': 2,
  83. 'SE': 3,
  84. 'ST': 4,
  85. 'JU': 5
  86. };
  87. return (order[a[0]] ?? 6).compareTo(order[b[0]] ?? 6);
  88. }))
  89. .map((e) => "${e[0]}: ${e[1]}, ${e[2]}")
  90. .join("\n");
  91. switch (pnleg.dutytype) {
  92. case "flight":
  93. ical.addEvent(
  94. summary: "${pnleg.dep}-${pnleg.arr}",
  95. description: """
  96. Flight from ${pnleg.dep} to ${pnleg.arr}
  97. Flight number: ${pnleg.al}${pnleg.fnum}
  98. Aircraft type: ${pnleg.actype}
  99. Departure time: ${pnleg.jdep?.Hm}
  100. Arrival time: ${pnleg.jarr?.Hm}
  101. Crew:
  102. $crewlistdisplay
  103. """
  104. .replaceAll("\n", "\\n"),
  105. startTime: pnleg.jdep!.dateTime,
  106. endTime: pnleg.jarr!.dateTime,
  107. attendees: event['crew'],
  108. );
  109. break;
  110. case "dhflight":
  111. ical.addEvent(
  112. summary: "DH ${pnleg.dep}-${pnleg.arr}",
  113. description: """
  114. DH Flight from ${pnleg.dep} to ${pnleg.arr}
  115. Flight number: ${pnleg.al}${pnleg.fnum}
  116. Aircraft type: ${pnleg.actype}
  117. Departure time: ${pnleg.jdep?.Hm}
  118. Arrival time: ${pnleg.jarr?.Hm}
  119. Crew:
  120. $crewlistdisplay
  121. """
  122. .replaceAll("\n", "\\n"),
  123. startTime: pnleg.jdep!.dateTime,
  124. endTime: pnleg.jarr!.dateTime,
  125. attendees: event['crew'],
  126. );
  127. break;
  128. case "dhlimo":
  129. ical.addEvent(
  130. summary: "${pnleg.dep}-${pnleg.arr}",
  131. description: """
  132. DH Limo from ${pnleg.dep} to ${pnleg.arr}
  133. Departure time: ${pnleg.jdep?.Hm}
  134. Arrival time: ${pnleg.jarr?.Hm}
  135. Crew:
  136. $crewlistdisplay
  137. """
  138. .replaceAll("\n", "\\n"),
  139. startTime: pnleg.jdep!.dateTime,
  140. endTime: pnleg.jarr!.dateTime,
  141. attendees: event['crew'],
  142. );
  143. break;
  144. case "standby":
  145. ical.addEvent(
  146. summary: "STDBY ${pnleg.label}",
  147. description: """
  148. Stand By ${pnleg.label} at ${pnleg.dep}
  149. Start time: ${pnleg.jdep?.Hm}
  150. End time: ${pnleg.jarr?.Hm}
  151. """
  152. .replaceAll("\n", "\\n"),
  153. startTime: pnleg.jdep!.dateTime,
  154. endTime: pnleg.jarr!.dateTime,
  155. attendees: event['crew'],
  156. );
  157. break;
  158. case "ground":
  159. ical.addEvent(
  160. summary: "${pnleg.label}",
  161. description: """
  162. ${pnleg.label} at ${pnleg.dep}
  163. Start time: ${pnleg.jdep?.Hm}
  164. End time: ${pnleg.jarr?.Hm}
  165. Attendee:
  166. $crewlistdisplay
  167. """
  168. .replaceAll("\n", "\\n"),
  169. startTime: pnleg.jdep!.dateTime,
  170. endTime: pnleg.jarr!.dateTime,
  171. attendees: event['crew'],
  172. );
  173. break;
  174. case "day":
  175. ical.addEvent(
  176. summary: "${pnleg.label}",
  177. description: """
  178. ${pnleg.label} at ${pnleg.dep}
  179. Attendee:
  180. $crewlistdisplay
  181. """
  182. .replaceAll("\n", "\\n"),
  183. startTime: pnleg.jdate!.dateTime,
  184. endTime: pnleg.jdate!.dateTime,
  185. attendees: event['crew'],
  186. allday: true);
  187. break;
  188. default:
  189. }
  190. }
  191. }
  192. // Return the response with the iCalendar content
  193. await supabase.dispose();
  194. return Response.ok(
  195. ical.serialize(),
  196. headers: {'Content-Type': 'text/calendar; charset=utf-8'},
  197. );
  198. }
  199. (String, String)? _getBasicAuthCredentials(Request request) {
  200. // Get Authorization header
  201. if (!request.headers.containsKey('authorization')) {
  202. return null;
  203. }
  204. String authHeader = request.headers['authorization'] ?? "";
  205. if (!authHeader.startsWith('Basic ')) {
  206. return null;
  207. }
  208. // Extract and decode credentials
  209. try {
  210. String base64Credentials = authHeader.substring('Basic '.length);
  211. String credentials = utf8.decode(base64.decode(base64Credentials));
  212. List<String> userPass = credentials.split(':');
  213. if (userPass.length != 2) return null;
  214. return (userPass[0], userPass[1]);
  215. } catch (e) {
  216. return null;
  217. }
  218. }
  219. }