uploadFiles function

Future<UploadFilesType> uploadFiles(
  1. String? folderPath,
  2. String apiPrefix,
  3. IFileUploadRequest? params,
  4. List<FileMetadata>? files,
)

Implementation

Future<UploadFilesType> uploadFiles(String? folderPath, String apiPrefix,
    IFileUploadRequest? params, List<FileMetadata>? files) async {
  if (folderPath != null) {
    ApillonLogger.log('Preparing to upload files from $folderPath...');
  } else if (files?.isNotEmpty == true) {
    ApillonLogger.log('Preparing to upload ${files?.length} files...');
  } else {
    throw ArgumentError('Invalid upload parameters received');
  }
  // If folderPath param passed, read files from local storage
  if (folderPath != null && (files?.isEmpty ?? true)) {
    try {
      files = listFilesRecursive(folderPath);
    } catch (err) {
      ApillonLogger.log(err.toString(), LogLevel.ERROR);
      rethrow;
    }
  }

  ApillonLogger.log('Total files to upload: ${files?.length}');

  // Split files into chunks for parallel uploading
  const fileChunkSize = 200;
  final sessionUuid = uuidv4();
  final uploadedFiles = <List<FileMetadata>>[];

  for (final fileGroup in chunkify(files!, fileChunkSize)) {
    var fileGroupJson = fileGroup.map((e) => e.toMap()).toList();
    final response = await ApillonApi.post<IFileUploadResponse>(
        '$apiPrefix/upload',
        {'files': fileGroupJson, 'sessionUuid': sessionUuid},
        mapper: IFileUploadResponse.fromMap);
    await uploadFilesToS3(
        response.files.map((e) => FileMetadata.fromMap(e)).toList(), fileGroup);
    uploadedFiles.add(files);
  }

  ApillonLogger.logWithTime('File upload complete.');

  ApillonLogger.log('Closing upload session...');
  await ApillonApi.post('$apiPrefix/upload/$sessionUuid/end', params?.toMap());
  ApillonLogger.logWithTime('Upload session ended.');

  return UploadFilesType(sessionUuid, uploadedFiles.expand((f) => f).toList());
}