2020-03-30 14:28:46 +00:00
|
|
|
import 'dart:async';
|
2020-11-30 10:20:08 +00:00
|
|
|
import 'dart:io';
|
2020-11-16 16:35:16 +00:00
|
|
|
import 'package:connectivity/connectivity.dart';
|
2020-11-02 10:57:55 +00:00
|
|
|
import 'package:flutter/foundation.dart';
|
2020-12-01 09:07:48 +00:00
|
|
|
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
|
2020-05-02 16:28:54 +00:00
|
|
|
import 'package:logging/logging.dart';
|
2020-12-01 09:07:48 +00:00
|
|
|
import 'package:photos/core/cache/thumbnail_cache_manager.dart';
|
|
|
|
import 'package:photos/core/cache/video_cache_manager.dart';
|
2020-05-04 20:08:20 +00:00
|
|
|
import 'package:photos/core/event_bus.dart';
|
2020-11-19 18:22:30 +00:00
|
|
|
import 'package:photos/core/network.dart';
|
2020-07-20 11:03:09 +00:00
|
|
|
import 'package:photos/db/files_db.dart';
|
2020-10-31 17:59:00 +00:00
|
|
|
import 'package:photos/events/collection_updated_event.dart';
|
2020-11-16 16:35:16 +00:00
|
|
|
import 'package:photos/events/sync_status_update_event.dart';
|
2021-02-02 16:35:38 +00:00
|
|
|
import 'package:photos/events/subscription_purchased_event.dart';
|
2020-11-02 10:57:55 +00:00
|
|
|
import 'package:photos/models/file_type.dart';
|
2021-01-13 19:41:32 +00:00
|
|
|
import 'package:photos/services/billing_service.dart';
|
2020-10-10 21:20:20 +00:00
|
|
|
import 'package:photos/services/collections_service.dart';
|
2020-11-01 11:00:50 +00:00
|
|
|
import 'package:photos/utils/date_time_util.dart';
|
2020-10-03 17:58:26 +00:00
|
|
|
import 'package:photos/utils/file_downloader.dart';
|
|
|
|
import 'package:photos/repositories/file_repository.dart';
|
2020-03-24 19:59:36 +00:00
|
|
|
import 'package:photo_manager/photo_manager.dart';
|
2020-11-01 11:00:50 +00:00
|
|
|
import 'package:photos/utils/file_sync_util.dart';
|
2020-10-03 17:58:26 +00:00
|
|
|
import 'package:photos/utils/file_uploader.dart';
|
2020-03-24 19:59:36 +00:00
|
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
import 'package:dio/dio.dart';
|
2020-06-19 23:03:26 +00:00
|
|
|
import 'package:photos/models/file.dart';
|
2020-03-26 14:39:31 +00:00
|
|
|
|
2020-05-04 20:08:20 +00:00
|
|
|
import 'package:photos/core/configuration.dart';
|
2020-04-30 15:09:41 +00:00
|
|
|
|
2020-10-03 17:58:26 +00:00
|
|
|
class SyncService {
|
2020-11-01 11:00:50 +00:00
|
|
|
final _logger = Logger("SyncService");
|
2020-11-19 18:22:30 +00:00
|
|
|
final _dio = Network.instance.getDio();
|
2020-07-20 11:03:09 +00:00
|
|
|
final _db = FilesDB.instance;
|
2020-10-21 16:20:41 +00:00
|
|
|
final _uploader = FileUploader.instance;
|
2020-10-28 15:45:05 +00:00
|
|
|
final _collectionsService = CollectionsService.instance;
|
2020-09-09 21:24:03 +00:00
|
|
|
final _downloader = DiffFetcher();
|
2020-04-30 15:09:41 +00:00
|
|
|
bool _isSyncInProgress = false;
|
2020-09-17 19:40:08 +00:00
|
|
|
bool _syncStopRequested = false;
|
2020-06-15 18:42:25 +00:00
|
|
|
Future<void> _existingSync;
|
2020-07-15 17:09:52 +00:00
|
|
|
SharedPreferences _prefs;
|
2020-11-16 16:35:16 +00:00
|
|
|
SyncStatusUpdate _lastSyncStatusEvent;
|
2020-04-27 13:02:29 +00:00
|
|
|
|
2020-08-11 23:04:16 +00:00
|
|
|
static final _dbUpdationTimeKey = "db_updation_time";
|
2020-12-03 22:19:25 +00:00
|
|
|
static final _diffLimit = 200;
|
2020-03-24 19:59:36 +00:00
|
|
|
|
2020-10-03 17:58:26 +00:00
|
|
|
SyncService._privateConstructor() {
|
2021-02-02 16:35:38 +00:00
|
|
|
Bus.instance.on<SubscriptionPurchasedEvent>().listen((event) {
|
2021-02-02 18:25:43 +00:00
|
|
|
_uploader.clearQueue();
|
2020-04-30 15:09:41 +00:00
|
|
|
sync();
|
|
|
|
});
|
2020-11-16 16:35:16 +00:00
|
|
|
|
|
|
|
Connectivity().onConnectivityChanged.listen((ConnectivityResult result) {
|
|
|
|
_logger.info("Connectivity change detected " + result.toString());
|
2021-01-13 19:41:32 +00:00
|
|
|
if (Configuration.instance.hasConfiguredAccount() &&
|
2021-01-18 17:11:40 +00:00
|
|
|
BillingService.instance.getSubscription() != null) {
|
2021-01-13 19:41:32 +00:00
|
|
|
sync(isAppInBackground: true);
|
|
|
|
}
|
2020-11-16 16:35:16 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
Bus.instance.on<SyncStatusUpdate>().listen((event) {
|
|
|
|
_lastSyncStatusEvent = event;
|
|
|
|
});
|
2020-04-30 15:09:41 +00:00
|
|
|
}
|
|
|
|
|
2020-10-03 17:58:26 +00:00
|
|
|
static final SyncService instance = SyncService._privateConstructor();
|
2020-03-28 13:56:06 +00:00
|
|
|
|
2020-07-15 17:09:52 +00:00
|
|
|
Future<void> init() async {
|
|
|
|
_prefs = await SharedPreferences.getInstance();
|
2020-11-30 10:20:08 +00:00
|
|
|
if (Platform.isIOS) {
|
|
|
|
_logger.info("Clearing file cache");
|
|
|
|
await PhotoManager.clearFileCache();
|
|
|
|
_logger.info("Cleared file cache");
|
|
|
|
}
|
2020-07-15 17:09:52 +00:00
|
|
|
}
|
|
|
|
|
2021-01-13 17:39:33 +00:00
|
|
|
Future<void> sync({bool isAppInBackground = false}) async {
|
2020-09-17 19:40:08 +00:00
|
|
|
_syncStopRequested = false;
|
2020-04-30 15:09:41 +00:00
|
|
|
if (_isSyncInProgress) {
|
2020-05-02 16:28:54 +00:00
|
|
|
_logger.warning("Sync already in progress, skipping.");
|
2020-06-15 18:42:25 +00:00
|
|
|
return _existingSync;
|
2020-04-27 13:02:29 +00:00
|
|
|
}
|
2020-04-30 15:09:41 +00:00
|
|
|
_isSyncInProgress = true;
|
2020-06-15 18:42:25 +00:00
|
|
|
_existingSync = Future<void>(() async {
|
|
|
|
_logger.info("Syncing...");
|
|
|
|
try {
|
2021-01-13 17:39:33 +00:00
|
|
|
await _doSync(isAppInBackground: isAppInBackground);
|
2020-12-03 21:47:06 +00:00
|
|
|
if (_lastSyncStatusEvent != null) {
|
|
|
|
Bus.instance.fire(SyncStatusUpdate(SyncStatus.completed));
|
|
|
|
}
|
2020-11-16 16:35:16 +00:00
|
|
|
} on WiFiUnavailableError {
|
|
|
|
_logger.warning("Not uploading over mobile data");
|
|
|
|
Bus.instance.fire(
|
|
|
|
SyncStatusUpdate(SyncStatus.paused, reason: "Waiting for WiFi..."));
|
2021-01-13 08:50:14 +00:00
|
|
|
} on SyncStopRequestedError {
|
|
|
|
_syncStopRequested = false;
|
|
|
|
Bus.instance
|
|
|
|
.fire(SyncStatusUpdate(SyncStatus.completed, wasStopped: true));
|
2021-02-02 16:35:38 +00:00
|
|
|
} on NoActiveSubscriptionError {
|
|
|
|
Bus.instance.fire(SyncStatusUpdate(SyncStatus.error,
|
2021-02-02 16:57:16 +00:00
|
|
|
error: NoActiveSubscriptionError()));
|
2020-10-28 15:25:32 +00:00
|
|
|
} catch (e, s) {
|
|
|
|
_logger.severe(e, s);
|
2020-11-16 16:35:16 +00:00
|
|
|
Bus.instance.fire(SyncStatusUpdate(SyncStatus.error));
|
2020-06-15 18:42:25 +00:00
|
|
|
} finally {
|
|
|
|
_isSyncInProgress = false;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return _existingSync;
|
|
|
|
}
|
2020-04-30 15:09:41 +00:00
|
|
|
|
2020-09-17 19:40:08 +00:00
|
|
|
void stopSync() {
|
|
|
|
_logger.info("Sync stop requested");
|
|
|
|
_syncStopRequested = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool shouldStopSync() {
|
|
|
|
return _syncStopRequested;
|
|
|
|
}
|
|
|
|
|
2020-07-15 17:09:52 +00:00
|
|
|
bool hasScannedDisk() {
|
2020-08-11 23:04:16 +00:00
|
|
|
return _prefs.containsKey(_dbUpdationTimeKey);
|
2020-06-15 19:57:48 +00:00
|
|
|
}
|
|
|
|
|
2020-11-12 16:32:10 +00:00
|
|
|
bool isSyncInProgress() {
|
|
|
|
return _isSyncInProgress;
|
|
|
|
}
|
|
|
|
|
2020-11-16 16:35:16 +00:00
|
|
|
SyncStatusUpdate getLastSyncStatusEvent() {
|
|
|
|
return _lastSyncStatusEvent;
|
|
|
|
}
|
|
|
|
|
2021-01-13 17:39:33 +00:00
|
|
|
Future<void> _doSync({bool isAppInBackground = false}) async {
|
2020-12-07 23:03:25 +00:00
|
|
|
final existingLocalFileIDs = await _db.getExistingLocalFileIDs();
|
|
|
|
final syncStartTime = DateTime.now().microsecondsSinceEpoch;
|
2021-01-13 17:39:33 +00:00
|
|
|
if (isAppInBackground) {
|
|
|
|
await PhotoManager.setIgnorePermissionCheck(true);
|
|
|
|
} else {
|
|
|
|
final result = await PhotoManager.requestPermission();
|
|
|
|
if (!result) {
|
|
|
|
_logger.severe("Did not get permission");
|
|
|
|
await _prefs.setInt(_dbUpdationTimeKey, syncStartTime);
|
|
|
|
await FileRepository.instance.reloadFiles();
|
|
|
|
return await syncWithRemote();
|
|
|
|
}
|
2020-07-27 21:07:56 +00:00
|
|
|
}
|
2020-11-01 11:00:50 +00:00
|
|
|
final lastDBUpdationTime = _prefs.getInt(_dbUpdationTimeKey);
|
|
|
|
if (lastDBUpdationTime != null && lastDBUpdationTime != 0) {
|
2020-12-01 08:09:02 +00:00
|
|
|
await _loadAndStorePhotos(
|
2020-12-01 08:56:37 +00:00
|
|
|
lastDBUpdationTime, syncStartTime, existingLocalFileIDs);
|
2020-11-01 11:00:50 +00:00
|
|
|
} else {
|
|
|
|
// Load from 0 - 01.01.2010
|
|
|
|
var startTime = 0;
|
|
|
|
var toYear = 2010;
|
|
|
|
var toTime = DateTime(toYear).microsecondsSinceEpoch;
|
|
|
|
while (toTime < syncStartTime) {
|
2020-12-01 08:09:02 +00:00
|
|
|
await _loadAndStorePhotos(startTime, toTime, existingLocalFileIDs);
|
2020-11-01 11:00:50 +00:00
|
|
|
startTime = toTime;
|
|
|
|
toYear++;
|
|
|
|
toTime = DateTime(toYear).microsecondsSinceEpoch;
|
2020-03-30 14:28:46 +00:00
|
|
|
}
|
2020-12-01 08:09:02 +00:00
|
|
|
await _loadAndStorePhotos(startTime, syncStartTime, existingLocalFileIDs);
|
2020-10-30 21:07:20 +00:00
|
|
|
}
|
2020-12-07 23:03:25 +00:00
|
|
|
await FileRepository.instance.reloadFiles();
|
2021-02-01 11:40:15 +00:00
|
|
|
await syncWithRemote();
|
2020-04-24 12:40:24 +00:00
|
|
|
}
|
|
|
|
|
2020-12-01 08:09:02 +00:00
|
|
|
Future<void> _loadAndStorePhotos(
|
|
|
|
int fromTime, int toTime, Set<String> existingLocalFileIDs) async {
|
2020-11-01 11:00:50 +00:00
|
|
|
_logger.info("Loading photos from " +
|
|
|
|
getMonthAndYear(DateTime.fromMicrosecondsSinceEpoch(fromTime)) +
|
|
|
|
" to " +
|
|
|
|
getMonthAndYear(DateTime.fromMicrosecondsSinceEpoch(toTime)));
|
|
|
|
final files = await getDeviceFiles(fromTime, toTime);
|
|
|
|
if (files.isNotEmpty) {
|
2020-12-03 21:47:06 +00:00
|
|
|
Bus.instance.fire(SyncStatusUpdate(SyncStatus.applying_local_diff));
|
2020-11-01 11:00:50 +00:00
|
|
|
_logger.info("Fetched " + files.length.toString() + " files.");
|
2020-11-30 18:42:11 +00:00
|
|
|
final updatedFiles =
|
2020-12-01 08:09:02 +00:00
|
|
|
files.where((file) => existingLocalFileIDs.contains(file.localID));
|
2020-11-30 18:42:11 +00:00
|
|
|
_logger.info(updatedFiles.length.toString() + " files were updated.");
|
|
|
|
for (final file in updatedFiles) {
|
|
|
|
await _db.updateUploadedFile(
|
|
|
|
file.localID,
|
|
|
|
file.title,
|
|
|
|
file.location,
|
|
|
|
file.creationTime,
|
|
|
|
file.modificationTime,
|
|
|
|
null,
|
|
|
|
);
|
|
|
|
}
|
2020-12-01 08:09:02 +00:00
|
|
|
files.removeWhere((file) => existingLocalFileIDs.contains(file.localID));
|
2020-11-01 11:00:50 +00:00
|
|
|
await _db.insertMultiple(files);
|
|
|
|
_logger.info("Inserted " + files.length.toString() + " files.");
|
|
|
|
await FileRepository.instance.reloadFiles();
|
2020-05-27 16:31:12 +00:00
|
|
|
}
|
2020-12-03 21:01:24 +00:00
|
|
|
await _prefs.setInt(_dbUpdationTimeKey, toTime);
|
2020-05-27 16:31:12 +00:00
|
|
|
}
|
|
|
|
|
2020-12-03 22:30:10 +00:00
|
|
|
Future<void> syncWithRemote({bool silently = false}) async {
|
2020-05-28 10:19:25 +00:00
|
|
|
if (!Configuration.instance.hasConfiguredAccount()) {
|
2020-06-15 18:42:25 +00:00
|
|
|
return Future.error("Account not configured yet");
|
2020-05-28 10:19:25 +00:00
|
|
|
}
|
2020-12-03 21:01:24 +00:00
|
|
|
final updatedCollections = await _collectionsService.sync();
|
2020-12-03 22:30:10 +00:00
|
|
|
if (updatedCollections.isNotEmpty && !silently) {
|
2020-12-03 21:47:06 +00:00
|
|
|
Bus.instance.fire(SyncStatusUpdate(SyncStatus.applying_remote_diff));
|
|
|
|
}
|
2020-12-03 21:01:24 +00:00
|
|
|
for (final collection in updatedCollections) {
|
2020-10-28 15:45:05 +00:00
|
|
|
await _fetchEncryptedFilesDiff(collection.id);
|
|
|
|
}
|
2020-11-01 06:45:10 +00:00
|
|
|
await deleteFilesOnServer();
|
2020-12-03 22:19:25 +00:00
|
|
|
bool hasUploadedFiles = await _uploadDiff();
|
|
|
|
if (hasUploadedFiles) {
|
2020-12-03 22:30:10 +00:00
|
|
|
syncWithRemote(silently: true);
|
2020-12-03 22:19:25 +00:00
|
|
|
}
|
2020-05-25 20:43:17 +00:00
|
|
|
}
|
|
|
|
|
2020-10-28 15:45:05 +00:00
|
|
|
Future<void> _fetchEncryptedFilesDiff(int collectionID) async {
|
2020-09-09 21:24:03 +00:00
|
|
|
final diff = await _downloader.getEncryptedFilesDiff(
|
2020-10-28 15:45:05 +00:00
|
|
|
collectionID,
|
2020-12-03 21:01:24 +00:00
|
|
|
_collectionsService.getCollectionSyncTime(collectionID),
|
2020-10-28 15:45:05 +00:00
|
|
|
_diffLimit,
|
|
|
|
);
|
2021-01-02 09:04:36 +00:00
|
|
|
if (diff.updatedFiles.isNotEmpty) {
|
|
|
|
await _storeDiff(diff.updatedFiles, collectionID);
|
|
|
|
_logger.info("Updated " +
|
|
|
|
diff.updatedFiles.length.toString() +
|
|
|
|
" files in collection " +
|
|
|
|
collectionID.toString());
|
2020-08-11 23:04:16 +00:00
|
|
|
FileRepository.instance.reloadFiles();
|
2020-10-31 17:59:28 +00:00
|
|
|
Bus.instance.fire(CollectionUpdatedEvent(collectionID: collectionID));
|
2021-01-02 09:04:36 +00:00
|
|
|
if (diff.fetchCount == _diffLimit) {
|
2020-10-28 15:45:05 +00:00
|
|
|
return await _fetchEncryptedFilesDiff(collectionID);
|
2020-08-11 23:04:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-03 22:19:25 +00:00
|
|
|
Future<bool> _uploadDiff() async {
|
2021-02-02 16:35:38 +00:00
|
|
|
if (!BillingService.instance.hasActiveSubscription()) {
|
|
|
|
await BillingService.instance.fetchSubscription();
|
|
|
|
if (!BillingService.instance.hasActiveSubscription()) {
|
|
|
|
throw NoActiveSubscriptionError();
|
|
|
|
}
|
|
|
|
}
|
2020-10-17 17:21:32 +00:00
|
|
|
final foldersToBackUp = Configuration.instance.getPathsToBackUp();
|
2020-11-30 18:42:11 +00:00
|
|
|
final filesToBeUploaded =
|
2020-09-17 18:48:25 +00:00
|
|
|
await _db.getFilesToBeUploadedWithinFolders(foldersToBackUp);
|
2020-11-12 16:32:10 +00:00
|
|
|
if (kDebugMode) {
|
2020-11-30 18:42:11 +00:00
|
|
|
filesToBeUploaded
|
|
|
|
.removeWhere((element) => element.fileType == FileType.video);
|
2020-11-12 16:32:10 +00:00
|
|
|
}
|
2021-01-02 08:02:29 +00:00
|
|
|
_logger.info(
|
|
|
|
filesToBeUploaded.length.toString() + " new files to be uploaded.");
|
2020-11-30 18:42:11 +00:00
|
|
|
|
|
|
|
final updatedFileIDs = await _db.getUploadedFileIDsToBeUpdated();
|
2021-01-02 08:02:29 +00:00
|
|
|
_logger.info(updatedFileIDs.length.toString() + " files updated.");
|
2020-11-30 18:42:11 +00:00
|
|
|
|
|
|
|
int uploadCounter = 0;
|
|
|
|
final totalUploads = filesToBeUploaded.length + updatedFileIDs.length;
|
|
|
|
|
2020-12-03 21:47:06 +00:00
|
|
|
if (totalUploads > 0) {
|
|
|
|
Bus.instance.fire(SyncStatusUpdate(SyncStatus.preparing_for_upload));
|
|
|
|
}
|
|
|
|
|
2021-01-02 08:02:29 +00:00
|
|
|
final futures = List<Future>();
|
2020-11-30 18:42:11 +00:00
|
|
|
for (final uploadedFileID in updatedFileIDs) {
|
|
|
|
final file = await _db.getUploadedFileInAnyCollection(uploadedFileID);
|
|
|
|
final future = _uploader.upload(file, file.collectionID).then((value) {
|
|
|
|
uploadCounter++;
|
|
|
|
Bus.instance
|
|
|
|
.fire(CollectionUpdatedEvent(collectionID: file.collectionID));
|
|
|
|
Bus.instance.fire(SyncStatusUpdate(SyncStatus.in_progress,
|
|
|
|
completed: uploadCounter, total: totalUploads));
|
|
|
|
});
|
|
|
|
futures.add(future);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (final file in filesToBeUploaded) {
|
2020-11-16 16:35:16 +00:00
|
|
|
final collectionID = (await CollectionsService.instance
|
|
|
|
.getOrCreateForPath(file.deviceFolder))
|
|
|
|
.id;
|
|
|
|
final future = _uploader.upload(file, collectionID).then((value) {
|
2020-11-30 18:42:11 +00:00
|
|
|
uploadCounter++;
|
2020-11-16 16:35:16 +00:00
|
|
|
Bus.instance
|
|
|
|
.fire(CollectionUpdatedEvent(collectionID: file.collectionID));
|
|
|
|
Bus.instance.fire(SyncStatusUpdate(SyncStatus.in_progress,
|
2020-11-30 18:42:11 +00:00
|
|
|
completed: uploadCounter, total: totalUploads));
|
2020-11-16 16:35:16 +00:00
|
|
|
});
|
|
|
|
futures.add(future);
|
2020-03-26 14:39:31 +00:00
|
|
|
}
|
2020-11-09 18:06:27 +00:00
|
|
|
try {
|
2021-02-02 18:03:51 +00:00
|
|
|
await Future.wait(futures);
|
2020-11-16 16:35:16 +00:00
|
|
|
} on InvalidFileError {
|
|
|
|
// Do nothing
|
2020-11-09 18:06:27 +00:00
|
|
|
} catch (e, s) {
|
|
|
|
_logger.severe("Error in syncing files", e, s);
|
2021-02-02 16:57:16 +00:00
|
|
|
throw e;
|
2020-11-09 18:06:27 +00:00
|
|
|
}
|
2020-12-03 22:19:25 +00:00
|
|
|
return uploadCounter > 0;
|
2020-03-26 14:39:31 +00:00
|
|
|
}
|
|
|
|
|
2020-10-28 15:45:05 +00:00
|
|
|
Future _storeDiff(List<File> diff, int collectionID) async {
|
2020-06-19 23:03:26 +00:00
|
|
|
for (File file in diff) {
|
2021-01-02 09:04:36 +00:00
|
|
|
final existingFiles = await _db.getMatchingFiles(
|
|
|
|
file.title, file.deviceFolder, file.creationTime);
|
2020-10-29 00:14:48 +00:00
|
|
|
if (existingFiles == null) {
|
|
|
|
// File uploaded from a different device
|
|
|
|
file.localID = null;
|
|
|
|
await _db.insert(file);
|
|
|
|
} else {
|
|
|
|
// File exists on device
|
|
|
|
file.localID = existingFiles[0]
|
|
|
|
.localID; // File should ideally have the same localID
|
2020-11-14 10:11:12 +00:00
|
|
|
bool wasUploadedOnAPreviousInstallation =
|
|
|
|
existingFiles.length == 1 && existingFiles[0].collectionID == null;
|
2020-10-29 00:14:48 +00:00
|
|
|
if (wasUploadedOnAPreviousInstallation) {
|
|
|
|
file.generatedID = existingFiles[0].generatedID;
|
2021-01-02 09:04:36 +00:00
|
|
|
if (file.modificationTime != existingFiles[0].modificationTime) {
|
|
|
|
// File was updated since the app was uninstalled
|
|
|
|
_logger.info("Updated since last installation: " +
|
|
|
|
file.uploadedFileID.toString());
|
|
|
|
file.updationTime = null;
|
|
|
|
}
|
2020-10-24 23:39:46 +00:00
|
|
|
await _db.update(file);
|
|
|
|
} else {
|
2020-11-14 10:47:28 +00:00
|
|
|
bool foundMatchingCollection = false;
|
2020-10-29 00:14:48 +00:00
|
|
|
for (final existingFile in existingFiles) {
|
2020-11-14 10:47:28 +00:00
|
|
|
if (file.collectionID == existingFile.collectionID &&
|
|
|
|
file.uploadedFileID == existingFile.uploadedFileID) {
|
|
|
|
foundMatchingCollection = true;
|
2020-10-29 00:14:48 +00:00
|
|
|
file.generatedID = existingFile.generatedID;
|
2020-11-14 10:47:28 +00:00
|
|
|
await _db.update(file);
|
2020-12-01 09:07:48 +00:00
|
|
|
if (file.fileType == FileType.video) {
|
|
|
|
VideoCacheManager().removeFile(file.getDownloadUrl());
|
|
|
|
} else {
|
|
|
|
DefaultCacheManager().removeFile(file.getDownloadUrl());
|
|
|
|
}
|
|
|
|
ThumbnailCacheManager().removeFile(file.getDownloadUrl());
|
2020-10-29 00:14:48 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2020-11-14 10:47:28 +00:00
|
|
|
if (!foundMatchingCollection) {
|
2020-10-29 00:14:48 +00:00
|
|
|
// Added to a new collection
|
|
|
|
await _db.insert(file);
|
|
|
|
}
|
2020-10-24 23:39:46 +00:00
|
|
|
}
|
2020-05-17 18:42:03 +00:00
|
|
|
}
|
2020-12-03 21:01:24 +00:00
|
|
|
await _collectionsService.setCollectionSyncTime(
|
|
|
|
collectionID, file.updationTime);
|
2020-03-28 13:56:06 +00:00
|
|
|
}
|
|
|
|
}
|
2020-03-26 14:39:31 +00:00
|
|
|
|
2020-11-01 06:45:10 +00:00
|
|
|
Future<void> deleteFilesOnServer() async {
|
2020-10-30 23:25:28 +00:00
|
|
|
return _db.getDeletedFileIDs().then((ids) async {
|
|
|
|
for (int id in ids) {
|
|
|
|
await _deleteFileOnServer(id);
|
|
|
|
await _db.delete(id);
|
2020-04-12 12:38:49 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-10-30 23:25:28 +00:00
|
|
|
Future<void> _deleteFileOnServer(int fileID) async {
|
2020-05-17 10:18:09 +00:00
|
|
|
return _dio
|
|
|
|
.delete(
|
|
|
|
Configuration.instance.getHttpEndpoint() +
|
|
|
|
"/files/" +
|
2020-10-30 23:25:28 +00:00
|
|
|
fileID.toString(),
|
2020-05-17 10:18:09 +00:00
|
|
|
options: Options(
|
|
|
|
headers: {"X-Auth-Token": Configuration.instance.getToken()}),
|
|
|
|
)
|
|
|
|
.catchError((e) => _logger.severe(e));
|
2020-03-29 14:04:26 +00:00
|
|
|
}
|
2020-03-24 19:59:36 +00:00
|
|
|
}
|