2021-08-07 22:34:44 +02:00
|
|
|
import 'dart:convert';
|
|
|
|
|
|
|
|
import 'package:logging/logging.dart';
|
|
|
|
import 'package:nc_photos/account.dart';
|
2023-02-23 15:49:17 +01:00
|
|
|
import 'package:nc_photos/api/entity_converter.dart';
|
2021-08-07 22:34:44 +02:00
|
|
|
import 'package:nc_photos/entity/file.dart';
|
2022-10-15 16:29:18 +02:00
|
|
|
import 'package:nc_photos/entity/file_descriptor.dart';
|
2021-08-07 22:34:44 +02:00
|
|
|
import 'package:nc_photos/entity/share.dart';
|
|
|
|
import 'package:nc_photos/exception.dart';
|
2023-02-23 15:49:17 +01:00
|
|
|
import 'package:nc_photos/np_api_util.dart';
|
|
|
|
import 'package:np_api/np_api.dart' as api;
|
2022-12-16 16:01:04 +01:00
|
|
|
import 'package:np_codegen/np_codegen.dart';
|
2023-02-23 15:49:17 +01:00
|
|
|
import 'package:np_common/type.dart';
|
2023-08-25 18:37:17 +02:00
|
|
|
import 'package:np_string/np_string.dart';
|
2021-08-07 22:34:44 +02:00
|
|
|
|
2022-12-16 16:01:04 +01:00
|
|
|
part 'data_source.g.dart';
|
|
|
|
|
|
|
|
@npLog
|
2021-08-07 22:34:44 +02:00
|
|
|
class ShareRemoteDataSource implements ShareDataSource {
|
|
|
|
@override
|
2024-02-13 17:59:05 +01:00
|
|
|
Future<List<Share>> list(
|
2021-12-07 15:28:10 +01:00
|
|
|
Account account,
|
2024-02-13 17:59:05 +01:00
|
|
|
FileDescriptor file, {
|
2021-12-07 15:28:10 +01:00
|
|
|
bool? isIncludeReshare,
|
|
|
|
}) async {
|
2024-02-13 17:59:05 +01:00
|
|
|
_log.info("[list] ${file.fdPath}");
|
2023-02-23 15:49:17 +01:00
|
|
|
final response =
|
|
|
|
await ApiUtil.fromAccount(account).ocs().filesSharing().shares().get(
|
|
|
|
path: file.strippedPath,
|
|
|
|
reshares: isIncludeReshare,
|
|
|
|
);
|
2021-08-13 12:42:31 +02:00
|
|
|
return _onListResult(response);
|
|
|
|
}
|
2021-08-07 22:34:44 +02:00
|
|
|
|
2021-08-13 12:42:31 +02:00
|
|
|
@override
|
|
|
|
listDir(Account account, File dir) async {
|
|
|
|
_log.info("[listDir] ${dir.path}");
|
2023-02-23 15:49:17 +01:00
|
|
|
final response =
|
|
|
|
await ApiUtil.fromAccount(account).ocs().filesSharing().shares().get(
|
|
|
|
path: dir.strippedPath,
|
|
|
|
subfiles: true,
|
|
|
|
);
|
2021-08-13 12:42:31 +02:00
|
|
|
return _onListResult(response);
|
2021-08-07 22:34:44 +02:00
|
|
|
}
|
|
|
|
|
2021-10-06 22:32:36 +02:00
|
|
|
@override
|
|
|
|
listAll(Account account) async {
|
|
|
|
_log.info("[listAll] $account");
|
2023-02-23 15:49:17 +01:00
|
|
|
final response =
|
|
|
|
await ApiUtil.fromAccount(account).ocs().filesSharing().shares().get();
|
2021-10-06 22:32:36 +02:00
|
|
|
return _onListResult(response);
|
|
|
|
}
|
|
|
|
|
2021-11-22 09:42:34 +01:00
|
|
|
@override
|
|
|
|
reverseList(Account account, File file) async {
|
|
|
|
_log.info("[reverseList] ${file.path}");
|
2023-02-23 15:49:17 +01:00
|
|
|
final response =
|
|
|
|
await ApiUtil.fromAccount(account).ocs().filesSharing().shares().get(
|
|
|
|
path: file.strippedPath,
|
|
|
|
sharedWithMe: true,
|
|
|
|
);
|
2021-11-22 09:42:34 +01:00
|
|
|
return _onListResult(response);
|
|
|
|
}
|
|
|
|
|
2021-10-11 19:03:37 +02:00
|
|
|
@override
|
|
|
|
reverseListAll(Account account) async {
|
|
|
|
_log.info("[reverseListAll] $account");
|
2023-02-23 15:49:17 +01:00
|
|
|
final response =
|
|
|
|
await ApiUtil.fromAccount(account).ocs().filesSharing().shares().get(
|
|
|
|
sharedWithMe: true,
|
|
|
|
);
|
2021-10-11 19:03:37 +02:00
|
|
|
return _onListResult(response);
|
|
|
|
}
|
|
|
|
|
2021-08-07 22:34:44 +02:00
|
|
|
@override
|
2024-02-13 17:59:05 +01:00
|
|
|
Future<Share> create(
|
|
|
|
Account account, FileDescriptor file, String shareWith) async {
|
|
|
|
_log.info("[create] Share '${file.fdPath}' with '$shareWith'");
|
2023-02-23 15:49:17 +01:00
|
|
|
final response =
|
|
|
|
await ApiUtil.fromAccount(account).ocs().filesSharing().shares().post(
|
|
|
|
path: file.strippedPath,
|
|
|
|
shareType: ShareType.user.toValue(),
|
|
|
|
shareWith: shareWith,
|
|
|
|
);
|
2021-08-07 22:34:44 +02:00
|
|
|
if (!response.isGood) {
|
|
|
|
_log.severe("[create] Failed requesting server: $response");
|
|
|
|
throw ApiException(
|
2023-02-23 15:49:17 +01:00
|
|
|
response: response,
|
|
|
|
message: "Server responed with an error: HTTP ${response.statusCode}",
|
|
|
|
);
|
2021-08-07 22:34:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
final json = jsonDecode(response.body);
|
|
|
|
final JsonObj dataJson = json["ocs"]["data"];
|
|
|
|
return _ShareParser().parseSingle(dataJson);
|
|
|
|
}
|
|
|
|
|
2021-09-28 08:36:00 +02:00
|
|
|
@override
|
|
|
|
createLink(
|
|
|
|
Account account,
|
|
|
|
File file, {
|
|
|
|
String? password,
|
|
|
|
}) async {
|
|
|
|
_log.info("[createLink] Share '${file.path}' with a share link");
|
2023-02-23 15:49:17 +01:00
|
|
|
final response =
|
|
|
|
await ApiUtil.fromAccount(account).ocs().filesSharing().shares().post(
|
|
|
|
path: file.strippedPath,
|
|
|
|
shareType: ShareType.publicLink.toValue(),
|
|
|
|
password: password,
|
|
|
|
);
|
2021-09-28 08:36:00 +02:00
|
|
|
if (!response.isGood) {
|
|
|
|
_log.severe("[create] Failed requesting server: $response");
|
|
|
|
throw ApiException(
|
2023-02-23 15:49:17 +01:00
|
|
|
response: response,
|
|
|
|
message: "Server responed with an error: HTTP ${response.statusCode}",
|
|
|
|
);
|
2021-09-28 08:36:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
final json = jsonDecode(response.body);
|
|
|
|
final JsonObj dataJson = json["ocs"]["data"];
|
|
|
|
return _ShareParser().parseSingle(dataJson);
|
|
|
|
}
|
|
|
|
|
2021-08-07 22:34:44 +02:00
|
|
|
@override
|
|
|
|
delete(Account account, Share share) async {
|
|
|
|
_log.info("[delete] $share");
|
2023-02-23 15:49:17 +01:00
|
|
|
final response = await ApiUtil.fromAccount(account)
|
|
|
|
.ocs()
|
|
|
|
.filesSharing()
|
|
|
|
.share(share.id)
|
|
|
|
.delete();
|
2021-08-07 22:34:44 +02:00
|
|
|
if (!response.isGood) {
|
|
|
|
_log.severe("[delete] Failed requesting server: $response");
|
|
|
|
throw ApiException(
|
2023-02-23 15:49:17 +01:00
|
|
|
response: response,
|
|
|
|
message: "Server responed with an error: HTTP ${response.statusCode}",
|
|
|
|
);
|
2021-08-07 22:34:44 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-23 15:49:17 +01:00
|
|
|
Future<List<Share>> _onListResult(api.Response response) async {
|
2021-08-13 12:42:31 +02:00
|
|
|
if (!response.isGood) {
|
|
|
|
_log.severe("[_onListResult] Failed requesting server: $response");
|
|
|
|
throw ApiException(
|
2023-02-23 15:49:17 +01:00
|
|
|
response: response,
|
|
|
|
message: "Server responed with an error: HTTP ${response.statusCode}",
|
|
|
|
);
|
2021-08-13 12:42:31 +02:00
|
|
|
}
|
|
|
|
|
2023-02-23 15:49:17 +01:00
|
|
|
final apiShares = await api.ShareParser().parse(response.body);
|
|
|
|
return apiShares.map(ApiShareConverter.fromApi).toList();
|
2021-08-13 12:42:31 +02:00
|
|
|
}
|
2021-08-07 22:34:44 +02:00
|
|
|
}
|
|
|
|
|
2022-12-16 16:01:04 +01:00
|
|
|
@npLog
|
2021-08-07 22:34:44 +02:00
|
|
|
class _ShareParser {
|
|
|
|
List<Share> parseList(List<JsonObj> jsons) {
|
|
|
|
final product = <Share>[];
|
|
|
|
for (final j in jsons) {
|
|
|
|
try {
|
|
|
|
product.add(parseSingle(j));
|
|
|
|
} catch (e) {
|
|
|
|
_log.severe("[parseList] Failed parsing json: ${jsonEncode(j)}", e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return product;
|
|
|
|
}
|
|
|
|
|
|
|
|
Share parseSingle(JsonObj json) {
|
2021-09-28 07:20:22 +02:00
|
|
|
final shareType = ShareTypeExtension.fromValue(json["share_type"]);
|
2021-10-06 22:32:36 +02:00
|
|
|
final itemType = ShareItemTypeExtension.fromValue(json["item_type"]);
|
2021-08-07 22:34:44 +02:00
|
|
|
return Share(
|
|
|
|
id: json["id"],
|
2021-09-28 07:20:22 +02:00
|
|
|
shareType: shareType,
|
2021-10-11 19:03:37 +02:00
|
|
|
stime: DateTime.fromMillisecondsSinceEpoch(json["stime"] * 1000),
|
2021-11-12 22:13:02 +01:00
|
|
|
uidOwner: CiString(json["uid_owner"]),
|
2021-10-11 19:03:37 +02:00
|
|
|
displaynameOwner: json["displayname_owner"],
|
2021-12-07 15:28:10 +01:00
|
|
|
uidFileOwner: CiString(json["uid_file_owner"]),
|
2021-10-06 22:32:36 +02:00
|
|
|
path: json["path"],
|
|
|
|
itemType: itemType,
|
|
|
|
mimeType: json["mimetype"],
|
|
|
|
itemSource: json["item_source"],
|
2021-09-28 08:36:00 +02:00
|
|
|
// when shared with a password protected link, shareWith somehow contains
|
|
|
|
// the password, which doesn't make sense. We set it to null instead
|
2021-11-12 22:13:02 +01:00
|
|
|
shareWith: shareType == ShareType.publicLink
|
|
|
|
? null
|
|
|
|
: (json["share_with"] as String?)?.toCi(),
|
2021-08-07 22:34:44 +02:00
|
|
|
shareWithDisplayName: json["share_with_displayname"],
|
2021-09-28 08:36:00 +02:00
|
|
|
url: json["url"],
|
2021-08-07 22:34:44 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|