Skip to content

Commit faaadaf

Browse files
committed
chore: detect takeouts inside zip files when importing history
1 parent f89c4b5 commit faaadaf

File tree

2 files changed

+79
-29
lines changed

2 files changed

+79
-29
lines changed

lib/controller/json_to_history_parser.dart

Lines changed: 78 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@ import 'package:flutter/material.dart';
99

1010
import 'package:intl/intl.dart';
1111

12+
import 'package:namida/class/file_parts.dart';
1213
import 'package:namida/class/split_config.dart';
1314
import 'package:namida/class/track.dart';
1415
import 'package:namida/class/video.dart';
1516
import 'package:namida/controller/history_controller.dart';
1617
import 'package:namida/controller/indexer_controller.dart';
1718
import 'package:namida/controller/navigator_controller.dart';
1819
import 'package:namida/controller/notification_controller.dart';
20+
import 'package:namida/controller/platform/zip_manager/zip_manager.dart';
1921
import 'package:namida/core/constants.dart';
2022
import 'package:namida/core/enums.dart';
2123
import 'package:namida/core/extensions.dart';
@@ -353,6 +355,9 @@ class JsonToHistoryParser {
353355
}
354356

355357
void _resetValues() {
358+
isParsing.value = false;
359+
isLoadingFile.value = false;
360+
356361
totalJsonToParse.value = 0;
357362
parsedHistoryJson.value = 0;
358363
addedHistoryJsonToPlaylist.value = 0;
@@ -376,43 +381,28 @@ class JsonToHistoryParser {
376381
DateTime? oldestDate,
377382
DateTime? newestDate,
378383
}) async {
384+
_resetValues();
385+
isParsing.value = true;
386+
isLoadingFile.value = true;
387+
_currentOldestDate.value = oldestDate;
388+
_currentNewestDate.value = newestDate;
389+
showParsingProgressDialog();
390+
391+
Directory? tempZipMainDestination;
392+
379393
if (files.isEmpty) {
380394
if (mainDirectory != null) {
381-
final contents = await mainDirectory.listAllIsolate(recursive: true);
382-
if (source == TrackSource.youtube || source == TrackSource.youtubeMusic) {
383-
contents.loop(
384-
(file) {
385-
if (file is File && NamidaFileExtensionsWrapper.json.isPathValid(file.path)) {
386-
final name = file.path.getFilename;
387-
if (name.contains('watch-history')) files.add(file);
388-
}
389-
},
390-
);
391-
} else {
392-
contents.loop(
393-
(file) {
394-
if (file is File && NamidaFileExtensionsWrapper.csv.isPathValid(file.path)) {
395-
// folder shouldnt contain yt playlists/etc csv files tho, otherwise wer cooked
396-
final name = file.path.getFilename;
397-
if (name != 'subscriptions.csv') files.add(file);
398-
}
399-
},
400-
);
401-
}
395+
tempZipMainDestination = await Directory.systemTemp.createTemp('namida_parser_');
396+
files = await _filterFilesFromDir(mainDirectory, source, tempZipMainDestination);
402397
}
403398
}
404399
if (files.isEmpty) {
405400
snackyy(message: 'No related files were found in this directory.', isError: true);
401+
_resetValues();
402+
NamidaNavigator.inst.closeDialog();
406403
return;
407404
}
408405

409-
_resetValues();
410-
isParsing.value = true;
411-
isLoadingFile.value = true;
412-
_currentOldestDate.value = oldestDate;
413-
_currentNewestDate.value = newestDate;
414-
showParsingProgressDialog();
415-
416406
// TODO: warning to backup history
417407

418408
await Future.delayed(Duration.zero);
@@ -486,6 +476,66 @@ class JsonToHistoryParser {
486476
_latestMissingMap.value = allMissingEntries;
487477
_latestMissingMapAddedStatus.clear();
488478
showMissingEntriesDialog();
479+
480+
if (tempZipMainDestination != null) {
481+
tempZipMainDestination.delete(recursive: true);
482+
}
483+
}
484+
485+
Future<List<File>> _filterFilesFromDir(Directory mainDirectory, TrackSource source, Directory tempZipMainDestination) async {
486+
final files = <File>[];
487+
488+
late final zipManager = ZipManager.platform();
489+
490+
Future<List<FileSystemEntity>> listDir(Directory dir) => dir.listAllIsolate(recursive: true);
491+
FutureOr<void> executeFileEnsureZipExtracted(File file, void Function(File file) onMatch) async {
492+
if (NamidaFileExtensionsWrapper.zip.isPathValid(file.path)) {
493+
final destinationDir = Directory(FileParts.joinPath(tempZipMainDestination.path, file.path.getFilenameWOExt));
494+
await zipManager.extractZip(zipFile: file, destinationDir: destinationDir);
495+
final zipContents = await listDir(destinationDir);
496+
for (final file in zipContents) {
497+
if (file is File) {
498+
onMatch(file);
499+
}
500+
}
501+
} else {
502+
onMatch(file);
503+
}
504+
}
505+
506+
final contents = await listDir(mainDirectory);
507+
508+
if (source == TrackSource.youtube || source == TrackSource.youtubeMusic) {
509+
for (final file in contents) {
510+
if (file is File) {
511+
await executeFileEnsureZipExtracted(
512+
file,
513+
(file) {
514+
if (NamidaFileExtensionsWrapper.json.isPathValid(file.path)) {
515+
final name = file.path.getFilename;
516+
if (name.contains('watch-history')) files.add(file);
517+
}
518+
},
519+
);
520+
}
521+
}
522+
} else {
523+
for (final file in contents) {
524+
if (file is File) {
525+
await executeFileEnsureZipExtracted(
526+
file,
527+
(file) {
528+
if (NamidaFileExtensionsWrapper.csv.isPathValid(file.path)) {
529+
// folder shouldnt contain yt playlists/etc csv files tho, otherwise wer cooked
530+
final name = file.path.getFilename;
531+
if (name != 'subscriptions.csv') files.add(file);
532+
}
533+
},
534+
);
535+
}
536+
}
537+
}
538+
return files;
489539
}
490540

491541
Future<({List<int> historyDays, List<int> ytHistoryDays, Map<_MissingListenEntry, List<int>> missingEntries})?> _parseYTHistoryJsonAndAdd({

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name: namida
22
description: A Beautiful and Feature-rich Music Player, With YouTube & Video Support Built in Flutter
33
publish_to: "none"
4-
version: 5.2.29-beta+250629220
4+
version: 5.2.3-beta+250629220
55

66
environment:
77
sdk: ">=3.6.0 <4.0.0"

0 commit comments

Comments
 (0)