import 'dart:io'; import 'package:jiffy/jiffy.dart'; import 'package:myshelf/models/data.dart'; import 'package:myshelf/models/dtinterval.dart'; import 'package:shelf/shelf.dart'; import 'package:shelf_multipart/shelf_multipart.dart'; import 'package:supabase/supabase.dart'; Future handleFileUpload(Request request) async { final start = Jiffy.now(); // Check authorization final authHeader = request.headers['authorization']; if (authHeader == null || !authHeader.startsWith('Bearer ')) { return Response.forbidden('Authorization header missing or invalid'); } final token = authHeader.substring(7); // Remove 'Bearer ' prefix final contentType = request.headers['content-type']; if (contentType == null || !contentType.contains('multipart/form-data')) { return Response(400, body: 'Unsupported content-type'); } final supabaseurl = request.headers['supabaseurl'] ?? "http://kong:8000"; // Initialize Supabase client with the bearer token final supabase = SupabaseClient( // 'http://baas.fares.cyou:8000', supabaseurl, token, ); if (request.multipart() case var multipart?) { List> uploadedFiles = []; await for (final part in multipart.parts) { final contentDisposition = part.headers['content-disposition']; if (contentDisposition != null && contentDisposition.contains('filename=')) { final name = RegExp(r'name="([^"]*)"').firstMatch(contentDisposition)?.group(1); final filename = RegExp(r'filename="([^"]*)"') .firstMatch(contentDisposition) ?.group(1); if (name != null && name != "" && filename != null) { print("File Uploaded: $filename"); // Create temporary file final tempFile = File('uploads/$filename'); await tempFile.create(recursive: true); await part.pipe(tempFile.openWrite()); // Upload to Supabase final bytes = await tempFile.readAsBytes(); await supabase.storage.from('csvhich').uploadBinary( filename, bytes, fileOptions: FileOptions( upsert: true, contentType: part.headers['content-type'], ), ); //insertline in csvhichupdates //print("inserting incsvhichupdates"); await supabase.from('csvhichupdates').insert({ 'filename': filename, 'updated_at': DateTime.now().toUtc().toIso8601String(), }); //copy file to csvhich archive final nowdt = DateTime.now().toUtc(); final now = nowdt.toIso8601String(); // final timestamp ='${nowdt.year}${nowdt.month.toString().padLeft(2, '0')}${nowdt.day.toString().padLeft(2, '0')}_${nowdt.hour.toString().padLeft(2, '0')}${nowdt.minute.toString().padLeft(2, '0')}'; final timestamp = nowdt.millisecondsSinceEpoch.toString(); //upload file to storage archive bucket final archiveFilename = 'upload/${timestamp}_$filename'; await supabase.storage.from('csvhich_archive').uploadBinary( archiveFilename, bytes, fileOptions: FileOptions( upsert: true, contentType: part.headers['content-type'], ), ); final myChannel = supabase.channel('csvhichstorage'); myChannel.subscribe((status, error) async { if (status == RealtimeSubscribeStatus.subscribed) { final serverResponse = await myChannel.sendBroadcastMessage( event: "upload", payload: { "filename": filename, "updated_at": now, }, ); print('serverResponse: $serverResponse'); } }); // No need to subscribe to channel // final channel = supabase.channel('csvhichstorage'); // final res = await channel.sendBroadcastMessage( // event: "upload", // payload: { // "filename": filename, // "updated_at": now, // }, // ); // print(" realtime response: $res"); await processCsvData(tempFile, supabase); //add filename ta list uploadedFiles.add({ 'filename': filename, 'updated_at': now, }); final end = Jiffy.now(); print( " ${DTInterval(start, end).duration.inMilliseconds / 1000} seconds\n"); // Clean up temporary file await tempFile.delete(); } } } supabase.dispose(); if (uploadedFiles.isNotEmpty) { return Response.ok( '{"status": "success", "files": ${uploadedFiles.toString()}}', headers: {'Content-Type': 'application/json'}, ); } return Response(400, body: 'No files were uploaded'); } else { supabase.dispose(); return Response(401, body: 'Not a multipart request'); } }