Use fileMigrationDB for verifying if file needs update
This commit is contained in:
parent
dfa761ae42
commit
4d0059df29
|
@ -107,15 +107,20 @@ class FilesMigrationDB {
|
|||
}
|
||||
|
||||
Future<int> deleteByLocalIDs(List<String> localIDs) async {
|
||||
if (localIDs.isEmpty) {
|
||||
return -1;
|
||||
}
|
||||
String inParam = "";
|
||||
for (final localID in localIDs) {
|
||||
inParam += "'" + localID + "',";
|
||||
}
|
||||
inParam = inParam.substring(0, inParam.length - 1);
|
||||
final db = await instance.database;
|
||||
return await db.delete(
|
||||
tableName,
|
||||
where: '$_columnLocalID IN (${localIDs.join(', ')})',
|
||||
db.rawQuery(
|
||||
'''
|
||||
DELETE FROM $tableName
|
||||
WHERE $_columnLocalID IN ($inParam);
|
||||
''',
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -124,9 +129,9 @@ class FilesMigrationDB {
|
|||
String reason,
|
||||
) async {
|
||||
final db = await instance.database;
|
||||
String whereClause = '$_columnReason = $reason';
|
||||
if (_columnReason == missingLocation) {
|
||||
whereClause = '($_columnReason = $reason OR $_columnReason IS NULL';
|
||||
String whereClause = '$_columnReason = "$reason"';
|
||||
if (reason == missingLocation) {
|
||||
whereClause = '($_columnReason = "$reason" OR $_columnReason IS NULL)';
|
||||
}
|
||||
final rows = await db.query(
|
||||
tableName,
|
||||
|
|
|
@ -6,6 +6,7 @@ import 'package:logging/logging.dart';
|
|||
import 'package:photo_manager/photo_manager.dart';
|
||||
import 'package:photos/db/file_migration_db.dart';
|
||||
import 'package:photos/db/files_db.dart';
|
||||
import 'package:photos/utils/file_uploader_util.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
// LocalFileUpdateService tracks all the potential local file IDs which have
|
||||
|
@ -52,6 +53,7 @@ class LocalFileUpdateService {
|
|||
_logger.info("start migration for missing location");
|
||||
await _runMigrationForFilesWithMissingLocation();
|
||||
}
|
||||
await _markFilesWhichAreActuallyUpdated();
|
||||
_existingMigration.complete();
|
||||
_existingMigration = null;
|
||||
} catch (e, s) {
|
||||
|
@ -61,6 +63,82 @@ class LocalFileUpdateService {
|
|||
}
|
||||
}
|
||||
|
||||
// This method analyses all of local files for which the file
|
||||
// modification/update time was changed. It checks if the existing fileHash
|
||||
// is different from the hash of uploaded file. If fileHash are different,
|
||||
// then it marks the file for file update.
|
||||
Future<void> _markFilesWhichAreActuallyUpdated() async {
|
||||
final sTime = DateTime.now().microsecondsSinceEpoch;
|
||||
bool hasData = true;
|
||||
const int limitInBatch = 100;
|
||||
while (hasData) {
|
||||
var localIDsToProcess =
|
||||
await _filesMigrationDB.getLocalIDsForPotentialReUpload(
|
||||
limitInBatch,
|
||||
FilesMigrationDB.modificationTimeUpdated,
|
||||
);
|
||||
if (localIDsToProcess.isEmpty) {
|
||||
hasData = false;
|
||||
} else {
|
||||
await _checkAndMarkFilesWithDifferentHashForFileUpdate(
|
||||
localIDsToProcess,
|
||||
);
|
||||
}
|
||||
}
|
||||
final eTime = DateTime.now().microsecondsSinceEpoch;
|
||||
final d = Duration(microseconds: eTime - sTime);
|
||||
_logger.info(
|
||||
'_markFilesWhichAreActuallyUpdated migration completed in ${d.inSeconds.toString()} seconds',
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _checkAndMarkFilesWithDifferentHashForFileUpdate(
|
||||
List<String> localIDsToProcess,
|
||||
) async {
|
||||
_logger.info("files to process ${localIDsToProcess.length}");
|
||||
var localFiles = await FilesDB.instance.getLocalFiles(localIDsToProcess);
|
||||
Set<String> processedIDs = {};
|
||||
for (var file in localFiles) {
|
||||
if (processedIDs.contains(file.localID)) {
|
||||
continue;
|
||||
}
|
||||
MediaUploadData uploadData;
|
||||
try {
|
||||
uploadData = await getUploadDataFromEnteFile(file);
|
||||
if (file.hash != null ||
|
||||
(file.hash == uploadData.fileHash ||
|
||||
file.hash == uploadData.zipHash)) {
|
||||
_logger.info("Skip file update as hash matched ${file.tag()}");
|
||||
} else {
|
||||
_logger.info(
|
||||
"Marking for file update as hash did not match ${file.tag()}",
|
||||
);
|
||||
await FilesDB.instance.updateUploadedFile(
|
||||
file.localID,
|
||||
file.title,
|
||||
file.location,
|
||||
file.creationTime,
|
||||
file.modificationTime,
|
||||
null,
|
||||
);
|
||||
}
|
||||
processedIDs.add(file.localID);
|
||||
} catch (e) {
|
||||
_logger.severe("Failed to get file uploadData", e);
|
||||
} finally {
|
||||
// delete the file from app's internal cache if it was copied to app
|
||||
// for upload. Shared Media should only be cleared when the upload
|
||||
// succeeds.
|
||||
if (Platform.isIOS &&
|
||||
uploadData != null &&
|
||||
uploadData.sourceFile != null) {
|
||||
await uploadData.sourceFile.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
await _filesMigrationDB.deleteByLocalIDs(processedIDs.toList());
|
||||
}
|
||||
|
||||
Future<void> _runMigrationForFilesWithMissingLocation() async {
|
||||
if (!Platform.isAndroid) {
|
||||
return;
|
||||
|
@ -82,7 +160,7 @@ class LocalFileUpdateService {
|
|||
if (localIDsToProcess.isEmpty) {
|
||||
hasData = false;
|
||||
} else {
|
||||
await _checkAndMarkFilesForReUpload(localIDsToProcess);
|
||||
await _checkAndMarkFilesWithLocationForReUpload(localIDsToProcess);
|
||||
}
|
||||
}
|
||||
final eTime = DateTime.now().microsecondsSinceEpoch;
|
||||
|
@ -94,7 +172,7 @@ class LocalFileUpdateService {
|
|||
await _markLocationMigrationAsCompleted();
|
||||
}
|
||||
|
||||
Future<void> _checkAndMarkFilesForReUpload(
|
||||
Future<void> _checkAndMarkFilesWithLocationForReUpload(
|
||||
List<String> localIDsToProcess,
|
||||
) async {
|
||||
_logger.info("files to process ${localIDsToProcess.length}");
|
||||
|
|
|
@ -6,6 +6,7 @@ import 'package:logging/logging.dart';
|
|||
import 'package:photo_manager/photo_manager.dart';
|
||||
import 'package:photos/core/configuration.dart';
|
||||
import 'package:photos/core/event_bus.dart';
|
||||
import 'package:photos/db/file_migration_db.dart';
|
||||
import 'package:photos/db/files_db.dart';
|
||||
import 'package:photos/events/local_photos_updated_event.dart';
|
||||
import 'package:photos/events/sync_status_update_event.dart';
|
||||
|
@ -244,17 +245,15 @@ class LocalSyncService {
|
|||
updatedFiles.length.toString() + " local files were updated.",
|
||||
);
|
||||
}
|
||||
|
||||
List<String> updatedLocalIDs = [];
|
||||
for (final file in updatedFiles) {
|
||||
await captureUpdateLogs(file);
|
||||
await _db.updateUploadedFile(
|
||||
file.localID,
|
||||
file.title,
|
||||
file.location,
|
||||
file.creationTime,
|
||||
file.modificationTime,
|
||||
null,
|
||||
);
|
||||
if (file.localID != null) {
|
||||
updatedLocalIDs.add(file.localID);
|
||||
}
|
||||
}
|
||||
FilesMigrationDB.instance.insertMultiple(updatedLocalIDs,
|
||||
reason: FilesMigrationDB.modificationTimeUpdated);
|
||||
final List<File> allFiles = [];
|
||||
allFiles.addAll(files);
|
||||
files.removeWhere((file) => existingLocalFileIDs.contains(file.localID));
|
||||
|
@ -266,32 +265,6 @@ class LocalSyncService {
|
|||
await _prefs.setInt(kDbUpdationTimeKey, toTime);
|
||||
}
|
||||
|
||||
// _captureUpdateLogs is a helper method to log details
|
||||
// about the file which is being marked for re-upload
|
||||
Future<void> captureUpdateLogs(File file) async {
|
||||
_logger.info(
|
||||
're-upload locally updated file ${file.toString()}',
|
||||
);
|
||||
try {
|
||||
if (Platform.isIOS) {
|
||||
var assetEntity = await AssetEntity.fromId(file.localID);
|
||||
if (assetEntity != null) {
|
||||
var isLocallyAvailable =
|
||||
await assetEntity.isLocallyAvailable(isOrigin: true);
|
||||
_logger.info(
|
||||
're-upload asset ${file.toString()} with localAvailableFlag '
|
||||
'$isLocallyAvailable and fav ${assetEntity.isFavorite}',
|
||||
);
|
||||
} else {
|
||||
_logger
|
||||
.info('re-upload failed to fetch assetInfo ${file.toString()}');
|
||||
}
|
||||
}
|
||||
} catch (ignore) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
|
||||
void _updatePathsToBackup(List<File> files) {
|
||||
if (Configuration.instance.hasSelectedAllFoldersForBackup()) {
|
||||
final pathsToBackup = Configuration.instance.getPathsToBackUp();
|
||||
|
|
|
@ -16,7 +16,6 @@ import 'package:photos/models/file.dart';
|
|||
import 'package:photos/models/file_type.dart';
|
||||
import 'package:photos/services/app_lifecycle_service.dart';
|
||||
import 'package:photos/services/collections_service.dart';
|
||||
import 'package:photos/services/feature_flag_service.dart';
|
||||
import 'package:photos/services/ignored_files_service.dart';
|
||||
import 'package:photos/services/local_file_update_service.dart';
|
||||
import 'package:photos/services/local_sync_service.dart';
|
||||
|
@ -134,9 +133,8 @@ class RemoteSyncService {
|
|||
if (!_hasReSynced()) {
|
||||
await _markReSyncAsDone();
|
||||
}
|
||||
if (FeatureFlagService.instance.enableMissingLocationMigration()) {
|
||||
_localFileUpdateService.markUpdatedFilesForReUpload();
|
||||
}
|
||||
|
||||
unawaited(_localFileUpdateService.markUpdatedFilesForReUpload());
|
||||
}
|
||||
|
||||
Future<void> _syncUpdatedCollections(bool silently) async {
|
||||
|
|
Loading…
Reference in a new issue