2021-04-10 06:28:12 +02:00
|
|
|
import 'package:event_bus/event_bus.dart';
|
|
|
|
import 'package:kiwi/kiwi.dart';
|
|
|
|
import 'package:logging/logging.dart';
|
|
|
|
import 'package:nc_photos/account.dart';
|
2021-12-02 11:47:37 +01:00
|
|
|
import 'package:nc_photos/debug_util.dart';
|
2021-12-03 18:31:27 +01:00
|
|
|
import 'package:nc_photos/di_container.dart';
|
2021-04-10 06:28:12 +02:00
|
|
|
import 'package:nc_photos/entity/album.dart';
|
2021-07-05 09:54:01 +02:00
|
|
|
import 'package:nc_photos/entity/album/item.dart';
|
2021-06-24 18:26:56 +02:00
|
|
|
import 'package:nc_photos/entity/album/provider.dart';
|
2022-10-15 16:29:18 +02:00
|
|
|
import 'package:nc_photos/entity/file_descriptor.dart';
|
2021-04-10 06:28:12 +02:00
|
|
|
import 'package:nc_photos/event/event.dart';
|
2022-05-03 19:37:10 +02:00
|
|
|
import 'package:nc_photos/stream_extension.dart';
|
2023-04-13 17:32:31 +02:00
|
|
|
import 'package:nc_photos/use_case/album/list_album.dart';
|
|
|
|
import 'package:nc_photos/use_case/album/remove_from_album.dart';
|
2021-12-02 11:47:37 +01:00
|
|
|
import 'package:nc_photos/use_case/list_share.dart';
|
|
|
|
import 'package:nc_photos/use_case/remove_share.dart';
|
2022-12-16 16:01:04 +01:00
|
|
|
import 'package:np_codegen/np_codegen.dart';
|
2023-08-25 19:31:06 +02:00
|
|
|
import 'package:np_collection/np_collection.dart';
|
2023-04-13 17:32:31 +02:00
|
|
|
import 'package:np_common/type.dart';
|
2023-08-25 18:37:17 +02:00
|
|
|
import 'package:np_string/np_string.dart';
|
2021-04-10 06:28:12 +02:00
|
|
|
|
2022-12-16 16:01:04 +01:00
|
|
|
part 'remove.g.dart';
|
|
|
|
|
|
|
|
@npLog
|
2021-04-10 06:28:12 +02:00
|
|
|
class Remove {
|
2024-01-12 19:37:13 +01:00
|
|
|
const Remove(this._c);
|
2021-04-10 06:28:12 +02:00
|
|
|
|
2023-04-13 17:32:31 +02:00
|
|
|
/// Remove list of [files] and return the removed count
|
|
|
|
Future<int> call(
|
2021-12-02 11:47:37 +01:00
|
|
|
Account account,
|
2023-04-13 17:32:31 +02:00
|
|
|
List<FileDescriptor> files, {
|
|
|
|
ErrorWithValueIndexedHandler<FileDescriptor>? onError,
|
2021-12-03 18:31:27 +01:00
|
|
|
bool shouldCleanUp = true,
|
2021-12-02 11:47:37 +01:00
|
|
|
}) async {
|
|
|
|
// need to cleanup first, otherwise we can't unshare the files
|
2021-12-03 18:31:27 +01:00
|
|
|
if (!shouldCleanUp) {
|
|
|
|
_log.info("[call] Skip album cleanup");
|
2021-12-02 11:47:37 +01:00
|
|
|
} else {
|
|
|
|
await _cleanUpAlbums(account, files);
|
2021-05-23 22:02:03 +02:00
|
|
|
}
|
2023-04-13 17:32:31 +02:00
|
|
|
var count = 0;
|
|
|
|
for (final pair in files.withIndex()) {
|
|
|
|
final i = pair.item1;
|
|
|
|
final f = pair.item2;
|
2021-12-02 11:47:37 +01:00
|
|
|
try {
|
2024-01-12 19:37:13 +01:00
|
|
|
await _c.fileRepo2.remove(account, f);
|
2023-04-13 17:32:31 +02:00
|
|
|
++count;
|
2021-12-02 11:47:37 +01:00
|
|
|
KiwiContainer().resolve<EventBus>().fire(FileRemovedEvent(account, f));
|
|
|
|
} catch (e, stackTrace) {
|
2023-04-13 17:32:31 +02:00
|
|
|
_log.severe("[call] Failed while remove: ${logFilename(f.fdPath)}", e,
|
2021-12-02 11:47:37 +01:00
|
|
|
stackTrace);
|
2023-04-13 17:32:31 +02:00
|
|
|
onError?.call(i, f, e, stackTrace);
|
2021-12-02 11:47:37 +01:00
|
|
|
}
|
2021-07-31 21:33:31 +02:00
|
|
|
}
|
2023-04-13 17:32:31 +02:00
|
|
|
return count;
|
2021-07-31 21:33:31 +02:00
|
|
|
}
|
|
|
|
|
2024-02-06 18:01:45 +01:00
|
|
|
// TODO: move to CollectionsController
|
2023-04-13 17:32:31 +02:00
|
|
|
Future<void> _cleanUpAlbums(
|
|
|
|
Account account, List<FileDescriptor> removes) async {
|
2022-05-03 19:37:10 +02:00
|
|
|
final albums = await ListAlbum(_c)(account).whereType<Album>().toList();
|
2021-12-02 11:47:37 +01:00
|
|
|
// figure out which files need to be unshared with whom
|
2024-02-13 18:12:04 +01:00
|
|
|
final unshares = <FileDescriptorServerIdentityComparator, Set<CiString>>{};
|
2021-06-24 18:26:56 +02:00
|
|
|
// clean up only make sense for static albums
|
2021-12-02 11:47:37 +01:00
|
|
|
for (final a in albums.where((a) => a.provider is AlbumStaticProvider)) {
|
2021-04-10 06:28:12 +02:00
|
|
|
try {
|
2021-06-24 18:26:56 +02:00
|
|
|
final provider = AlbumStaticProvider.of(a);
|
2021-12-02 11:47:37 +01:00
|
|
|
final itemsToRemove = provider.items
|
|
|
|
.whereType<AlbumFileItem>()
|
|
|
|
.where((i) =>
|
2024-02-13 18:12:04 +01:00
|
|
|
(i.ownerId == account.userId || i.addedBy == account.userId) &&
|
2021-12-02 11:47:37 +01:00
|
|
|
removes.any((r) => r.compareServerIdentity(i.file)))
|
|
|
|
.toList();
|
|
|
|
if (itemsToRemove.isEmpty) {
|
|
|
|
continue;
|
2021-04-10 06:28:12 +02:00
|
|
|
}
|
2021-12-02 11:47:37 +01:00
|
|
|
for (final i in itemsToRemove) {
|
2024-02-13 18:12:04 +01:00
|
|
|
final key = FileDescriptorServerIdentityComparator(i.file);
|
2021-12-02 11:47:37 +01:00
|
|
|
final value = (a.shares?.map((s) => s.userId).toList() ?? [])
|
|
|
|
..add(a.albumFile!.ownerId!)
|
2022-07-11 20:14:42 +02:00
|
|
|
..remove(account.userId);
|
2021-12-02 11:47:37 +01:00
|
|
|
(unshares[key] ??= <CiString>{}).addAll(value);
|
|
|
|
}
|
|
|
|
_log.fine(
|
2024-02-13 18:12:04 +01:00
|
|
|
"[_cleanUpAlbums] Removing from album '${a.name}': ${itemsToRemove.map((e) => e.file.fdPath).toReadableString()}");
|
2021-12-02 11:47:37 +01:00
|
|
|
// skip unsharing as we'll handle it ourselves
|
2021-12-03 18:31:27 +01:00
|
|
|
await RemoveFromAlbum(_c)(account, a, itemsToRemove,
|
|
|
|
shouldUnshare: false);
|
2021-04-10 06:28:12 +02:00
|
|
|
} catch (e, stacktrace) {
|
2021-04-27 22:06:16 +02:00
|
|
|
_log.shout(
|
2021-04-10 06:28:12 +02:00
|
|
|
"[_cleanUpAlbums] Failed while updating album", e, stacktrace);
|
|
|
|
// continue to next album
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-02 11:47:37 +01:00
|
|
|
for (final e in unshares.entries) {
|
|
|
|
try {
|
2021-12-03 18:32:38 +01:00
|
|
|
final shares = await ListShare(_c)(account, e.key.file);
|
2021-12-02 11:47:37 +01:00
|
|
|
for (final s in shares.where((s) => e.value.contains(s.shareWith))) {
|
|
|
|
try {
|
2021-12-03 18:31:27 +01:00
|
|
|
await RemoveShare(_c.shareRepo)(account, s);
|
2021-12-02 11:47:37 +01:00
|
|
|
} catch (e, stackTrace) {
|
|
|
|
_log.severe(
|
|
|
|
"[_cleanUpAlbums] Failed while RemoveShare: $s", e, stackTrace);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (e, stackTrace) {
|
|
|
|
_log.shout("[_cleanUpAlbums] Failed", e, stackTrace);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-04-10 06:28:12 +02:00
|
|
|
|
2021-12-03 18:31:27 +01:00
|
|
|
final DiContainer _c;
|
2021-04-10 06:28:12 +02:00
|
|
|
}
|