mirror of
https://gitlab.com/nkming2/nc-photos.git
synced 2025-02-02 06:46:22 +01:00
139 lines
4.2 KiB
Dart
139 lines
4.2 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:logging/logging.dart';
|
|
import 'package:nc_photos/account.dart';
|
|
import 'package:nc_photos/controller/account_pref_controller.dart';
|
|
import 'package:nc_photos/controller/server_controller.dart';
|
|
import 'package:nc_photos/db/entity_converter.dart';
|
|
import 'package:nc_photos/entity/exif_util.dart';
|
|
import 'package:nc_photos/entity/file.dart';
|
|
import 'package:nc_photos/entity/file/file_cache_manager.dart';
|
|
import 'package:nc_photos/entity/file/repo.dart';
|
|
import 'package:nc_photos/entity/file_util.dart' as file_util;
|
|
import 'package:nc_photos/geocoder_util.dart';
|
|
import 'package:nc_photos/service/service.dart';
|
|
import 'package:nc_photos/use_case/battery_ensurer.dart';
|
|
import 'package:nc_photos/use_case/get_file_binary.dart';
|
|
import 'package:nc_photos/use_case/load_metadata.dart';
|
|
import 'package:nc_photos/use_case/update_property.dart';
|
|
import 'package:nc_photos/use_case/wifi_ensurer.dart';
|
|
import 'package:np_codegen/np_codegen.dart';
|
|
import 'package:np_collection/np_collection.dart';
|
|
import 'package:np_common/or_null.dart';
|
|
import 'package:np_db/np_db.dart';
|
|
import 'package:np_geocoder/np_geocoder.dart';
|
|
import 'package:path/path.dart';
|
|
|
|
part 'sync_by_app.dart';
|
|
part 'sync_by_server.dart';
|
|
part 'sync_metadata.g.dart';
|
|
|
|
@npLog
|
|
class SyncMetadata {
|
|
const SyncMetadata({
|
|
required this.fileRepo,
|
|
required this.fileRepo2,
|
|
required this.fileRepoRemote,
|
|
required this.db,
|
|
this.interrupter,
|
|
required this.wifiEnsurer,
|
|
required this.batteryEnsurer,
|
|
});
|
|
|
|
Stream<File> syncAccount(
|
|
Account account,
|
|
AccountPrefController accountPrefController,
|
|
) async* {
|
|
final bool isNcMetadataSupported;
|
|
try {
|
|
isNcMetadataSupported =
|
|
(await _isNcMetadataSupported(account, accountPrefController))!;
|
|
} catch (e) {
|
|
_log.severe("[syncAccount] Failed to get server version", e);
|
|
return;
|
|
}
|
|
final files = await db.getFilesByMissingMetadata(
|
|
account: account.toDb(),
|
|
mimes: file_util.supportedImageFormatMimes,
|
|
ownerId: account.userId.toCaseInsensitiveString(),
|
|
);
|
|
_log.info("[syncAccount] Missing count: ${files.items.length}");
|
|
if (isNcMetadataSupported) {
|
|
yield* _doWithServer(account, files);
|
|
} else {
|
|
yield* _doWithApp(account, files);
|
|
}
|
|
}
|
|
|
|
Stream<File> _doWithApp(
|
|
Account account, DbFileMissingMetadataResult files) async* {
|
|
final op = _SyncByApp(
|
|
account: account,
|
|
fileRepo: fileRepo,
|
|
fileRepo2: fileRepo2,
|
|
db: db,
|
|
interrupter: interrupter,
|
|
wifiEnsurer: wifiEnsurer,
|
|
batteryEnsurer: batteryEnsurer,
|
|
);
|
|
await op.init();
|
|
final stream = op.syncFiles(
|
|
fileIds: files.items.map((e) => e.fileId).toList(),
|
|
);
|
|
yield* stream;
|
|
}
|
|
|
|
Stream<File> _doWithServer(
|
|
Account account, DbFileMissingMetadataResult files) async* {
|
|
final fallback = _SyncByApp(
|
|
account: account,
|
|
fileRepo: fileRepo,
|
|
fileRepo2: fileRepo2,
|
|
db: db,
|
|
interrupter: interrupter,
|
|
wifiEnsurer: wifiEnsurer,
|
|
batteryEnsurer: batteryEnsurer,
|
|
);
|
|
await fallback.init();
|
|
final op = _SyncByServer(
|
|
account: account,
|
|
fileRepoRemote: fileRepoRemote,
|
|
fileRepo2: fileRepo2,
|
|
db: db,
|
|
interrupter: interrupter,
|
|
fallback: fallback,
|
|
);
|
|
await op.init();
|
|
final fileIds = <int>[];
|
|
final relativePaths = <String>[];
|
|
for (final f in files.items) {
|
|
fileIds.add(f.fileId);
|
|
relativePaths.add(f.relativePath);
|
|
}
|
|
final stream = op.syncFiles(
|
|
fileIds: fileIds,
|
|
relativePaths: relativePaths,
|
|
);
|
|
yield* stream;
|
|
}
|
|
|
|
Future<bool?> _isNcMetadataSupported(
|
|
Account account,
|
|
AccountPrefController accountPrefController,
|
|
) async {
|
|
final serverController = ServerController(
|
|
account: account,
|
|
accountPrefController: accountPrefController,
|
|
);
|
|
await serverController.status.first.timeout(const Duration(seconds: 15));
|
|
return serverController.isSupported(ServerFeature.ncMetadata);
|
|
}
|
|
|
|
final FileRepo fileRepo;
|
|
final FileRepo2 fileRepo2;
|
|
final FileRepo fileRepoRemote;
|
|
final NpDb db;
|
|
final Stream<void>? interrupter;
|
|
final WifiEnsurer wifiEnsurer;
|
|
final BatteryEnsurer batteryEnsurer;
|
|
}
|