ente/lib/photo_sync_manager.dart

109 lines
3.6 KiB
Dart
Raw Normal View History

2020-03-24 19:59:36 +00:00
import 'package:logger/logger.dart';
2020-03-26 14:39:31 +00:00
import 'package:myapp/db/db_helper.dart';
2020-03-27 19:54:24 +00:00
import 'package:myapp/photo_loader.dart';
2020-03-26 14:39:31 +00:00
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
2020-03-24 19:59:36 +00:00
import 'package:photo_manager/photo_manager.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:dio/dio.dart';
2020-03-27 16:07:55 +00:00
import 'package:myapp/models/photo.dart';
2020-03-26 14:39:31 +00:00
2020-03-24 19:59:36 +00:00
class PhotoSyncManager {
final logger = Logger();
final dio = Dio();
2020-03-27 19:54:24 +00:00
final endpoint = "http://172.20.10.6:8080";
2020-03-26 14:39:31 +00:00
final user = "umbu";
static final lastSyncTimestampKey = "last_sync_timestamp_0";
2020-03-24 19:59:36 +00:00
PhotoSyncManager(List<AssetEntity> assets) {
logger.i("PhotoSyncManager init");
_syncPhotos(assets);
}
_syncPhotos(List<AssetEntity> assets) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
2020-03-26 14:39:31 +00:00
var lastSyncTimestamp = prefs.getInt(lastSyncTimestampKey);
2020-03-24 19:59:36 +00:00
if (lastSyncTimestamp == null) {
lastSyncTimestamp = 0;
}
logger.i("Last sync timestamp: " + lastSyncTimestamp.toString());
2020-03-26 14:39:31 +00:00
await _downloadDiff(lastSyncTimestamp, prefs);
await _uploadDiff(assets, prefs);
// TODO: Fix race conditions triggered due to concurrent syncs.
// Add device_id/last_sync_timestamp to the upload request?
}
Future _uploadDiff(List<AssetEntity> assets, SharedPreferences prefs) async {
assets.sort((first, second) => second
.modifiedDateTime.millisecondsSinceEpoch
.compareTo(first.modifiedDateTime.millisecondsSinceEpoch));
2020-03-27 19:54:24 +00:00
var uploadedAssetCount = 0;
2020-03-24 19:59:36 +00:00
for (AssetEntity asset in assets) {
2020-03-27 19:54:24 +00:00
// TODO: Fix me
if (uploadedAssetCount == 100) {
return;
}
var containsPath = await DatabaseHelper.instance
.containsPath((await asset.originFile).path);
if (!containsPath) {
var response = await _uploadFile(asset);
prefs.setInt(lastSyncTimestampKey, response.syncTimestamp);
uploadedAssetCount++;
}
2020-03-26 14:39:31 +00:00
}
}
Future _downloadDiff(int lastSyncTimestamp, SharedPreferences prefs) async {
Response response = await dio.get(endpoint + "/diff", queryParameters: {
"user": user,
"lastSyncTimestamp": lastSyncTimestamp
});
2020-03-27 19:54:24 +00:00
logger.i(response.toString());
var externalPath = (await getApplicationDocumentsDirectory()).path;
2020-03-26 14:39:31 +00:00
logger.i("External path: " + externalPath);
var path = externalPath + "/photos/";
2020-03-27 16:07:55 +00:00
List<Photo> photos = (response.data["diff"] as List)
.map((photo) => new Photo.fromJson(photo))
2020-03-26 14:39:31 +00:00
.toList();
2020-03-27 16:07:55 +00:00
for (Photo photo in photos) {
2020-03-26 14:39:31 +00:00
await dio.download(endpoint + photo.url, path + basename(photo.url));
2020-03-27 16:07:55 +00:00
photo.hash = _getHash(photo);
photo.localPath = path + basename(photo.url);
2020-03-27 19:54:24 +00:00
insertPhotoToDB(photo);
2020-03-26 14:39:31 +00:00
prefs.setInt(lastSyncTimestampKey, photo.syncTimestamp);
logger.i("Downloaded " + photo.url + " to " + path);
2020-03-24 19:59:36 +00:00
}
}
2020-03-27 16:07:55 +00:00
Future<Photo> _uploadFile(AssetEntity entity) async {
2020-03-24 19:59:36 +00:00
logger.i("Uploading: " + entity.id);
2020-03-26 14:39:31 +00:00
var path = (await entity.originFile).path;
2020-03-24 19:59:36 +00:00
var formData = FormData.fromMap({
2020-03-26 14:39:31 +00:00
"file": await MultipartFile.fromFile(path, filename: entity.title),
"user": user,
2020-03-24 19:59:36 +00:00
});
2020-03-26 14:39:31 +00:00
var response = await dio.post(endpoint + "/upload", data: formData);
2020-03-24 19:59:36 +00:00
logger.i(response.toString());
2020-03-27 16:07:55 +00:00
var photo = Photo.fromJson(response.data);
photo.hash = _getHash(photo);
photo.localPath = path;
2020-03-27 19:54:24 +00:00
insertPhotoToDB(photo);
2020-03-27 16:07:55 +00:00
return photo;
}
String _getHash(Photo photo) {
2020-03-26 14:39:31 +00:00
// TODO: Compute hash
2020-03-27 16:07:55 +00:00
return "hash";
2020-03-24 19:59:36 +00:00
}
2020-03-27 19:54:24 +00:00
Future<void> insertPhotoToDB(Photo photo) async {
logger.i("Inserting to DB");
await DatabaseHelper.instance.insertPhoto(photo);
PhotoLoader.instance.reloadPhotos();
}
2020-03-24 19:59:36 +00:00
}