downloadModelWithProgress static method
Downloads a model specification with progress tracking
Implementation
static Stream<DownloadProgress> downloadModelWithProgress(
ModelSpec spec, {
String? token,
}) async* {
// print('Starting download for model: ${spec.name} (${spec.files.length} files)');
try {
final totalFiles = spec.files.length;
for (int i = 0; i < spec.files.length; i++) {
final file = spec.files[i];
final filePath = await ModelFileSystemManager.getModelFilePath(file.filename);
// print('Downloading file ${i + 1}/$totalFiles: ${file.filename}');
// Emit progress for current file start
yield DownloadProgress(
currentFileIndex: i,
totalFiles: totalFiles,
currentFileProgress: 0,
currentFileName: file.filename,
);
// Download current file with progress
await for (final progress in _downloadSingleFileWithProgress(
url: file.url,
targetPath: filePath,
token: token,
)) {
yield DownloadProgress(
currentFileIndex: i,
totalFiles: totalFiles,
currentFileProgress: progress,
currentFileName: file.filename,
);
}
// Validate downloaded file
final minSize = file.extension == '.json' ? 1024 : 1024 * 1024; // 1KB for JSON, 1MB for others
if (!await ModelFileSystemManager.isFileValid(filePath, minSizeBytes: minSize)) {
throw ModelValidationException(
'Downloaded file failed validation: ${file.filename}',
null,
filePath,
);
}
// print('Completed file ${i + 1}/$totalFiles: ${file.filename}');
}
// Save to SharedPreferences ONLY after ALL files are successfully downloaded
await ModelPreferencesManager.saveModelFiles(spec);
// Emit final progress
yield DownloadProgress(
currentFileIndex: totalFiles,
totalFiles: totalFiles,
currentFileProgress: 100,
currentFileName: 'Complete',
);
// print('Successfully downloaded model: ${spec.name}');
} catch (e) {
// print('Download failed for model ${spec.name}: $e');
// Cleanup any partial files
await ModelFileSystemManager.cleanupFailedDownload(spec);
if (e is ModelException) {
rethrow;
} else {
throw ModelDownloadException(
'Failed to download model: ${spec.name}',
e,
);
}
}
}