upload_handler.dart 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. import 'dart:io';
  2. import 'package:jiffy/jiffy.dart';
  3. import 'package:myshelf/models/data.dart';
  4. import 'package:myshelf/models/dtinterval.dart';
  5. import 'package:shelf/shelf.dart';
  6. import 'package:shelf_multipart/shelf_multipart.dart';
  7. import 'package:supabase/supabase.dart';
  8. Future<Response> handleFileUpload(Request request) async {
  9. final start = Jiffy.now();
  10. // Check authorization
  11. final authHeader = request.headers['authorization'];
  12. if (authHeader == null || !authHeader.startsWith('Bearer ')) {
  13. return Response.forbidden('Authorization header missing or invalid');
  14. }
  15. final token = authHeader.substring(7); // Remove 'Bearer ' prefix
  16. final contentType = request.headers['content-type'];
  17. if (contentType == null || !contentType.contains('multipart/form-data')) {
  18. return Response(400, body: 'Unsupported content-type');
  19. }
  20. final supabaseurl = request.headers['supabaseurl'] ?? "kong:8000";
  21. // Initialize Supabase client with the bearer token
  22. final supabase = SupabaseClient(
  23. // 'http://baas.fares.cyou:8000',
  24. supabaseurl,
  25. token,
  26. );
  27. if (request.multipart() case var multipart?) {
  28. List<Map<String, dynamic>> uploadedFiles = [];
  29. await for (final part in multipart.parts) {
  30. final contentDisposition = part.headers['content-disposition'];
  31. if (contentDisposition != null &&
  32. contentDisposition.contains('filename=')) {
  33. final name =
  34. RegExp(r'name="([^"]*)"').firstMatch(contentDisposition)?.group(1);
  35. final filename = RegExp(r'filename="([^"]*)"')
  36. .firstMatch(contentDisposition)
  37. ?.group(1);
  38. if (name != null && name != "" && filename != null) {
  39. print("File Uploaded: $filename");
  40. // Create temporary file
  41. final tempFile = File('uploads/$filename');
  42. await tempFile.create(recursive: true);
  43. await part.pipe(tempFile.openWrite());
  44. // Upload to Supabase
  45. final bytes = await tempFile.readAsBytes();
  46. await supabase.storage.from('csvhich').uploadBinary(
  47. filename,
  48. bytes,
  49. fileOptions: FileOptions(
  50. upsert: true,
  51. contentType: part.headers['content-type'],
  52. ),
  53. );
  54. //insertline in csvhichupdates
  55. //print("inserting incsvhichupdates");
  56. await supabase.from('csvhichupdates').insert({
  57. 'filename': filename,
  58. 'updated_at': DateTime.now().toUtc().toIso8601String(),
  59. });
  60. //copy file to csvhich archive
  61. final nowdt = DateTime.now().toUtc();
  62. final now = nowdt.toIso8601String();
  63. // 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')}';
  64. final timestamp = nowdt.millisecondsSinceEpoch.toString();
  65. //upload file to storage archive bucket
  66. final archiveFilename = 'upload/${timestamp}_$filename';
  67. await supabase.storage.from('csvhich_archive').uploadBinary(
  68. archiveFilename,
  69. bytes,
  70. fileOptions: FileOptions(
  71. upsert: true,
  72. contentType: part.headers['content-type'],
  73. ),
  74. );
  75. <<<<<<< HEAD
  76. // No need to subscribe to channel
  77. final supabaseRT = SupabaseClient(
  78. // 'http://baas.fares.cyou:8000',
  79. supabaseurl,
  80. token,
  81. );
  82. final channel = supabaseRT.channel('csvhichstorage');
  83. final res = await channel.sendBroadcastMessage(
  84. event: "upload",
  85. payload: {
  86. "filename": filename,
  87. "updated_at": now,
  88. },
  89. );
  90. supabaseRT.dispose();
  91. print(" realtime response: $res");
  92. =======
  93. // No need to subscribe to channel
  94. final channel = supabase.channel('csvhichstorage');
  95. final res = await channel.sendBroadcastMessage(
  96. event: "upload",
  97. payload: {
  98. "filename": filename,
  99. "updated_at": now,
  100. },
  101. );
  102. print(" realtime response: $res");
  103. await processCsvData(tempFile, supabase);
  104. >>>>>>> e195ac1ab2e5fb33285e6aa7ee999144b436c214
  105. await processCsvData(tempFile, supabase);
  106. //add filename ta list
  107. uploadedFiles.add({
  108. 'filename': filename,
  109. 'updated_at': now,
  110. });
  111. final end = Jiffy.now();
  112. print(
  113. " ${DTInterval(start, end).duration.inSeconds} seconds\n");
  114. // Clean up temporary file
  115. await tempFile.delete();
  116. }
  117. }
  118. }
  119. supabase.dispose();
  120. if (uploadedFiles.isNotEmpty) {
  121. return Response.ok(
  122. '{"status": "success", "files": ${uploadedFiles.toString()}}',
  123. headers: {'Content-Type': 'application/json'},
  124. );
  125. }
  126. return Response(400, body: 'No files were uploaded');
  127. } else {
  128. supabase.dispose();
  129. return Response(401, body: 'Not a multipart request');
  130. }
  131. }