|
@@ -68,17 +68,19 @@ class FileUploader {
|
|
|
Future<void> init(bool isBackground) async {
|
|
|
_prefs = await SharedPreferences.getInstance();
|
|
|
_isBackground = isBackground;
|
|
|
- _processType = isBackground ? ProcessType.background : ProcessType.foreground;
|
|
|
+ _processType =
|
|
|
+ isBackground ? ProcessType.background : ProcessType.foreground;
|
|
|
final currentTime = DateTime.now().microsecondsSinceEpoch;
|
|
|
await _uploadLocks.releaseLocksAcquiredByOwnerBefore(
|
|
|
_processType.toString(),
|
|
|
currentTime,
|
|
|
);
|
|
|
- await _uploadLocks.releaseAllLocksAcquiredBefore(currentTime - kSafeBufferForLockExpiry);
|
|
|
+ await _uploadLocks
|
|
|
+ .releaseAllLocksAcquiredBefore(currentTime - kSafeBufferForLockExpiry);
|
|
|
if (!isBackground) {
|
|
|
await _prefs.reload();
|
|
|
- final isBGTaskDead =
|
|
|
- (_prefs.getInt(kLastBGTaskHeartBeatTime) ?? 0) < (currentTime - kBGTaskDeathTimeout);
|
|
|
+ final isBGTaskDead = (_prefs.getInt(kLastBGTaskHeartBeatTime) ?? 0) <
|
|
|
+ (currentTime - kBGTaskDeathTimeout);
|
|
|
if (isBGTaskDead) {
|
|
|
await _uploadLocks.releaseLocksAcquiredByOwnerBefore(
|
|
|
ProcessType.background.toString(),
|
|
@@ -136,7 +138,10 @@ class FileUploader {
|
|
|
|
|
|
Future<File> forceUpload(File file, int collectionID) async {
|
|
|
_logger.info(
|
|
|
- "Force uploading " + file.toString() + " into collection " + collectionID.toString(),
|
|
|
+ "Force uploading " +
|
|
|
+ file.toString() +
|
|
|
+ " into collection " +
|
|
|
+ collectionID.toString(),
|
|
|
);
|
|
|
_totalCountInUploadSession++;
|
|
|
// If the file hasn't been queued yet, ez.
|
|
@@ -153,13 +158,15 @@ class FileUploader {
|
|
|
}
|
|
|
var item = _queue[file.localID];
|
|
|
// If the file is being uploaded right now, wait and proceed
|
|
|
- if (item.status == UploadStatus.inProgress || item.status == UploadStatus.inBackground) {
|
|
|
+ if (item.status == UploadStatus.inProgress ||
|
|
|
+ item.status == UploadStatus.inBackground) {
|
|
|
_totalCountInUploadSession--;
|
|
|
final uploadedFile = await item.completer.future;
|
|
|
if (uploadedFile.collectionID == collectionID) {
|
|
|
// Do nothing
|
|
|
} else {
|
|
|
- await CollectionsService.instance.addToCollection(collectionID, [uploadedFile]);
|
|
|
+ await CollectionsService.instance
|
|
|
+ .addToCollection(collectionID, [uploadedFile]);
|
|
|
}
|
|
|
return uploadedFile;
|
|
|
} else {
|
|
@@ -177,7 +184,8 @@ class FileUploader {
|
|
|
if (item.collectionID == collectionID) {
|
|
|
return uploadedFile;
|
|
|
} else {
|
|
|
- await CollectionsService.instance.addToCollection(item.collectionID, [uploadedFile]);
|
|
|
+ await CollectionsService.instance
|
|
|
+ .addToCollection(item.collectionID, [uploadedFile]);
|
|
|
return uploadedFile;
|
|
|
}
|
|
|
}
|
|
@@ -266,7 +274,8 @@ class FileUploader {
|
|
|
}
|
|
|
final localID = file.localID;
|
|
|
try {
|
|
|
- final uploadedFile = await _tryToUpload(file, collectionID, forcedUpload).timeout(
|
|
|
+ final uploadedFile =
|
|
|
+ await _tryToUpload(file, collectionID, forcedUpload).timeout(
|
|
|
kFileUploadTimeout,
|
|
|
onTimeout: () {
|
|
|
final message = "Upload timed out for file " + file.toString();
|
|
@@ -299,8 +308,9 @@ class FileUploader {
|
|
|
bool forcedUpload,
|
|
|
) async {
|
|
|
final connectivityResult = await (Connectivity().checkConnectivity());
|
|
|
- var canUploadUnderCurrentNetworkConditions = (connectivityResult == ConnectivityResult.wifi ||
|
|
|
- Configuration.instance.shouldBackupOverMobileData());
|
|
|
+ var canUploadUnderCurrentNetworkConditions =
|
|
|
+ (connectivityResult == ConnectivityResult.wifi ||
|
|
|
+ Configuration.instance.shouldBackupOverMobileData());
|
|
|
if (!canUploadUnderCurrentNetworkConditions && !forcedUpload) {
|
|
|
throw WiFiUnavailableError();
|
|
|
}
|
|
@@ -324,8 +334,10 @@ class FileUploader {
|
|
|
}
|
|
|
|
|
|
final tempDirectory = Configuration.instance.getTempDirectory();
|
|
|
- final encryptedFilePath =
|
|
|
- tempDirectory + file.generatedID.toString() + (_isBackground ? "_bg" : "") + ".encrypted";
|
|
|
+ final encryptedFilePath = tempDirectory +
|
|
|
+ file.generatedID.toString() +
|
|
|
+ (_isBackground ? "_bg" : "") +
|
|
|
+ ".encrypted";
|
|
|
final encryptedThumbnailPath = tempDirectory +
|
|
|
file.generatedID.toString() +
|
|
|
"_thumbnail" +
|
|
@@ -335,7 +347,10 @@ class FileUploader {
|
|
|
|
|
|
try {
|
|
|
_logger.info(
|
|
|
- "Trying to upload " + file.toString() + ", isForced: " + forcedUpload.toString(),
|
|
|
+ "Trying to upload " +
|
|
|
+ file.toString() +
|
|
|
+ ", isForced: " +
|
|
|
+ forcedUpload.toString(),
|
|
|
);
|
|
|
try {
|
|
|
mediaUploadData = await getUploadDataFromEnteFile(file);
|
|
@@ -347,7 +362,8 @@ class FileUploader {
|
|
|
}
|
|
|
}
|
|
|
Uint8List key;
|
|
|
- bool isUpdatedFile = file.uploadedFileID != null && file.updationTime == -1;
|
|
|
+ bool isUpdatedFile =
|
|
|
+ file.uploadedFileID != null && file.updationTime == -1;
|
|
|
if (isUpdatedFile) {
|
|
|
_logger.info("File was updated " + file.toString());
|
|
|
key = decryptFileKey(file);
|
|
@@ -372,23 +388,29 @@ class FileUploader {
|
|
|
await io.File(encryptedThumbnailPath).delete();
|
|
|
}
|
|
|
final encryptedThumbnailFile = io.File(encryptedThumbnailPath);
|
|
|
- await encryptedThumbnailFile.writeAsBytes(encryptedThumbnailData.encryptedData);
|
|
|
+ await encryptedThumbnailFile
|
|
|
+ .writeAsBytes(encryptedThumbnailData.encryptedData);
|
|
|
|
|
|
final thumbnailUploadURL = await _getUploadURL();
|
|
|
- String thumbnailObjectKey = await _putFile(thumbnailUploadURL, encryptedThumbnailFile);
|
|
|
+ String thumbnailObjectKey =
|
|
|
+ await _putFile(thumbnailUploadURL, encryptedThumbnailFile);
|
|
|
|
|
|
final fileUploadURL = await _getUploadURL();
|
|
|
String fileObjectKey = await _putFile(fileUploadURL, encryptedFile);
|
|
|
|
|
|
- final metadata = await file.getMetadataForUpload(mediaUploadData.sourceFile);
|
|
|
+ final metadata =
|
|
|
+ await file.getMetadataForUpload(mediaUploadData.sourceFile);
|
|
|
final encryptedMetadataData = await CryptoUtil.encryptChaCha(
|
|
|
utf8.encode(jsonEncode(metadata)),
|
|
|
fileAttributes.key,
|
|
|
);
|
|
|
final fileDecryptionHeader = Sodium.bin2base64(fileAttributes.header);
|
|
|
- final thumbnailDecryptionHeader = Sodium.bin2base64(encryptedThumbnailData.header);
|
|
|
- final encryptedMetadata = Sodium.bin2base64(encryptedMetadataData.encryptedData);
|
|
|
- final metadataDecryptionHeader = Sodium.bin2base64(encryptedMetadataData.header);
|
|
|
+ final thumbnailDecryptionHeader =
|
|
|
+ Sodium.bin2base64(encryptedThumbnailData.header);
|
|
|
+ final encryptedMetadata =
|
|
|
+ Sodium.bin2base64(encryptedMetadataData.encryptedData);
|
|
|
+ final metadataDecryptionHeader =
|
|
|
+ Sodium.bin2base64(encryptedMetadataData.header);
|
|
|
if (SyncService.instance.shouldStopSync()) {
|
|
|
throw SyncStopRequestedError();
|
|
|
}
|
|
@@ -412,8 +434,10 @@ class FileUploader {
|
|
|
fileAttributes.key,
|
|
|
CollectionsService.instance.getCollectionKey(collectionID),
|
|
|
);
|
|
|
- final encryptedKey = Sodium.bin2base64(encryptedFileKeyData.encryptedData);
|
|
|
- final keyDecryptionNonce = Sodium.bin2base64(encryptedFileKeyData.nonce);
|
|
|
+ final encryptedKey =
|
|
|
+ Sodium.bin2base64(encryptedFileKeyData.encryptedData);
|
|
|
+ final keyDecryptionNonce =
|
|
|
+ Sodium.bin2base64(encryptedFileKeyData.nonce);
|
|
|
remoteFile = await _uploadFile(
|
|
|
file,
|
|
|
collectionID,
|
|
@@ -450,7 +474,9 @@ class FileUploader {
|
|
|
}
|
|
|
rethrow;
|
|
|
} finally {
|
|
|
- if (io.Platform.isIOS && mediaUploadData != null && mediaUploadData.sourceFile != null) {
|
|
|
+ if (io.Platform.isIOS &&
|
|
|
+ mediaUploadData != null &&
|
|
|
+ mediaUploadData.sourceFile != null) {
|
|
|
await mediaUploadData.sourceFile.delete();
|
|
|
}
|
|
|
if (io.File(encryptedFilePath).existsSync()) {
|
|
@@ -654,7 +680,9 @@ class FileUploader {
|
|
|
headers: {"X-Auth-Token": Configuration.instance.getToken()},
|
|
|
),
|
|
|
);
|
|
|
- final urls = (response.data["urls"] as List).map((e) => UploadURL.fromMap(e)).toList();
|
|
|
+ final urls = (response.data["urls"] as List)
|
|
|
+ .map((e) => UploadURL.fromMap(e))
|
|
|
+ .toList();
|
|
|
_uploadURLs.addAll(urls);
|
|
|
} on DioError catch (e, s) {
|
|
|
if (e.response != null) {
|
|
@@ -691,7 +719,10 @@ class FileUploader {
|
|
|
}) async {
|
|
|
final fileSize = contentLength ?? await file.length();
|
|
|
_logger.info(
|
|
|
- "Putting object for " + file.toString() + " of size: " + fileSize.toString(),
|
|
|
+ "Putting object for " +
|
|
|
+ file.toString() +
|
|
|
+ " of size: " +
|
|
|
+ fileSize.toString(),
|
|
|
);
|
|
|
final startTime = DateTime.now().millisecondsSinceEpoch;
|
|
|
try {
|
|
@@ -706,7 +737,8 @@ class FileUploader {
|
|
|
);
|
|
|
_logger.info(
|
|
|
"Upload speed : " +
|
|
|
- (fileSize / (DateTime.now().millisecondsSinceEpoch - startTime)).toString() +
|
|
|
+ (fileSize / (DateTime.now().millisecondsSinceEpoch - startTime))
|
|
|
+ .toString() +
|
|
|
" kilo bytes per second",
|
|
|
);
|
|
|
|
|
@@ -741,8 +773,9 @@ class FileUploader {
|
|
|
}
|
|
|
|
|
|
Future<void> _pollBackgroundUploadStatus() async {
|
|
|
- final blockedUploads =
|
|
|
- _queue.entries.where((e) => e.value.status == UploadStatus.inBackground).toList();
|
|
|
+ final blockedUploads = _queue.entries
|
|
|
+ .where((e) => e.value.status == UploadStatus.inBackground)
|
|
|
+ .toList();
|
|
|
for (final upload in blockedUploads) {
|
|
|
final file = upload.value.file;
|
|
|
final isStillLocked = await _uploadLocks.isLocked(
|
|
@@ -751,7 +784,8 @@ class FileUploader {
|
|
|
);
|
|
|
if (!isStillLocked) {
|
|
|
final completer = _queue.remove(upload.key).completer;
|
|
|
- final dbFile = await FilesDB.instance.getFile(upload.value.file.generatedID);
|
|
|
+ final dbFile =
|
|
|
+ await FilesDB.instance.getFile(upload.value.file.generatedID);
|
|
|
if (dbFile.uploadedFileID != null) {
|
|
|
_logger.info("Background upload success detected");
|
|
|
completer.complete(dbFile);
|