import 'dart:convert'; import 'package:icalserver/data.dart'; import 'package:icalserver/icalendar.dart'; import 'package:supabase/supabase.dart'; import 'package:shelf/shelf.dart'; class CalendarHandler { SupabaseClient getSupabaseClient(Request request) { // final supabaseUrl = request.headers['supabase-url']; // final authHeader = request.headers['authorization']; // final token = authHeader!.substring(7); // Remove 'Bearer ' prefix final supabaseUrl = 'http://baas.fares.cyou:8000'; final token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q"; return SupabaseClient( supabaseUrl, token, ); } // Handler for the /link route Future getCalendar(Request request) async { final credentials = _getBasicAuthCredentials(request); if (credentials == null) { return Response.unauthorized('Invalid credentials'); } final (username, password) = credentials; if (username != password) { return Response.unauthorized('Invalid credentials'); } final supabase = getSupabaseClient(request); //get licence_csv table into variable final licences = (await supabase.from('licences_csv').select()); //print(licencesCsv); // Execute the query final rosterlist = await supabase.rpc('get_crew_roster', params: {'_tlc': username}); // Handle the response print('TLC: $username ... EVENTS: ${rosterlist.length}'); // Create an iCalendar object final ical = ICalendar(); if (rosterlist is List) { for (var i = 0; i < rosterlist.length; i++) { final event = rosterlist[i]; final pnleg = Pnleg( date: event['date'], tlc: username, actype: event['actype'], al: event['al'], fnum: event['fnum'], dep: event['dep'], arr: event['des'], depdate: event['ddep'], deptime: event['hdep'], arrdate: event['ddes'], arrtime: event['hdes'], label: event['label'], type: event['type']); final List> crewlist = []; for (var j = 0; j < (event['crew'] as List).length; j++) { final crewmember = event['crew'][j] as String; final crewmemberDataAc = licences.firstWhere( (e) => (e['tlc'] == crewmember) && (e['ac'] == pnleg.ac), orElse: () => {}); final crewmemberData = licences .firstWhere((e) => e['tlc'] == crewmember, orElse: () => {}); crewlist.add([ '${([ "F", "G" ].contains(event['crewtype'][j]) ? "DH " : null) ?? (crewmemberDataAc["college"] ?? "--")}', '${crewmemberData["lname"] ?? "------"}', '${crewmemberData["fname"] ?? "Unknown"}' ]); } final crewlistdisplay = (crewlist ..sort((a, b) { const order = { 'CP': 0, 'FO': 1, 'PU': 2, 'SE': 3, 'ST': 4, 'JU': 5 }; return (order[a[0]] ?? 6).compareTo(order[b[0]] ?? 6); })) .map((e) => "${e[0]}: ${e[1]}, ${e[2]}") .join("\n"); switch (pnleg.dutytype) { case "flight": ical.addEvent( summary: "${pnleg.dep}-${pnleg.arr}", description: """ Flight from ${pnleg.dep} to ${pnleg.arr} Flight number: ${pnleg.al}${pnleg.fnum} Aircraft type: ${pnleg.actype} Departure time: ${pnleg.jdep?.Hm} Arrival time: ${pnleg.jarr?.Hm} Crew: $crewlistdisplay """ .replaceAll("\n", "\\n"), startTime: pnleg.jdep!.dateTime, endTime: pnleg.jarr!.dateTime, attendees: event['crew'], ); break; case "dhflight": case "dhlimo": case "standby": case "ground": case "day": default: } } } // Return the response with the iCalendar content await supabase.dispose(); return Response.ok( ical.serialize(), headers: {'Content-Type': 'text/calendar; charset=utf-8'}, ); } (String, String)? _getBasicAuthCredentials(Request request) { // Get Authorization header String authHeader = request.headers['authorization'] ?? ""; if (!authHeader.startsWith('Basic ')) { return null; } // Extract and decode credentials try { String base64Credentials = authHeader.substring('Basic '.length); String credentials = utf8.decode(base64.decode(base64Credentials)); List userPass = credentials.split(':'); if (userPass.length != 2) return null; return (userPass[0], userPass[1]); } catch (e) { return null; } } }