download method

Future<void> download(
  1. String url,
  2. String path, {
  3. ProgressCallback? onProgress,
  4. CancelToken? cancelToken,
  5. Map<String, dynamic>? headers,
  6. Map<String, dynamic>? queryParameters,
})

Downloads url into path, replacing any file there only once the download has finished.

Uses Nylo's NyApiService, so your interceptors apply. onProgress receives bytes received and the total, or -1 when the server doesn't say.

Implementation

Future<void> download(
  String url,
  String path, {
  ProgressCallback? onProgress,
  CancelToken? cancelToken,
  Map<String, dynamic>? headers,
  Map<String, dynamic>? queryParameters,
}) => _run(path, () async {
  _guardWrite('download');
  final String target = _resolve(path);
  final NyApiService api = NyApiService(
    useNetworkLogger: NyEnvRegistry.isInitialized ? null : false,
  );
  final Options options = Options(headers: {'Accept': '*/*', ...?headers});
  final String? absolute = await driver.absolutePath(target);

  if (absolute == null) {
    final Response<List<int>> response = await api.dio.get<List<int>>(
      url,
      queryParameters: queryParameters,
      cancelToken: cancelToken,
      onReceiveProgress: onProgress,
      options: options.copyWith(responseType: ResponseType.bytes),
    );
    await driver.write(target, response.data ?? const <int>[]);
    _written(target);
    return;
  }

  // Download next to the target under a hidden temp name, then rename it
  // into place, so a half-finished download never looks complete.
  final String folder = parentDiskPath(target);
  final String temp = joinDiskPath(
    folder,
    '.${target.substring(folder.isEmpty ? 0 : folder.length + 1)}'
    '${LocalDiskDriver.tempMarker}download-${_randomName(8)}',
  );
  await driver.createDirectory(folder);
  try {
    await api.download(
      url,
      savePath: (await driver.absolutePath(temp))!,
      onProgress: onProgress,
      cancelToken: cancelToken,
      queryParameters: queryParameters,
      options: options,
    );
    await driver.move(temp, target);
  } catch (_) {
    try {
      await driver.delete(temp);
    } catch (_) {}
    rethrow;
  }
  _written(target);
});