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';
|
|
|
|
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-26 14:39:31 +00:00
|
|
|
final endpoint = "http://192.168.0.106:8080";
|
|
|
|
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-24 19:59:36 +00:00
|
|
|
for (AssetEntity asset in assets) {
|
2020-03-26 14:39:31 +00:00
|
|
|
DatabaseHelper.instance
|
|
|
|
.containsPath((await asset.originFile).path)
|
|
|
|
.then((containsPath) async {
|
|
|
|
if (!containsPath) {
|
|
|
|
var response = await _uploadFile(asset);
|
|
|
|
prefs.setInt(lastSyncTimestampKey, response.syncTimestamp);
|
2020-03-24 19:59:36 +00:00
|
|
|
}
|
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
|
|
|
|
});
|
|
|
|
var externalPath = (await getExternalStorageDirectory()).path;
|
|
|
|
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);
|
|
|
|
DatabaseHelper.instance.insertPhoto(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;
|
|
|
|
DatabaseHelper.instance.insertPhoto(photo);
|
|
|
|
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
|
|
|
}
|
|
|
|
}
|