diff --git a/lib/blocs/data_export/data_export_cubit.dart b/lib/blocs/data_export/data_export_cubit.dart index 318b706409..80696f434d 100644 --- a/lib/blocs/data_export/data_export_cubit.dart +++ b/lib/blocs/data_export/data_export_cubit.dart @@ -1,5 +1,6 @@ import 'dart:convert'; +import 'package:ardrive/core/arfs/repository/folder_repository.dart'; import 'package:ardrive/models/models.dart'; import 'package:csv/csv.dart'; import 'package:drift/drift.dart'; @@ -8,17 +9,32 @@ import 'package:flutter_bloc/flutter_bloc.dart'; part 'data_export_state.dart'; +const _fileIdColumnName = 'File Id'; +const _fileNameColumnName = 'File Name'; +const _parentFolderIdColumnName = 'Parent Folder ID'; +const _parentFolderNameColumnName = 'Parent Folder Name'; +const _dataTransactionIdColumnName = 'Data Transaction ID'; +const _metadataTransactionIdColumnName = 'Metadata Transaction ID'; +const _fileSizeColumnName = 'File Size'; +const _dateCreatedColumnName = 'Date Created'; +const _lastModifiedColumnName = 'Last Modified'; +const _directDownloadLinkColumnName = 'Direct Download Link'; +const _statusColumnName = 'Status'; + class DataExportCubit extends Cubit { final String driveId; final DriveDao _driveDao; + final FolderRepository _folderRepository; final String _gatewayURL; DataExportCubit({ required this.driveId, required DriveDao driveDao, required String gatewayURL, + required FolderRepository folderRepository, }) : _driveDao = driveDao, _gatewayURL = gatewayURL, + _folderRepository = folderRepository, super(DataExportInitial()); Future getFilesInDriveAsCSV(String driveId) async { @@ -27,30 +43,44 @@ class DataExportCubit extends Cubit { .get(); final export = >[ [ - 'File Id', - 'File Name', - 'Parent Folder ID', - 'Data Transaction ID', - 'Metadata Transaction ID', - 'File Size', - 'Date Created', - 'Last Modified', - 'Direct Download Link' + _fileIdColumnName, + _fileNameColumnName, + _parentFolderIdColumnName, + _parentFolderNameColumnName, + _dataTransactionIdColumnName, + _metadataTransactionIdColumnName, + _fileSizeColumnName, + _dateCreatedColumnName, + _lastModifiedColumnName, + _directDownloadLinkColumnName, + _statusColumnName, ] ]; + final Map folderNames = {}; + for (var file in files) { final fileContent = []; + + final parentFolder = await _folderRepository.getLatestFolderRevisionInfo( + driveId, file.parentFolderId); + + if (parentFolder != null) { + folderNames[file.parentFolderId] = parentFolder.name; + } + fileContent ..add(file.id) ..add(file.name) ..add(file.parentFolderId) + ..add(folderNames[file.parentFolderId] ?? '') ..add(file.dataTx.id) ..add(file.metadataTx.id) ..add(file.size.toString()) ..add(file.dateCreated.toString()) ..add(file.lastModifiedDate.toString()) - ..add(Uri.parse('$_gatewayURL/${file.dataTx.id}').toString()); + ..add(Uri.parse('$_gatewayURL/${file.dataTx.id}').toString()) + ..add(file.dataTx.status.toString()); export.add(fileContent); } return const ListToCsvConverter().convert(export); diff --git a/lib/components/csv_export_dialog.dart b/lib/components/csv_export_dialog.dart index 3ac0676dfe..b99c91a28e 100644 --- a/lib/components/csv_export_dialog.dart +++ b/lib/components/csv_export_dialog.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:ardrive/blocs/blocs.dart'; import 'package:ardrive/blocs/data_export/data_export_cubit.dart'; +import 'package:ardrive/core/arfs/repository/folder_repository.dart'; import 'package:ardrive/models/models.dart'; import 'package:ardrive/services/services.dart'; import 'package:ardrive/theme/theme.dart'; @@ -23,6 +24,7 @@ Future promptToExportCSVData({ return DataExportCubit( driveId: driveId, driveDao: context.read(), + folderRepository: context.read(), gatewayURL: context.read().client.api.gatewayUrl.toString(), )..exportData(); diff --git a/test/blocs/data_export_cubit_test.dart b/test/blocs/data_export_cubit_test.dart index 7932880bb1..e67be394ad 100644 --- a/test/blocs/data_export_cubit_test.dart +++ b/test/blocs/data_export_cubit_test.dart @@ -2,6 +2,7 @@ import 'package:ardrive/blocs/data_export/data_export_cubit.dart'; import 'package:ardrive/models/models.dart'; import 'package:ardrive_io/ardrive_io.dart'; import 'package:bloc_test/bloc_test.dart'; +import 'package:mocktail/mocktail.dart'; import 'package:test/test.dart'; import '../snapshots/data_export_snapshot.dart'; @@ -10,6 +11,7 @@ import '../test_utils/utils.dart'; void main() { late Database db; late DriveDao driveDao; + late MockFolderRepository folderRepository; group('DataExport', () { const driveId = 'drive-id'; @@ -22,10 +24,13 @@ void main() { const emptyNestedFolderIdPrefix = 'empty-nested-folder-id'; const emptyNestedFolderCount = 5; + const folderName = 'folder-name'; + const testGatewayURL = 'https://arweave.net'; setUp(() async { db = getTestDb(); driveDao = db.driveDao; + folderRepository = MockFolderRepository(); // Setup mock drive. await addTestFilesToDb( db, @@ -37,6 +42,19 @@ void main() { nestedFolderId: nestedFolderId, nestedFolderFileCount: nestedFolderFileCount, ); + when(() => folderRepository.getLatestFolderRevisionInfo( + any(), + any(), + )).thenAnswer((_) async => FolderRevision( + folderId: '', + name: folderName, + driveId: driveId, + dateCreated: DateTime.now(), + action: 'create', + isHidden: false, + metadataTxId: '', + parentFolderId: '', + )); }); tearDown(() async { await db.close(); @@ -46,6 +64,7 @@ void main() { 'export drive contents as csv file exports the correct number of files', build: () => DataExportCubit( gatewayURL: testGatewayURL, + folderRepository: folderRepository, driveDao: driveDao, driveId: driveId, ), diff --git a/test/snapshots/data_export_snapshot.dart b/test/snapshots/data_export_snapshot.dart index 9d23e7c6dc..46f5c8369c 100644 --- a/test/snapshots/data_export_snapshot.dart +++ b/test/snapshots/data_export_snapshot.dart @@ -1,12 +1,12 @@ const String dataExportSnapshot = - 'File Id,File Name,Parent Folder ID,Data Transaction ID,Metadata Transaction ID,File Size,Date Created,Last Modified,Direct Download Link\r\n' - 'root-folder-id4,root-folder-id4,root-folder-id,root-folder-id4Data,root-folder-id4Meta,500,2017-09-07 17:30:00.000,2017-09-07 17:30:00.000,https://arweave.net/root-folder-id4Data\r\n' - 'root-folder-id2,root-folder-id2,root-folder-id,root-folder-id2Data,root-folder-id2Meta,500,2017-09-07 17:30:00.000,2017-09-07 17:30:00.000,https://arweave.net/root-folder-id2Data\r\n' - 'root-folder-id3,root-folder-id3,root-folder-id,root-folder-id3Data,root-folder-id3Meta,500,2017-09-07 17:30:00.000,2017-09-07 17:30:00.000,https://arweave.net/root-folder-id3Data\r\n' - 'root-folder-id1,root-folder-id1,root-folder-id,root-folder-id1Data,root-folder-id1Meta,500,2017-09-07 17:30:00.000,2017-09-07 17:30:00.000,https://arweave.net/root-folder-id1Data\r\n' - 'root-folder-id0,root-folder-id0,root-folder-id,root-folder-id0Data,root-folder-id0Meta,500,2017-09-07 17:30:00.000,2017-09-07 17:30:00.000,https://arweave.net/root-folder-id0Data\r\n' - 'nested-folder-id4,nested-folder-id4,nested-folder-id,nested-folder-id4Meta,nested-folder-id4Data,500,2017-09-07 17:30:00.000,2017-09-07 17:30:00.000,https://arweave.net/nested-folder-id4Meta\r\n' - 'nested-folder-id2,nested-folder-id2,nested-folder-id,nested-folder-id2Meta,nested-folder-id2Data,500,2017-09-07 17:30:00.000,2017-09-07 17:30:00.000,https://arweave.net/nested-folder-id2Meta\r\n' - 'nested-folder-id3,nested-folder-id3,nested-folder-id,nested-folder-id3Meta,nested-folder-id3Data,500,2017-09-07 17:30:00.000,2017-09-07 17:30:00.000,https://arweave.net/nested-folder-id3Meta\r\n' - 'nested-folder-id1,nested-folder-id1,nested-folder-id,nested-folder-id1Meta,nested-folder-id1Data,500,2017-09-07 17:30:00.000,2017-09-07 17:30:00.000,https://arweave.net/nested-folder-id1Meta\r\n' - 'nested-folder-id0,nested-folder-id0,nested-folder-id,nested-folder-id0Meta,nested-folder-id0Data,500,2017-09-07 17:30:00.000,2017-09-07 17:30:00.000,https://arweave.net/nested-folder-id0Meta'; + 'File Id,File Name,Parent Folder ID,Parent Folder Name,Data Transaction ID,Metadata Transaction ID,File Size,Date Created,Last Modified,Direct Download Link,Status\r\n' + 'root-folder-id4,root-folder-id4,root-folder-id,folder-name,root-folder-id4Data,root-folder-id4Meta,500,2017-09-07 17:30:00.000,2017-09-07 17:30:00.000,https://arweave.net/root-folder-id4Data,confirmed\r\n' + 'root-folder-id2,root-folder-id2,root-folder-id,folder-name,root-folder-id2Data,root-folder-id2Meta,500,2017-09-07 17:30:00.000,2017-09-07 17:30:00.000,https://arweave.net/root-folder-id2Data,confirmed\r\n' + 'root-folder-id3,root-folder-id3,root-folder-id,folder-name,root-folder-id3Data,root-folder-id3Meta,500,2017-09-07 17:30:00.000,2017-09-07 17:30:00.000,https://arweave.net/root-folder-id3Data,confirmed\r\n' + 'root-folder-id1,root-folder-id1,root-folder-id,folder-name,root-folder-id1Data,root-folder-id1Meta,500,2017-09-07 17:30:00.000,2017-09-07 17:30:00.000,https://arweave.net/root-folder-id1Data,confirmed\r\n' + 'root-folder-id0,root-folder-id0,root-folder-id,folder-name,root-folder-id0Data,root-folder-id0Meta,500,2017-09-07 17:30:00.000,2017-09-07 17:30:00.000,https://arweave.net/root-folder-id0Data,confirmed\r\n' + 'nested-folder-id4,nested-folder-id4,nested-folder-id,folder-name,nested-folder-id4Meta,nested-folder-id4Data,500,2017-09-07 17:30:00.000,2017-09-07 17:30:00.000,https://arweave.net/nested-folder-id4Meta,confirmed\r\n' + 'nested-folder-id2,nested-folder-id2,nested-folder-id,folder-name,nested-folder-id2Meta,nested-folder-id2Data,500,2017-09-07 17:30:00.000,2017-09-07 17:30:00.000,https://arweave.net/nested-folder-id2Meta,confirmed\r\n' + 'nested-folder-id3,nested-folder-id3,nested-folder-id,folder-name,nested-folder-id3Meta,nested-folder-id3Data,500,2017-09-07 17:30:00.000,2017-09-07 17:30:00.000,https://arweave.net/nested-folder-id3Meta,confirmed\r\n' + 'nested-folder-id1,nested-folder-id1,nested-folder-id,folder-name,nested-folder-id1Meta,nested-folder-id1Data,500,2017-09-07 17:30:00.000,2017-09-07 17:30:00.000,https://arweave.net/nested-folder-id1Meta,confirmed\r\n' + 'nested-folder-id0,nested-folder-id0,nested-folder-id,folder-name,nested-folder-id0Meta,nested-folder-id0Data,500,2017-09-07 17:30:00.000,2017-09-07 17:30:00.000,https://arweave.net/nested-folder-id0Meta,confirmed';