mirror of
https://gitlab.com/nkming2/nc-photos.git
synced 2025-01-22 16:56:19 +01:00
Refactor: move nextcloud api to dedicated pacakge
This commit is contained in:
parent
6e00d44871
commit
7a17f2b274
133 changed files with 2668 additions and 952 deletions
|
@ -3,11 +3,11 @@ import 'dart:math';
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/iterable_extension.dart';
|
import 'package:nc_photos/iterable_extension.dart';
|
||||||
import 'package:nc_photos/string_extension.dart';
|
|
||||||
import 'package:nc_photos/type.dart';
|
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
|
import 'package:np_common/string_extension.dart';
|
||||||
|
import 'package:np_common/type.dart';
|
||||||
import 'package:to_string/to_string.dart';
|
import 'package:to_string/to_string.dart';
|
||||||
|
|
||||||
part 'account.g.dart';
|
part 'account.g.dart';
|
||||||
|
|
|
@ -4,10 +4,10 @@ import 'dart:convert';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/api/api.dart';
|
|
||||||
import 'package:nc_photos/entity/file_descriptor.dart';
|
import 'package:nc_photos/entity/file_descriptor.dart';
|
||||||
import 'package:nc_photos/entity/file_util.dart' as file_util;
|
import 'package:nc_photos/entity/file_util.dart' as file_util;
|
||||||
import 'package:nc_photos/exception.dart';
|
import 'package:nc_photos/exception.dart';
|
||||||
|
import 'package:np_api/np_api.dart';
|
||||||
import 'package:to_string/to_string.dart';
|
import 'package:to_string/to_string.dart';
|
||||||
|
|
||||||
part 'api_util.g.dart';
|
part 'api_util.g.dart';
|
||||||
|
|
173
app/lib/api/entity_converter.dart
Normal file
173
app/lib/api/entity_converter.dart
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:logging/logging.dart';
|
||||||
|
import 'package:nc_photos/entity/face.dart';
|
||||||
|
import 'package:nc_photos/entity/favorite.dart';
|
||||||
|
import 'package:nc_photos/entity/file.dart';
|
||||||
|
import 'package:nc_photos/entity/person.dart';
|
||||||
|
import 'package:nc_photos/entity/share.dart';
|
||||||
|
import 'package:nc_photos/entity/sharee.dart';
|
||||||
|
import 'package:nc_photos/entity/tag.dart';
|
||||||
|
import 'package:nc_photos/entity/tagged_file.dart';
|
||||||
|
import 'package:nc_photos/object_extension.dart';
|
||||||
|
import 'package:np_api/np_api.dart' as api;
|
||||||
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
|
import 'package:np_common/string_extension.dart';
|
||||||
|
|
||||||
|
part 'entity_converter.g.dart';
|
||||||
|
|
||||||
|
class ApiFaceConverter {
|
||||||
|
static Face fromApi(api.Face face) {
|
||||||
|
return Face(
|
||||||
|
id: face.id,
|
||||||
|
fileId: face.fileId,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ApiFavoriteConverter {
|
||||||
|
static Favorite fromApi(api.Favorite favorite) {
|
||||||
|
return Favorite(
|
||||||
|
fileId: favorite.fileId,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@npLog
|
||||||
|
class ApiFileConverter {
|
||||||
|
static File fromApi(api.File file) {
|
||||||
|
final metadata = file.customProperties?["com.nkming.nc_photos:metadata"]
|
||||||
|
?.run((obj) => Metadata.fromJson(
|
||||||
|
jsonDecode(obj),
|
||||||
|
upgraderV1: MetadataUpgraderV1(
|
||||||
|
fileContentType: file.contentType,
|
||||||
|
logFilePath: file.href,
|
||||||
|
),
|
||||||
|
upgraderV2: MetadataUpgraderV2(
|
||||||
|
fileContentType: file.contentType,
|
||||||
|
logFilePath: file.href,
|
||||||
|
),
|
||||||
|
upgraderV3: MetadataUpgraderV3(
|
||||||
|
fileContentType: file.contentType,
|
||||||
|
logFilePath: file.href,
|
||||||
|
),
|
||||||
|
));
|
||||||
|
return File(
|
||||||
|
path: _hrefToPath(file.href),
|
||||||
|
contentLength: file.contentLength,
|
||||||
|
contentType: file.contentType,
|
||||||
|
etag: file.etag,
|
||||||
|
lastModified: file.lastModified,
|
||||||
|
isCollection: file.isCollection,
|
||||||
|
hasPreview: file.hasPreview,
|
||||||
|
fileId: file.fileId,
|
||||||
|
isFavorite: file.favorite,
|
||||||
|
ownerId: file.ownerId?.toCi(),
|
||||||
|
ownerDisplayName: file.ownerDisplayName,
|
||||||
|
trashbinFilename: file.trashbinFilename,
|
||||||
|
trashbinOriginalLocation: file.trashbinOriginalLocation,
|
||||||
|
trashbinDeletionTime: file.trashbinDeletionTime,
|
||||||
|
metadata: metadata,
|
||||||
|
isArchived: file.customProperties?["com.nkming.nc_photos:is-archived"]
|
||||||
|
?.run((obj) => obj == "true"),
|
||||||
|
overrideDateTime: file
|
||||||
|
.customProperties?["com.nkming.nc_photos:override-date-time"]
|
||||||
|
?.run((obj) => DateTime.parse(obj)),
|
||||||
|
location: file.customProperties?["com.nkming.nc_photos:location"]
|
||||||
|
?.run((obj) => ImageLocation.fromJson(jsonDecode(obj))),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static String _hrefToPath(String href) {
|
||||||
|
final rawPath = href.trimLeftAny("/");
|
||||||
|
final pos = rawPath.indexOf("remote.php");
|
||||||
|
if (pos == -1) {
|
||||||
|
// what?
|
||||||
|
_log.warning("[_hrefToPath] Unknown href value: $rawPath");
|
||||||
|
return rawPath;
|
||||||
|
} else {
|
||||||
|
return rawPath.substring(pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static final _log = _$ApiFileConverterNpLog.log;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ApiPersonConverter {
|
||||||
|
static Person fromApi(api.Person person) {
|
||||||
|
return Person(
|
||||||
|
name: person.name,
|
||||||
|
thumbFaceId: person.thumbFaceId,
|
||||||
|
count: person.count,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ApiShareConverter {
|
||||||
|
static Share fromApi(api.Share share) {
|
||||||
|
final shareType = ShareTypeExtension.fromValue(share.shareType);
|
||||||
|
final itemType = ShareItemTypeExtension.fromValue(share.itemType);
|
||||||
|
return Share(
|
||||||
|
id: share.id,
|
||||||
|
shareType: shareType,
|
||||||
|
stime: DateTime.fromMillisecondsSinceEpoch(share.stime * 1000),
|
||||||
|
uidOwner: share.uidOwner.toCi(),
|
||||||
|
displaynameOwner: share.displaynameOwner,
|
||||||
|
uidFileOwner: share.uidFileOwner.toCi(),
|
||||||
|
path: share.path,
|
||||||
|
itemType: itemType,
|
||||||
|
mimeType: share.mimeType,
|
||||||
|
itemSource: share.itemSource,
|
||||||
|
// when shared with a password protected link, shareWith somehow contains
|
||||||
|
// the password, which doesn't make sense. We set it to null instead
|
||||||
|
shareWith:
|
||||||
|
shareType == ShareType.publicLink ? null : share.shareWith?.toCi(),
|
||||||
|
shareWithDisplayName: share.shareWithDisplayName,
|
||||||
|
url: share.url,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ApiShareeConverter {
|
||||||
|
static Sharee fromApi(api.Sharee sharee) {
|
||||||
|
return Sharee(
|
||||||
|
type: _keyTypes[sharee.type]!,
|
||||||
|
label: sharee.label,
|
||||||
|
shareType: sharee.shareType,
|
||||||
|
shareWith: sharee.shareWith.toCi(),
|
||||||
|
shareWithDisplayNameUnique: sharee.shareWithDisplayNameUnique,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const _keyTypes = {
|
||||||
|
"users": ShareeType.user,
|
||||||
|
"groups": ShareeType.group,
|
||||||
|
"remotes": ShareeType.remote,
|
||||||
|
"remote_groups": ShareeType.remoteGroup,
|
||||||
|
"emails": ShareeType.email,
|
||||||
|
"circles": ShareeType.circle,
|
||||||
|
"rooms": ShareeType.room,
|
||||||
|
"deck": ShareeType.deck,
|
||||||
|
"lookup": ShareeType.lookup,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class ApiTagConverter {
|
||||||
|
static Tag fromApi(api.Tag tag) {
|
||||||
|
return Tag(
|
||||||
|
id: tag.id,
|
||||||
|
displayName: tag.displayName,
|
||||||
|
userVisible: tag.userVisible,
|
||||||
|
userAssignable: tag.userAssignable,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ApiTaggedFileConverter {
|
||||||
|
static TaggedFile fromApi(api.TaggedFile taggedFile) {
|
||||||
|
return TaggedFile(
|
||||||
|
fileId: taggedFile.fileId,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
14
app/lib/api/entity_converter.g.dart
Normal file
14
app/lib/api/entity_converter.g.dart
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'entity_converter.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// NpLogGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
extension _$ApiFileConverterNpLog on ApiFileConverter {
|
||||||
|
// ignore: unused_element
|
||||||
|
Logger get _log => log;
|
||||||
|
|
||||||
|
static final log = Logger("api.entity_converter.ApiFileConverter");
|
||||||
|
}
|
|
@ -5,9 +5,9 @@ import 'package:bloc/bloc.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/api/api_util.dart' as api_util;
|
import 'package:nc_photos/api/api_util.dart' as api_util;
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/exception.dart';
|
import 'package:nc_photos/exception.dart';
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
import 'package:to_string/to_string.dart';
|
import 'package:to_string/to_string.dart';
|
||||||
|
|
||||||
part 'app_password_exchange.g.dart';
|
part 'app_password_exchange.g.dart';
|
||||||
|
|
|
@ -4,7 +4,6 @@ import 'package:flutter/foundation.dart';
|
||||||
import 'package:kiwi/kiwi.dart';
|
import 'package:kiwi/kiwi.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/di_container.dart';
|
import 'package:nc_photos/di_container.dart';
|
||||||
import 'package:nc_photos/entity/album.dart';
|
import 'package:nc_photos/entity/album.dart';
|
||||||
import 'package:nc_photos/entity/person.dart';
|
import 'package:nc_photos/entity/person.dart';
|
||||||
|
@ -15,6 +14,7 @@ import 'package:nc_photos/use_case/list_location_group.dart';
|
||||||
import 'package:nc_photos/use_case/list_person.dart';
|
import 'package:nc_photos/use_case/list_person.dart';
|
||||||
import 'package:nc_photos/use_case/list_tag.dart';
|
import 'package:nc_photos/use_case/list_tag.dart';
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
import 'package:to_string/to_string.dart';
|
import 'package:to_string/to_string.dart';
|
||||||
import 'package:tuple/tuple.dart';
|
import 'package:tuple/tuple.dart';
|
||||||
import 'package:woozy_search/woozy_search.dart';
|
import 'package:woozy_search/woozy_search.dart';
|
||||||
|
|
|
@ -3,7 +3,6 @@ import 'package:equatable/equatable.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/debug_util.dart';
|
import 'package:nc_photos/debug_util.dart';
|
||||||
import 'package:nc_photos/di_container.dart';
|
import 'package:nc_photos/di_container.dart';
|
||||||
import 'package:nc_photos/entity/album.dart';
|
import 'package:nc_photos/entity/album.dart';
|
||||||
|
@ -16,6 +15,7 @@ import 'package:nc_photos/object_extension.dart';
|
||||||
import 'package:nc_photos/use_case/list_share.dart';
|
import 'package:nc_photos/use_case/list_share.dart';
|
||||||
import 'package:nc_photos/use_case/list_sharee.dart';
|
import 'package:nc_photos/use_case/list_sharee.dart';
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
import 'package:to_string/to_string.dart';
|
import 'package:to_string/to_string.dart';
|
||||||
|
|
||||||
part 'list_album_share_outlier.g.dart';
|
part 'list_album_share_outlier.g.dart';
|
||||||
|
|
|
@ -2,9 +2,9 @@ import 'package:bloc/bloc.dart';
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/iterable_extension.dart';
|
import 'package:nc_photos/iterable_extension.dart';
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
import 'package:to_string/to_string.dart';
|
import 'package:to_string/to_string.dart';
|
||||||
import 'package:tuple/tuple.dart';
|
import 'package:tuple/tuple.dart';
|
||||||
import 'package:woozy_search/woozy_search.dart';
|
import 'package:woozy_search/woozy_search.dart';
|
||||||
|
|
|
@ -3,7 +3,7 @@ import 'dart:convert';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:nc_photos/mobile/platform.dart'
|
import 'package:nc_photos/mobile/platform.dart'
|
||||||
if (dart.library.html) 'package:nc_photos/web/platform.dart' as platform;
|
if (dart.library.html) 'package:nc_photos/web/platform.dart' as platform;
|
||||||
import 'package:nc_photos/string_extension.dart';
|
import 'package:np_common/string_extension.dart';
|
||||||
import 'package:path/path.dart' as path_lib;
|
import 'package:path/path.dart' as path_lib;
|
||||||
|
|
||||||
class LogCapturer {
|
class LogCapturer {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import 'package:nc_photos/string_extension.dart';
|
import 'package:np_common/string_extension.dart';
|
||||||
|
|
||||||
extension DoubleExtension on double {
|
extension DoubleExtension on double {
|
||||||
/// Same as toStringAsFixed but with trailing zeros truncated
|
/// Same as toStringAsFixed but with trailing zeros truncated
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/entity/album/cover_provider.dart';
|
import 'package:nc_photos/entity/album/cover_provider.dart';
|
||||||
import 'package:nc_photos/entity/album/provider.dart';
|
import 'package:nc_photos/entity/album/provider.dart';
|
||||||
import 'package:nc_photos/entity/album/sort_provider.dart';
|
import 'package:nc_photos/entity/album/sort_provider.dart';
|
||||||
|
@ -10,8 +9,9 @@ import 'package:nc_photos/entity/file.dart';
|
||||||
import 'package:nc_photos/iterable_extension.dart';
|
import 'package:nc_photos/iterable_extension.dart';
|
||||||
import 'package:nc_photos/object_extension.dart';
|
import 'package:nc_photos/object_extension.dart';
|
||||||
import 'package:nc_photos/or_null.dart';
|
import 'package:nc_photos/or_null.dart';
|
||||||
import 'package:nc_photos/type.dart';
|
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
|
import 'package:np_common/type.dart';
|
||||||
import 'package:to_string/to_string.dart';
|
import 'package:to_string/to_string.dart';
|
||||||
|
|
||||||
part 'album.g.dart';
|
part 'album.g.dart';
|
||||||
|
|
|
@ -7,8 +7,8 @@ import 'package:nc_photos/entity/album/provider.dart';
|
||||||
import 'package:nc_photos/entity/file.dart';
|
import 'package:nc_photos/entity/file.dart';
|
||||||
import 'package:nc_photos/entity/file_descriptor.dart';
|
import 'package:nc_photos/entity/file_descriptor.dart';
|
||||||
import 'package:nc_photos/entity/file_util.dart' as file_util;
|
import 'package:nc_photos/entity/file_util.dart' as file_util;
|
||||||
import 'package:nc_photos/type.dart';
|
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/type.dart';
|
||||||
import 'package:to_string/to_string.dart';
|
import 'package:to_string/to_string.dart';
|
||||||
|
|
||||||
part 'cover_provider.g.dart';
|
part 'cover_provider.g.dart';
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/entity/file.dart';
|
import 'package:nc_photos/entity/file.dart';
|
||||||
import 'package:nc_photos/or_null.dart';
|
import 'package:nc_photos/or_null.dart';
|
||||||
import 'package:nc_photos/type.dart';
|
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
|
import 'package:np_common/type.dart';
|
||||||
import 'package:to_string/to_string.dart';
|
import 'package:to_string/to_string.dart';
|
||||||
|
|
||||||
part 'item.g.dart';
|
part 'item.g.dart';
|
||||||
|
|
|
@ -9,8 +9,8 @@ import 'package:nc_photos/entity/file.dart';
|
||||||
import 'package:nc_photos/entity/tag.dart';
|
import 'package:nc_photos/entity/tag.dart';
|
||||||
import 'package:nc_photos/iterable_extension.dart';
|
import 'package:nc_photos/iterable_extension.dart';
|
||||||
import 'package:nc_photos/or_null.dart';
|
import 'package:nc_photos/or_null.dart';
|
||||||
import 'package:nc_photos/type.dart';
|
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/type.dart';
|
||||||
import 'package:to_string/to_string.dart';
|
import 'package:to_string/to_string.dart';
|
||||||
|
|
||||||
part 'provider.g.dart';
|
part 'provider.g.dart';
|
||||||
|
|
|
@ -5,8 +5,8 @@ import 'package:nc_photos/entity/album/item.dart';
|
||||||
import 'package:nc_photos/entity/file.dart';
|
import 'package:nc_photos/entity/file.dart';
|
||||||
import 'package:nc_photos/entity/file_descriptor.dart';
|
import 'package:nc_photos/entity/file_descriptor.dart';
|
||||||
import 'package:nc_photos/iterable_extension.dart';
|
import 'package:nc_photos/iterable_extension.dart';
|
||||||
import 'package:nc_photos/type.dart';
|
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/type.dart';
|
||||||
import 'package:to_string/to_string.dart';
|
import 'package:to_string/to_string.dart';
|
||||||
import 'package:tuple/tuple.dart';
|
import 'package:tuple/tuple.dart';
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/entity/exif.dart';
|
import 'package:nc_photos/entity/exif.dart';
|
||||||
import 'package:nc_photos/entity/file.dart';
|
import 'package:nc_photos/entity/file.dart';
|
||||||
import 'package:nc_photos/type.dart';
|
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
|
import 'package:np_common/type.dart';
|
||||||
import 'package:tuple/tuple.dart';
|
import 'package:tuple/tuple.dart';
|
||||||
|
|
||||||
part 'upgrader.g.dart';
|
part 'upgrader.g.dart';
|
||||||
|
|
|
@ -2,8 +2,8 @@ import 'package:equatable/equatable.dart';
|
||||||
import 'package:exifdart/exifdart.dart';
|
import 'package:exifdart/exifdart.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/type.dart';
|
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/type.dart';
|
||||||
|
|
||||||
part 'exif.g.dart';
|
part 'exif.g.dart';
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/api/api.dart';
|
import 'package:nc_photos/api/entity_converter.dart';
|
||||||
import 'package:nc_photos/entity/face.dart';
|
import 'package:nc_photos/entity/face.dart';
|
||||||
import 'package:nc_photos/entity/person.dart';
|
import 'package:nc_photos/entity/person.dart';
|
||||||
import 'package:nc_photos/exception.dart';
|
import 'package:nc_photos/exception.dart';
|
||||||
import 'package:nc_photos/type.dart';
|
import 'package:nc_photos/np_api_util.dart';
|
||||||
|
import 'package:np_api/np_api.dart' as api;
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
|
||||||
part 'data_source.g.dart';
|
part 'data_source.g.dart';
|
||||||
|
@ -18,7 +17,7 @@ class FaceRemoteDataSource implements FaceDataSource {
|
||||||
@override
|
@override
|
||||||
list(Account account, Person person) async {
|
list(Account account, Person person) async {
|
||||||
_log.info("[list] $person");
|
_log.info("[list] $person");
|
||||||
final response = await Api(account)
|
final response = await ApiUtil.fromAccount(account)
|
||||||
.ocs()
|
.ocs()
|
||||||
.facerecognition()
|
.facerecognition()
|
||||||
.person(person.name)
|
.person(person.name)
|
||||||
|
@ -28,34 +27,11 @@ class FaceRemoteDataSource implements FaceDataSource {
|
||||||
_log.severe("[list] Failed requesting server: $response");
|
_log.severe("[list] Failed requesting server: $response");
|
||||||
throw ApiException(
|
throw ApiException(
|
||||||
response: response,
|
response: response,
|
||||||
message:
|
message: "Server responed with an error: HTTP ${response.statusCode}",
|
||||||
"Server responed with an error: HTTP ${response.statusCode}");
|
|
||||||
}
|
|
||||||
|
|
||||||
final json = jsonDecode(response.body);
|
|
||||||
final List<JsonObj> dataJson = json["ocs"]["data"].cast<JsonObj>();
|
|
||||||
return _FaceParser().parseList(dataJson);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@npLog
|
|
||||||
class _FaceParser {
|
|
||||||
List<Face> parseList(List<JsonObj> jsons) {
|
|
||||||
final product = <Face>[];
|
|
||||||
for (final j in jsons) {
|
|
||||||
try {
|
|
||||||
product.add(parseSingle(j));
|
|
||||||
} catch (e) {
|
|
||||||
_log.severe("[parseList] Failed parsing json: ${jsonEncode(j)}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return product;
|
|
||||||
}
|
|
||||||
|
|
||||||
Face parseSingle(JsonObj json) {
|
|
||||||
return Face(
|
|
||||||
id: json["id"],
|
|
||||||
fileId: json["fileId"],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final apiFaces = await api.FaceParser().parse(response.body);
|
||||||
|
return apiFaces.map(ApiFaceConverter.fromApi).toList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,3 @@ extension _$FaceRemoteDataSourceNpLog on FaceRemoteDataSource {
|
||||||
|
|
||||||
static final log = Logger("entity.face.data_source.FaceRemoteDataSource");
|
static final log = Logger("entity.face.data_source.FaceRemoteDataSource");
|
||||||
}
|
}
|
||||||
|
|
||||||
extension _$_FaceParserNpLog on _FaceParser {
|
|
||||||
// ignore: unused_element
|
|
||||||
Logger get _log => log;
|
|
||||||
|
|
||||||
static final log = Logger("entity.face.data_source._FaceParser");
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/api/api.dart';
|
import 'package:nc_photos/api/entity_converter.dart';
|
||||||
import 'package:nc_photos/entity/favorite.dart';
|
import 'package:nc_photos/entity/favorite.dart';
|
||||||
import 'package:nc_photos/entity/file.dart';
|
import 'package:nc_photos/entity/file.dart';
|
||||||
import 'package:nc_photos/entity/webdav_response_parser.dart';
|
|
||||||
import 'package:nc_photos/exception.dart';
|
import 'package:nc_photos/exception.dart';
|
||||||
|
import 'package:nc_photos/np_api_util.dart';
|
||||||
|
import 'package:np_api/np_api.dart' as api;
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
import 'package:xml/xml.dart';
|
|
||||||
|
|
||||||
part 'data_source.g.dart';
|
part 'data_source.g.dart';
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ class FavoriteRemoteDataSource implements FavoriteDataSource {
|
||||||
@override
|
@override
|
||||||
list(Account account, File dir) async {
|
list(Account account, File dir) async {
|
||||||
_log.info("[list] ${dir.path}");
|
_log.info("[list] ${dir.path}");
|
||||||
final response = await Api(account).files().report(
|
final response = await ApiUtil.fromAccount(account).files().report(
|
||||||
path: dir.path,
|
path: dir.path,
|
||||||
favorite: true,
|
favorite: true,
|
||||||
);
|
);
|
||||||
|
@ -25,11 +25,11 @@ class FavoriteRemoteDataSource implements FavoriteDataSource {
|
||||||
_log.severe("[list] Failed requesting server: $response");
|
_log.severe("[list] Failed requesting server: $response");
|
||||||
throw ApiException(
|
throw ApiException(
|
||||||
response: response,
|
response: response,
|
||||||
message:
|
message: "Server responed with an error: HTTP ${response.statusCode}",
|
||||||
"Server responed with an error: HTTP ${response.statusCode}");
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
final xml = XmlDocument.parse(response.body);
|
final apiFavorites = await api.FavoriteParser().parse(response.body);
|
||||||
return WebdavResponseParser().parseFavorites(xml);
|
return apiFavorites.map(ApiFavoriteConverter.fromApi).toList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,15 +3,15 @@ import 'dart:typed_data';
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/entity/exif.dart';
|
import 'package:nc_photos/entity/exif.dart';
|
||||||
import 'package:nc_photos/entity/file_descriptor.dart';
|
import 'package:nc_photos/entity/file_descriptor.dart';
|
||||||
import 'package:nc_photos/entity/file_util.dart' as file_util;
|
import 'package:nc_photos/entity/file_util.dart' as file_util;
|
||||||
import 'package:nc_photos/json_util.dart' as json_util;
|
import 'package:nc_photos/json_util.dart' as json_util;
|
||||||
import 'package:nc_photos/or_null.dart';
|
import 'package:nc_photos/or_null.dart';
|
||||||
import 'package:nc_photos/string_extension.dart';
|
|
||||||
import 'package:nc_photos/type.dart';
|
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
|
import 'package:np_common/string_extension.dart';
|
||||||
|
import 'package:np_common/type.dart';
|
||||||
import 'package:to_string/to_string.dart';
|
import 'package:to_string/to_string.dart';
|
||||||
|
|
||||||
part 'file.g.dart';
|
part 'file.g.dart';
|
||||||
|
|
|
@ -4,7 +4,7 @@ import 'dart:typed_data';
|
||||||
import 'package:drift/drift.dart' as sql;
|
import 'package:drift/drift.dart' as sql;
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/api/api.dart';
|
import 'package:nc_photos/api/entity_converter.dart';
|
||||||
import 'package:nc_photos/debug_util.dart';
|
import 'package:nc_photos/debug_util.dart';
|
||||||
import 'package:nc_photos/di_container.dart';
|
import 'package:nc_photos/di_container.dart';
|
||||||
import 'package:nc_photos/entity/file.dart';
|
import 'package:nc_photos/entity/file.dart';
|
||||||
|
@ -13,15 +13,15 @@ import 'package:nc_photos/entity/file_descriptor.dart';
|
||||||
import 'package:nc_photos/entity/file_util.dart' as file_util;
|
import 'package:nc_photos/entity/file_util.dart' as file_util;
|
||||||
import 'package:nc_photos/entity/sqlite/database.dart' as sql;
|
import 'package:nc_photos/entity/sqlite/database.dart' as sql;
|
||||||
import 'package:nc_photos/entity/sqlite/files_query_builder.dart' as sql;
|
import 'package:nc_photos/entity/sqlite/files_query_builder.dart' as sql;
|
||||||
import 'package:nc_photos/entity/webdav_response_parser.dart';
|
|
||||||
import 'package:nc_photos/exception.dart';
|
import 'package:nc_photos/exception.dart';
|
||||||
import 'package:nc_photos/iterable_extension.dart';
|
import 'package:nc_photos/iterable_extension.dart';
|
||||||
|
import 'package:nc_photos/np_api_util.dart';
|
||||||
import 'package:nc_photos/object_extension.dart';
|
import 'package:nc_photos/object_extension.dart';
|
||||||
import 'package:nc_photos/or_null.dart';
|
import 'package:nc_photos/or_null.dart';
|
||||||
import 'package:nc_photos/use_case/compat/v32.dart';
|
import 'package:nc_photos/use_case/compat/v32.dart';
|
||||||
|
import 'package:np_api/np_api.dart' as api;
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
import 'package:path/path.dart' as path_lib;
|
import 'package:path/path.dart' as path_lib;
|
||||||
import 'package:xml/xml.dart';
|
|
||||||
|
|
||||||
part 'data_source.g.dart';
|
part 'data_source.g.dart';
|
||||||
|
|
||||||
|
@ -92,20 +92,22 @@ class FileWebdavDataSource implements FileDataSource {
|
||||||
@override
|
@override
|
||||||
remove(Account account, File f) async {
|
remove(Account account, File f) async {
|
||||||
_log.info("[remove] ${f.path}");
|
_log.info("[remove] ${f.path}");
|
||||||
final response = await Api(account).files().delete(path: f.path);
|
final response =
|
||||||
|
await ApiUtil.fromAccount(account).files().delete(path: f.path);
|
||||||
if (!response.isGood) {
|
if (!response.isGood) {
|
||||||
_log.severe("[remove] Failed requesting server: $response");
|
_log.severe("[remove] Failed requesting server: $response");
|
||||||
throw ApiException(
|
throw ApiException(
|
||||||
response: response,
|
response: response,
|
||||||
message:
|
message: "Server responed with an error: HTTP ${response.statusCode}",
|
||||||
"Server responed with an error: HTTP ${response.statusCode}");
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
getBinary(Account account, File f) async {
|
getBinary(Account account, File f) async {
|
||||||
_log.info("[getBinary] ${f.path}");
|
_log.info("[getBinary] ${f.path}");
|
||||||
final response = await Api(account).files().get(path: f.path);
|
final response =
|
||||||
|
await ApiUtil.fromAccount(account).files().get(path: f.path);
|
||||||
if (!response.isGood) {
|
if (!response.isGood) {
|
||||||
_log.severe("[getBinary] Failed requesting server: $response");
|
_log.severe("[getBinary] Failed requesting server: $response");
|
||||||
throw ApiException(
|
throw ApiException(
|
||||||
|
@ -119,8 +121,9 @@ class FileWebdavDataSource implements FileDataSource {
|
||||||
@override
|
@override
|
||||||
putBinary(Account account, String path, Uint8List content) async {
|
putBinary(Account account, String path, Uint8List content) async {
|
||||||
_log.info("[putBinary] $path");
|
_log.info("[putBinary] $path");
|
||||||
final response =
|
final response = await ApiUtil.fromAccount(account)
|
||||||
await Api(account).files().put(path: path, content: content);
|
.files()
|
||||||
|
.put(path: path, content: content);
|
||||||
if (!response.isGood) {
|
if (!response.isGood) {
|
||||||
_log.severe("[putBinary] Failed requesting server: $response");
|
_log.severe("[putBinary] Failed requesting server: $response");
|
||||||
throw ApiException(
|
throw ApiException(
|
||||||
|
@ -162,7 +165,7 @@ class FileWebdavDataSource implements FileDataSource {
|
||||||
if (OrNull.isSetNull(overrideDateTime)) "app:override-date-time",
|
if (OrNull.isSetNull(overrideDateTime)) "app:override-date-time",
|
||||||
if (OrNull.isSetNull(location)) "app:location",
|
if (OrNull.isSetNull(location)) "app:location",
|
||||||
];
|
];
|
||||||
final response = await Api(account).files().proppatch(
|
final response = await ApiUtil.fromAccount(account).files().proppatch(
|
||||||
path: f.path,
|
path: f.path,
|
||||||
namespaces: {
|
namespaces: {
|
||||||
"com.nkming.nc_photos": "app",
|
"com.nkming.nc_photos": "app",
|
||||||
|
@ -188,7 +191,7 @@ class FileWebdavDataSource implements FileDataSource {
|
||||||
bool? shouldOverwrite,
|
bool? shouldOverwrite,
|
||||||
}) async {
|
}) async {
|
||||||
_log.info("[copy] ${f.path} to $destination");
|
_log.info("[copy] ${f.path} to $destination");
|
||||||
final response = await Api(account).files().copy(
|
final response = await ApiUtil.fromAccount(account).files().copy(
|
||||||
path: f.path,
|
path: f.path,
|
||||||
destinationUrl: "${account.url}/$destination",
|
destinationUrl: "${account.url}/$destination",
|
||||||
overwrite: shouldOverwrite,
|
overwrite: shouldOverwrite,
|
||||||
|
@ -216,7 +219,7 @@ class FileWebdavDataSource implements FileDataSource {
|
||||||
bool? shouldOverwrite,
|
bool? shouldOverwrite,
|
||||||
}) async {
|
}) async {
|
||||||
_log.info("[move] ${f.path} to $destination");
|
_log.info("[move] ${f.path} to $destination");
|
||||||
final response = await Api(account).files().move(
|
final response = await ApiUtil.fromAccount(account).files().move(
|
||||||
path: f.path,
|
path: f.path,
|
||||||
destinationUrl: "${account.url}/$destination",
|
destinationUrl: "${account.url}/$destination",
|
||||||
overwrite: shouldOverwrite,
|
overwrite: shouldOverwrite,
|
||||||
|
@ -233,7 +236,7 @@ class FileWebdavDataSource implements FileDataSource {
|
||||||
@override
|
@override
|
||||||
createDir(Account account, String path) async {
|
createDir(Account account, String path) async {
|
||||||
_log.info("[createDir] $path");
|
_log.info("[createDir] $path");
|
||||||
final response = await Api(account).files().mkcol(
|
final response = await ApiUtil.fromAccount(account).files().mkcol(
|
||||||
path: path,
|
path: path,
|
||||||
);
|
);
|
||||||
if (!response.isGood) {
|
if (!response.isGood) {
|
||||||
|
@ -273,7 +276,7 @@ class FileWebdavDataSource implements FileDataSource {
|
||||||
Map<String, String>? customNamespaces,
|
Map<String, String>? customNamespaces,
|
||||||
List<String>? customProperties,
|
List<String>? customProperties,
|
||||||
}) async {
|
}) async {
|
||||||
final response = await Api(account).files().propfind(
|
final response = await ApiUtil.fromAccount(account).files().propfind(
|
||||||
path: dir.path,
|
path: dir.path,
|
||||||
depth: depth,
|
depth: depth,
|
||||||
getlastmodified: getlastmodified,
|
getlastmodified: getlastmodified,
|
||||||
|
@ -308,11 +311,11 @@ class FileWebdavDataSource implements FileDataSource {
|
||||||
"Server responed with an error: HTTP ${response.statusCode}");
|
"Server responed with an error: HTTP ${response.statusCode}");
|
||||||
}
|
}
|
||||||
|
|
||||||
final xml = XmlDocument.parse(response.body);
|
final apiFiles = await api.FileParser().parse(response.body);
|
||||||
var files = await WebdavResponseParser().parseFiles(xml);
|
|
||||||
// _log.fine("[list] Parsed files: [$files]");
|
// _log.fine("[list] Parsed files: [$files]");
|
||||||
bool hasNoMediaMarker = false;
|
bool hasNoMediaMarker = false;
|
||||||
files = files
|
final files = apiFiles
|
||||||
|
.map(ApiFileConverter.fromApi)
|
||||||
.forEachLazy((f) {
|
.forEachLazy((f) {
|
||||||
if (file_util.isNoMediaMarker(f)) {
|
if (file_util.isNoMediaMarker(f)) {
|
||||||
hasNoMediaMarker = true;
|
hasNoMediaMarker = true;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:nc_photos/type.dart';
|
import 'package:np_common/type.dart';
|
||||||
import 'package:path/path.dart' as path_lib;
|
import 'package:path/path.dart' as path_lib;
|
||||||
|
|
||||||
int compareFileDescriptorDateTimeDescending(
|
int compareFileDescriptorDateTimeDescending(
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/api/api_util.dart' as api_util;
|
import 'package:nc_photos/api/api_util.dart' as api_util;
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/entity/file.dart';
|
import 'package:nc_photos/entity/file.dart';
|
||||||
import 'package:nc_photos/entity/file_descriptor.dart';
|
import 'package:nc_photos/entity/file_descriptor.dart';
|
||||||
import 'package:nc_photos/platform/k.dart' as platform_k;
|
import 'package:nc_photos/platform/k.dart' as platform_k;
|
||||||
import 'package:nc_photos/remote_storage_util.dart' as remote_storage_util;
|
import 'package:nc_photos/remote_storage_util.dart' as remote_storage_util;
|
||||||
import 'package:nc_photos/string_extension.dart';
|
import 'package:np_common/ci_string.dart';
|
||||||
|
import 'package:np_common/string_extension.dart';
|
||||||
import 'package:path/path.dart' as path_lib;
|
import 'package:path/path.dart' as path_lib;
|
||||||
|
|
||||||
bool isSupportedMime(String mime) => supportedFormatMimes.contains(mime);
|
bool isSupportedMime(String mime) => supportedFormatMimes.contains(mime);
|
||||||
|
|
|
@ -2,13 +2,15 @@ import 'dart:convert';
|
||||||
|
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/api/api.dart';
|
import 'package:nc_photos/api/entity_converter.dart';
|
||||||
import 'package:nc_photos/entity/person.dart';
|
import 'package:nc_photos/entity/person.dart';
|
||||||
import 'package:nc_photos/entity/sqlite/database.dart' as sql;
|
import 'package:nc_photos/entity/sqlite/database.dart' as sql;
|
||||||
import 'package:nc_photos/entity/sqlite/type_converter.dart';
|
import 'package:nc_photos/entity/sqlite/type_converter.dart';
|
||||||
import 'package:nc_photos/exception.dart';
|
import 'package:nc_photos/exception.dart';
|
||||||
import 'package:nc_photos/type.dart';
|
import 'package:nc_photos/np_api_util.dart';
|
||||||
|
import 'package:np_api/np_api.dart' as api;
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/type.dart';
|
||||||
|
|
||||||
part 'data_source.g.dart';
|
part 'data_source.g.dart';
|
||||||
|
|
||||||
|
@ -19,18 +21,21 @@ class PersonRemoteDataSource implements PersonDataSource {
|
||||||
@override
|
@override
|
||||||
list(Account account) async {
|
list(Account account) async {
|
||||||
_log.info("[list] $account");
|
_log.info("[list] $account");
|
||||||
final response = await Api(account).ocs().facerecognition().persons().get();
|
final response = await ApiUtil.fromAccount(account)
|
||||||
|
.ocs()
|
||||||
|
.facerecognition()
|
||||||
|
.persons()
|
||||||
|
.get();
|
||||||
if (!response.isGood) {
|
if (!response.isGood) {
|
||||||
_log.severe("[list] Failed requesting server: $response");
|
_log.severe("[list] Failed requesting server: $response");
|
||||||
throw ApiException(
|
throw ApiException(
|
||||||
response: response,
|
response: response,
|
||||||
message:
|
message: "Server responed with an error: HTTP ${response.statusCode}",
|
||||||
"Server responed with an error: HTTP ${response.statusCode}");
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
final json = jsonDecode(response.body);
|
final apiPersons = await api.PersonParser().parse(response.body);
|
||||||
final List<JsonObj> dataJson = json["ocs"]["data"].cast<JsonObj>();
|
return apiPersons.map(ApiPersonConverter.fromApi).toList();
|
||||||
return _PersonParser().parseList(dataJson);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import 'package:drift/drift.dart' as sql;
|
import 'package:drift/drift.dart' as sql;
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/di_container.dart';
|
import 'package:nc_photos/di_container.dart';
|
||||||
import 'package:nc_photos/entity/file.dart';
|
import 'package:nc_photos/entity/file.dart';
|
||||||
import 'package:nc_photos/entity/file_descriptor.dart';
|
import 'package:nc_photos/entity/file_descriptor.dart';
|
||||||
|
@ -15,6 +14,7 @@ import 'package:nc_photos/object_extension.dart';
|
||||||
import 'package:nc_photos/use_case/list_tagged_file.dart';
|
import 'package:nc_photos/use_case/list_tagged_file.dart';
|
||||||
import 'package:nc_photos/use_case/populate_person.dart';
|
import 'package:nc_photos/use_case/populate_person.dart';
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
|
|
||||||
part 'data_source.g.dart';
|
part 'data_source.g.dart';
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/entity/file.dart';
|
import 'package:nc_photos/entity/file.dart';
|
||||||
import 'package:nc_photos/string_extension.dart';
|
import 'package:np_common/ci_string.dart';
|
||||||
|
import 'package:np_common/string_extension.dart';
|
||||||
import 'package:path/path.dart' as path_lib;
|
import 'package:path/path.dart' as path_lib;
|
||||||
import 'package:to_string/to_string.dart';
|
import 'package:to_string/to_string.dart';
|
||||||
|
|
||||||
|
|
|
@ -2,14 +2,16 @@ import 'dart:convert';
|
||||||
|
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/api/api.dart';
|
import 'package:nc_photos/api/entity_converter.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/entity/file.dart';
|
import 'package:nc_photos/entity/file.dart';
|
||||||
import 'package:nc_photos/entity/file_descriptor.dart';
|
import 'package:nc_photos/entity/file_descriptor.dart';
|
||||||
import 'package:nc_photos/entity/share.dart';
|
import 'package:nc_photos/entity/share.dart';
|
||||||
import 'package:nc_photos/exception.dart';
|
import 'package:nc_photos/exception.dart';
|
||||||
import 'package:nc_photos/type.dart';
|
import 'package:nc_photos/np_api_util.dart';
|
||||||
|
import 'package:np_api/np_api.dart' as api;
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
|
import 'package:np_common/type.dart';
|
||||||
|
|
||||||
part 'data_source.g.dart';
|
part 'data_source.g.dart';
|
||||||
|
|
||||||
|
@ -22,7 +24,8 @@ class ShareRemoteDataSource implements ShareDataSource {
|
||||||
bool? isIncludeReshare,
|
bool? isIncludeReshare,
|
||||||
}) async {
|
}) async {
|
||||||
_log.info("[list] ${file.path}");
|
_log.info("[list] ${file.path}");
|
||||||
final response = await Api(account).ocs().filesSharing().shares().get(
|
final response =
|
||||||
|
await ApiUtil.fromAccount(account).ocs().filesSharing().shares().get(
|
||||||
path: file.strippedPath,
|
path: file.strippedPath,
|
||||||
reshares: isIncludeReshare,
|
reshares: isIncludeReshare,
|
||||||
);
|
);
|
||||||
|
@ -32,7 +35,8 @@ class ShareRemoteDataSource implements ShareDataSource {
|
||||||
@override
|
@override
|
||||||
listDir(Account account, File dir) async {
|
listDir(Account account, File dir) async {
|
||||||
_log.info("[listDir] ${dir.path}");
|
_log.info("[listDir] ${dir.path}");
|
||||||
final response = await Api(account).ocs().filesSharing().shares().get(
|
final response =
|
||||||
|
await ApiUtil.fromAccount(account).ocs().filesSharing().shares().get(
|
||||||
path: dir.strippedPath,
|
path: dir.strippedPath,
|
||||||
subfiles: true,
|
subfiles: true,
|
||||||
);
|
);
|
||||||
|
@ -42,14 +46,16 @@ class ShareRemoteDataSource implements ShareDataSource {
|
||||||
@override
|
@override
|
||||||
listAll(Account account) async {
|
listAll(Account account) async {
|
||||||
_log.info("[listAll] $account");
|
_log.info("[listAll] $account");
|
||||||
final response = await Api(account).ocs().filesSharing().shares().get();
|
final response =
|
||||||
|
await ApiUtil.fromAccount(account).ocs().filesSharing().shares().get();
|
||||||
return _onListResult(response);
|
return _onListResult(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
reverseList(Account account, File file) async {
|
reverseList(Account account, File file) async {
|
||||||
_log.info("[reverseList] ${file.path}");
|
_log.info("[reverseList] ${file.path}");
|
||||||
final response = await Api(account).ocs().filesSharing().shares().get(
|
final response =
|
||||||
|
await ApiUtil.fromAccount(account).ocs().filesSharing().shares().get(
|
||||||
path: file.strippedPath,
|
path: file.strippedPath,
|
||||||
sharedWithMe: true,
|
sharedWithMe: true,
|
||||||
);
|
);
|
||||||
|
@ -59,7 +65,8 @@ class ShareRemoteDataSource implements ShareDataSource {
|
||||||
@override
|
@override
|
||||||
reverseListAll(Account account) async {
|
reverseListAll(Account account) async {
|
||||||
_log.info("[reverseListAll] $account");
|
_log.info("[reverseListAll] $account");
|
||||||
final response = await Api(account).ocs().filesSharing().shares().get(
|
final response =
|
||||||
|
await ApiUtil.fromAccount(account).ocs().filesSharing().shares().get(
|
||||||
sharedWithMe: true,
|
sharedWithMe: true,
|
||||||
);
|
);
|
||||||
return _onListResult(response);
|
return _onListResult(response);
|
||||||
|
@ -68,7 +75,8 @@ class ShareRemoteDataSource implements ShareDataSource {
|
||||||
@override
|
@override
|
||||||
create(Account account, File file, String shareWith) async {
|
create(Account account, File file, String shareWith) async {
|
||||||
_log.info("[create] Share '${file.path}' with '$shareWith'");
|
_log.info("[create] Share '${file.path}' with '$shareWith'");
|
||||||
final response = await Api(account).ocs().filesSharing().shares().post(
|
final response =
|
||||||
|
await ApiUtil.fromAccount(account).ocs().filesSharing().shares().post(
|
||||||
path: file.strippedPath,
|
path: file.strippedPath,
|
||||||
shareType: ShareType.user.toValue(),
|
shareType: ShareType.user.toValue(),
|
||||||
shareWith: shareWith,
|
shareWith: shareWith,
|
||||||
|
@ -77,8 +85,8 @@ class ShareRemoteDataSource implements ShareDataSource {
|
||||||
_log.severe("[create] Failed requesting server: $response");
|
_log.severe("[create] Failed requesting server: $response");
|
||||||
throw ApiException(
|
throw ApiException(
|
||||||
response: response,
|
response: response,
|
||||||
message:
|
message: "Server responed with an error: HTTP ${response.statusCode}",
|
||||||
"Server responed with an error: HTTP ${response.statusCode}");
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
final json = jsonDecode(response.body);
|
final json = jsonDecode(response.body);
|
||||||
|
@ -93,7 +101,8 @@ class ShareRemoteDataSource implements ShareDataSource {
|
||||||
String? password,
|
String? password,
|
||||||
}) async {
|
}) async {
|
||||||
_log.info("[createLink] Share '${file.path}' with a share link");
|
_log.info("[createLink] Share '${file.path}' with a share link");
|
||||||
final response = await Api(account).ocs().filesSharing().shares().post(
|
final response =
|
||||||
|
await ApiUtil.fromAccount(account).ocs().filesSharing().shares().post(
|
||||||
path: file.strippedPath,
|
path: file.strippedPath,
|
||||||
shareType: ShareType.publicLink.toValue(),
|
shareType: ShareType.publicLink.toValue(),
|
||||||
password: password,
|
password: password,
|
||||||
|
@ -102,8 +111,8 @@ class ShareRemoteDataSource implements ShareDataSource {
|
||||||
_log.severe("[create] Failed requesting server: $response");
|
_log.severe("[create] Failed requesting server: $response");
|
||||||
throw ApiException(
|
throw ApiException(
|
||||||
response: response,
|
response: response,
|
||||||
message:
|
message: "Server responed with an error: HTTP ${response.statusCode}",
|
||||||
"Server responed with an error: HTTP ${response.statusCode}");
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
final json = jsonDecode(response.body);
|
final json = jsonDecode(response.body);
|
||||||
|
@ -114,29 +123,31 @@ class ShareRemoteDataSource implements ShareDataSource {
|
||||||
@override
|
@override
|
||||||
delete(Account account, Share share) async {
|
delete(Account account, Share share) async {
|
||||||
_log.info("[delete] $share");
|
_log.info("[delete] $share");
|
||||||
final response =
|
final response = await ApiUtil.fromAccount(account)
|
||||||
await Api(account).ocs().filesSharing().share(share.id).delete();
|
.ocs()
|
||||||
|
.filesSharing()
|
||||||
|
.share(share.id)
|
||||||
|
.delete();
|
||||||
if (!response.isGood) {
|
if (!response.isGood) {
|
||||||
_log.severe("[delete] Failed requesting server: $response");
|
_log.severe("[delete] Failed requesting server: $response");
|
||||||
throw ApiException(
|
throw ApiException(
|
||||||
response: response,
|
response: response,
|
||||||
message:
|
message: "Server responed with an error: HTTP ${response.statusCode}",
|
||||||
"Server responed with an error: HTTP ${response.statusCode}");
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Share> _onListResult(Response response) {
|
Future<List<Share>> _onListResult(api.Response response) async {
|
||||||
if (!response.isGood) {
|
if (!response.isGood) {
|
||||||
_log.severe("[_onListResult] Failed requesting server: $response");
|
_log.severe("[_onListResult] Failed requesting server: $response");
|
||||||
throw ApiException(
|
throw ApiException(
|
||||||
response: response,
|
response: response,
|
||||||
message:
|
message: "Server responed with an error: HTTP ${response.statusCode}",
|
||||||
"Server responed with an error: HTTP ${response.statusCode}");
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
final json = jsonDecode(response.body);
|
final apiShares = await api.ShareParser().parse(response.body);
|
||||||
final List<JsonObj> dataJson = json["ocs"]["data"].cast<JsonObj>();
|
return apiShares.map(ApiShareConverter.fromApi).toList();
|
||||||
return _ShareParser().parseList(dataJson);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
import 'package:np_common/ci_string.dart';
|
||||||
import 'package:to_string/to_string.dart';
|
import 'package:to_string/to_string.dart';
|
||||||
|
|
||||||
part 'sharee.g.dart';
|
part 'sharee.g.dart';
|
||||||
|
|
|
@ -2,12 +2,14 @@ import 'dart:convert';
|
||||||
|
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/api/api.dart';
|
import 'package:nc_photos/api/entity_converter.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/entity/sharee.dart';
|
import 'package:nc_photos/entity/sharee.dart';
|
||||||
import 'package:nc_photos/exception.dart';
|
import 'package:nc_photos/exception.dart';
|
||||||
import 'package:nc_photos/type.dart';
|
import 'package:nc_photos/np_api_util.dart';
|
||||||
|
import 'package:np_api/np_api.dart' as api;
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
|
import 'package:np_common/type.dart';
|
||||||
|
|
||||||
part 'data_source.g.dart';
|
part 'data_source.g.dart';
|
||||||
|
|
||||||
|
@ -16,7 +18,8 @@ class ShareeRemoteDataSource implements ShareeDataSource {
|
||||||
@override
|
@override
|
||||||
list(Account account) async {
|
list(Account account) async {
|
||||||
_log.info("[list]");
|
_log.info("[list]");
|
||||||
final response = await Api(account).ocs().filesSharing().sharees().get(
|
final response =
|
||||||
|
await ApiUtil.fromAccount(account).ocs().filesSharing().sharees().get(
|
||||||
itemType: "file",
|
itemType: "file",
|
||||||
lookup: false,
|
lookup: false,
|
||||||
);
|
);
|
||||||
|
@ -28,9 +31,8 @@ class ShareeRemoteDataSource implements ShareeDataSource {
|
||||||
"Server responed with an error: HTTP ${response.statusCode}");
|
"Server responed with an error: HTTP ${response.statusCode}");
|
||||||
}
|
}
|
||||||
|
|
||||||
final json = jsonDecode(response.body);
|
final apiShares = await api.ShareeParser().parse(response.body);
|
||||||
final sharees = _ShareeParser()(json);
|
return apiShares.map(ApiShareeConverter.fromApi).toList();
|
||||||
return sharees;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:nc_photos/account.dart' as app;
|
import 'package:nc_photos/account.dart' as app;
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/entity/sqlite/database.dart';
|
import 'package:nc_photos/entity/sqlite/database.dart';
|
||||||
import 'package:nc_photos/location_util.dart' as location_util;
|
import 'package:nc_photos/location_util.dart' as location_util;
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
|
|
||||||
enum FilesQueryMode {
|
enum FilesQueryMode {
|
||||||
file,
|
file,
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/entity/album.dart';
|
import 'package:nc_photos/entity/album.dart';
|
||||||
import 'package:nc_photos/entity/album/cover_provider.dart';
|
import 'package:nc_photos/entity/album/cover_provider.dart';
|
||||||
import 'package:nc_photos/entity/album/provider.dart';
|
import 'package:nc_photos/entity/album/provider.dart';
|
||||||
|
@ -15,6 +14,7 @@ import 'package:nc_photos/entity/tag.dart';
|
||||||
import 'package:nc_photos/iterable_extension.dart';
|
import 'package:nc_photos/iterable_extension.dart';
|
||||||
import 'package:nc_photos/object_extension.dart';
|
import 'package:nc_photos/object_extension.dart';
|
||||||
import 'package:nc_photos/or_null.dart';
|
import 'package:nc_photos/or_null.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
|
|
||||||
extension SqlTagListExtension on List<sql.Tag> {
|
extension SqlTagListExtension on List<sql.Tag> {
|
||||||
Future<List<Tag>> convertToAppTag() {
|
Future<List<Tag>> convertToAppTag() {
|
||||||
|
|
|
@ -3,7 +3,7 @@ import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/entity/file.dart';
|
import 'package:nc_photos/entity/file.dart';
|
||||||
import 'package:nc_photos/json_util.dart' as json_util;
|
import 'package:nc_photos/json_util.dart' as json_util;
|
||||||
import 'package:nc_photos/or_null.dart';
|
import 'package:nc_photos/or_null.dart';
|
||||||
import 'package:nc_photos/type.dart';
|
import 'package:np_common/type.dart';
|
||||||
import 'package:to_string/to_string.dart';
|
import 'package:to_string/to_string.dart';
|
||||||
|
|
||||||
part 'tag.g.dart';
|
part 'tag.g.dart';
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/api/api.dart';
|
import 'package:nc_photos/api/entity_converter.dart';
|
||||||
import 'package:nc_photos/entity/file.dart';
|
import 'package:nc_photos/entity/file.dart';
|
||||||
import 'package:nc_photos/entity/sqlite/database.dart' as sql;
|
import 'package:nc_photos/entity/sqlite/database.dart' as sql;
|
||||||
import 'package:nc_photos/entity/sqlite/type_converter.dart';
|
import 'package:nc_photos/entity/sqlite/type_converter.dart';
|
||||||
import 'package:nc_photos/entity/tag.dart';
|
import 'package:nc_photos/entity/tag.dart';
|
||||||
import 'package:nc_photos/entity/webdav_response_parser.dart';
|
|
||||||
import 'package:nc_photos/exception.dart';
|
import 'package:nc_photos/exception.dart';
|
||||||
|
import 'package:nc_photos/np_api_util.dart';
|
||||||
|
import 'package:np_api/np_api.dart' as api;
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
import 'package:xml/xml.dart';
|
|
||||||
|
|
||||||
part 'data_source.g.dart';
|
part 'data_source.g.dart';
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ class TagRemoteDataSource implements TagDataSource {
|
||||||
@override
|
@override
|
||||||
list(Account account) async {
|
list(Account account) async {
|
||||||
_log.info("[list] $account");
|
_log.info("[list] $account");
|
||||||
final response = await Api(account).systemtags().propfind(
|
final response = await ApiUtil.fromAccount(account).systemtags().propfind(
|
||||||
id: 1,
|
id: 1,
|
||||||
displayName: 1,
|
displayName: 1,
|
||||||
userVisible: 1,
|
userVisible: 1,
|
||||||
|
@ -33,15 +33,17 @@ class TagRemoteDataSource implements TagDataSource {
|
||||||
"Server responed with an error: HTTP ${response.statusCode}");
|
"Server responed with an error: HTTP ${response.statusCode}");
|
||||||
}
|
}
|
||||||
|
|
||||||
final xml = XmlDocument.parse(response.body);
|
final apiTags = await api.TagParser().parse(response.body);
|
||||||
return WebdavResponseParser().parseTags(xml);
|
return apiTags.map(ApiTagConverter.fromApi).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
listByFile(Account account, File file) async {
|
listByFile(Account account, File file) async {
|
||||||
_log.info("[listByFile] ${file.path}");
|
_log.info("[listByFile] ${file.path}");
|
||||||
final response =
|
final response = await ApiUtil.fromAccount(account)
|
||||||
await Api(account).systemtagsRelations().files(file.fileId!).propfind(
|
.systemtagsRelations()
|
||||||
|
.files(file.fileId!)
|
||||||
|
.propfind(
|
||||||
id: 1,
|
id: 1,
|
||||||
displayName: 1,
|
displayName: 1,
|
||||||
userVisible: 1,
|
userVisible: 1,
|
||||||
|
@ -55,8 +57,8 @@ class TagRemoteDataSource implements TagDataSource {
|
||||||
"Server responed with an error: HTTP ${response.statusCode}");
|
"Server responed with an error: HTTP ${response.statusCode}");
|
||||||
}
|
}
|
||||||
|
|
||||||
final xml = XmlDocument.parse(response.body);
|
final apiTags = await api.TagParser().parse(response.body);
|
||||||
return WebdavResponseParser().parseTags(xml);
|
return apiTags.map(ApiTagConverter.fromApi).toList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/api/api.dart';
|
import 'package:nc_photos/api/entity_converter.dart';
|
||||||
import 'package:nc_photos/entity/file.dart';
|
import 'package:nc_photos/entity/file.dart';
|
||||||
import 'package:nc_photos/entity/tag.dart';
|
import 'package:nc_photos/entity/tag.dart';
|
||||||
import 'package:nc_photos/entity/tagged_file.dart';
|
import 'package:nc_photos/entity/tagged_file.dart';
|
||||||
import 'package:nc_photos/entity/webdav_response_parser.dart';
|
|
||||||
import 'package:nc_photos/exception.dart';
|
import 'package:nc_photos/exception.dart';
|
||||||
import 'package:nc_photos/iterable_extension.dart';
|
import 'package:nc_photos/iterable_extension.dart';
|
||||||
|
import 'package:nc_photos/np_api_util.dart';
|
||||||
|
import 'package:np_api/np_api.dart' as api;
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
import 'package:xml/xml.dart';
|
|
||||||
|
|
||||||
part 'data_source.g.dart';
|
part 'data_source.g.dart';
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ class TaggedFileRemoteDataSource implements TaggedFileDataSource {
|
||||||
list(Account account, File dir, List<Tag> tags) async {
|
list(Account account, File dir, List<Tag> tags) async {
|
||||||
_log.info(
|
_log.info(
|
||||||
"[list] ${tags.map((t) => t.displayName).toReadableString()} under ${dir.path}");
|
"[list] ${tags.map((t) => t.displayName).toReadableString()} under ${dir.path}");
|
||||||
final response = await Api(account).files().report(
|
final response = await ApiUtil.fromAccount(account).files().report(
|
||||||
path: dir.path,
|
path: dir.path,
|
||||||
systemtag: tags.map((t) => t.id).toList(),
|
systemtag: tags.map((t) => t.id).toList(),
|
||||||
);
|
);
|
||||||
|
@ -32,7 +32,7 @@ class TaggedFileRemoteDataSource implements TaggedFileDataSource {
|
||||||
"Server responed with an error: HTTP ${response.statusCode}");
|
"Server responed with an error: HTTP ${response.statusCode}");
|
||||||
}
|
}
|
||||||
|
|
||||||
final xml = XmlDocument.parse(response.body);
|
final apiTaggedFiles = await api.TaggedFileParser().parse(response.body);
|
||||||
return WebdavResponseParser().parseTaggedFiles(xml);
|
return apiTaggedFiles.map(ApiTaggedFileConverter.fromApi).toList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,550 +0,0 @@
|
||||||
import 'dart:convert';
|
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:logging/logging.dart';
|
|
||||||
import 'package:nc_photos/app_init.dart' as app_init;
|
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/entity/favorite.dart';
|
|
||||||
import 'package:nc_photos/entity/file.dart';
|
|
||||||
import 'package:nc_photos/entity/tag.dart';
|
|
||||||
import 'package:nc_photos/entity/tagged_file.dart';
|
|
||||||
import 'package:nc_photos/string_extension.dart';
|
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
|
||||||
import 'package:xml/xml.dart';
|
|
||||||
|
|
||||||
part 'webdav_response_parser.g.dart';
|
|
||||||
|
|
||||||
@npLog
|
|
||||||
class WebdavResponseParser {
|
|
||||||
Future<List<File>> parseFiles(XmlDocument xml) =>
|
|
||||||
compute(_parseFilesIsolate, xml);
|
|
||||||
|
|
||||||
Future<List<Favorite>> parseFavorites(XmlDocument xml) =>
|
|
||||||
compute(_parseFavoritesIsolate, xml);
|
|
||||||
|
|
||||||
Future<List<Tag>> parseTags(XmlDocument xml) =>
|
|
||||||
compute(_parseTagsIsolate, xml);
|
|
||||||
|
|
||||||
Future<List<TaggedFile>> parseTaggedFiles(XmlDocument xml) =>
|
|
||||||
compute(_parseTaggedFilesIsolate, xml);
|
|
||||||
|
|
||||||
Map<String, String> get namespaces => _namespaces;
|
|
||||||
|
|
||||||
List<File> _parseFiles(XmlDocument xml) => _parse<File>(xml, _toFile);
|
|
||||||
|
|
||||||
List<Favorite> _parseFavorites(XmlDocument xml) =>
|
|
||||||
_parse<Favorite>(xml, _toFavorite);
|
|
||||||
|
|
||||||
List<Tag> _parseTags(XmlDocument xml) => _parse<Tag>(xml, _toTag);
|
|
||||||
|
|
||||||
List<TaggedFile> _parseTaggedFiles(XmlDocument xml) =>
|
|
||||||
_parse<TaggedFile>(xml, _toTaggedFile);
|
|
||||||
|
|
||||||
List<T> _parse<T>(XmlDocument xml, T? Function(XmlElement) mapper) {
|
|
||||||
_namespaces = _parseNamespaces(xml);
|
|
||||||
final body = () {
|
|
||||||
try {
|
|
||||||
return xml.children.whereType<XmlElement>().firstWhere((element) =>
|
|
||||||
element.matchQualifiedName("multistatus",
|
|
||||||
prefix: "DAV:", namespaces: _namespaces));
|
|
||||||
} catch (_) {
|
|
||||||
_log.shout("[_parse] Missing element: multistatus");
|
|
||||||
rethrow;
|
|
||||||
}
|
|
||||||
}();
|
|
||||||
return body.children
|
|
||||||
.whereType<XmlElement>()
|
|
||||||
.where((e) => e.matchQualifiedName("response",
|
|
||||||
prefix: "DAV:", namespaces: _namespaces))
|
|
||||||
.map((e) {
|
|
||||||
try {
|
|
||||||
return mapper(e);
|
|
||||||
} catch (e, stackTrace) {
|
|
||||||
_log.shout("[_parse] Failed parsing XML", e, stackTrace);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.whereType<T>()
|
|
||||||
.toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, String> _parseNamespaces(XmlDocument xml) {
|
|
||||||
final namespaces = <String, String>{};
|
|
||||||
final xmlContent = xml.descendants.whereType<XmlElement>().firstWhere(
|
|
||||||
(element) => !element.name.qualified.startsWith("?"),
|
|
||||||
orElse: () => XmlElement(XmlName.fromString("")));
|
|
||||||
for (final a in xmlContent.attributes) {
|
|
||||||
if (a.name.prefix == "xmlns") {
|
|
||||||
namespaces[a.name.local] = a.value;
|
|
||||||
} else if (a.name.local == "xmlns") {
|
|
||||||
namespaces["!"] = a.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// _log.fine("[_parseNamespaces] Namespaces: $namespaces");
|
|
||||||
return namespaces;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Map <DAV:response> contents to File
|
|
||||||
File _toFile(XmlElement element) {
|
|
||||||
String? path;
|
|
||||||
int? contentLength;
|
|
||||||
String? contentType;
|
|
||||||
String? etag;
|
|
||||||
DateTime? lastModified;
|
|
||||||
bool? isCollection;
|
|
||||||
int? usedBytes;
|
|
||||||
bool? hasPreview;
|
|
||||||
int? fileId;
|
|
||||||
bool? isFavorite;
|
|
||||||
CiString? ownerId;
|
|
||||||
String? ownerDisplayName;
|
|
||||||
Metadata? metadata;
|
|
||||||
bool? isArchived;
|
|
||||||
DateTime? overrideDateTime;
|
|
||||||
String? trashbinFilename;
|
|
||||||
String? trashbinOriginalLocation;
|
|
||||||
DateTime? trashbinDeletionTime;
|
|
||||||
ImageLocation? location;
|
|
||||||
|
|
||||||
for (final child in element.children.whereType<XmlElement>()) {
|
|
||||||
if (child.matchQualifiedName("href",
|
|
||||||
prefix: "DAV:", namespaces: _namespaces)) {
|
|
||||||
path = _hrefToPath(child);
|
|
||||||
} else if (child.matchQualifiedName("propstat",
|
|
||||||
prefix: "DAV:", namespaces: _namespaces)) {
|
|
||||||
final status = child.children
|
|
||||||
.whereType<XmlElement>()
|
|
||||||
.firstWhere((element) => element.matchQualifiedName("status",
|
|
||||||
prefix: "DAV:", namespaces: _namespaces))
|
|
||||||
.innerText;
|
|
||||||
if (!status.contains(" 200 ")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
final prop = child.children.whereType<XmlElement>().firstWhere(
|
|
||||||
(element) => element.matchQualifiedName("prop",
|
|
||||||
prefix: "DAV:", namespaces: _namespaces));
|
|
||||||
final propParser =
|
|
||||||
_FilePropParser(namespaces: _namespaces, logFilePath: path);
|
|
||||||
propParser.parse(prop);
|
|
||||||
contentLength = propParser.contentLength;
|
|
||||||
contentType = propParser.contentType;
|
|
||||||
etag = propParser.etag;
|
|
||||||
lastModified = propParser.lastModified;
|
|
||||||
isCollection = propParser.isCollection;
|
|
||||||
usedBytes = propParser.usedBytes;
|
|
||||||
hasPreview = propParser.hasPreview;
|
|
||||||
fileId = propParser.fileId;
|
|
||||||
isFavorite = propParser.isFavorite;
|
|
||||||
ownerId = propParser.ownerId;
|
|
||||||
ownerDisplayName = propParser.ownerDisplayName;
|
|
||||||
metadata = propParser.metadata;
|
|
||||||
isArchived = propParser.isArchived;
|
|
||||||
overrideDateTime = propParser.overrideDateTime;
|
|
||||||
trashbinFilename = propParser.trashbinFilename;
|
|
||||||
trashbinOriginalLocation = propParser.trashbinOriginalLocation;
|
|
||||||
trashbinDeletionTime = propParser.trashbinDeletionTime;
|
|
||||||
location = propParser.location;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return File(
|
|
||||||
path: path!,
|
|
||||||
contentLength: contentLength,
|
|
||||||
contentType: contentType,
|
|
||||||
etag: etag,
|
|
||||||
lastModified: lastModified,
|
|
||||||
isCollection: isCollection,
|
|
||||||
usedBytes: usedBytes,
|
|
||||||
hasPreview: hasPreview,
|
|
||||||
fileId: fileId,
|
|
||||||
isFavorite: isFavorite,
|
|
||||||
ownerId: ownerId,
|
|
||||||
ownerDisplayName: ownerDisplayName,
|
|
||||||
metadata: metadata,
|
|
||||||
isArchived: isArchived,
|
|
||||||
overrideDateTime: overrideDateTime,
|
|
||||||
trashbinFilename: trashbinFilename,
|
|
||||||
trashbinOriginalLocation: trashbinOriginalLocation,
|
|
||||||
trashbinDeletionTime: trashbinDeletionTime,
|
|
||||||
location: location,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Map <DAV:response> contents to Favorite
|
|
||||||
Favorite _toFavorite(XmlElement element) {
|
|
||||||
String? path;
|
|
||||||
int? fileId;
|
|
||||||
|
|
||||||
for (final child in element.children.whereType<XmlElement>()) {
|
|
||||||
if (child.matchQualifiedName("href",
|
|
||||||
prefix: "DAV:", namespaces: _namespaces)) {
|
|
||||||
path = _hrefToPath(child);
|
|
||||||
} else if (child.matchQualifiedName("propstat",
|
|
||||||
prefix: "DAV:", namespaces: _namespaces)) {
|
|
||||||
final status = child.children
|
|
||||||
.whereType<XmlElement>()
|
|
||||||
.firstWhere((element) => element.matchQualifiedName("status",
|
|
||||||
prefix: "DAV:", namespaces: _namespaces))
|
|
||||||
.innerText;
|
|
||||||
if (!status.contains(" 200 ")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
final prop = child.children.whereType<XmlElement>().firstWhere(
|
|
||||||
(element) => element.matchQualifiedName("prop",
|
|
||||||
prefix: "DAV:", namespaces: _namespaces));
|
|
||||||
final propParser =
|
|
||||||
_FileIdPropParser(namespaces: _namespaces, logFilePath: path);
|
|
||||||
propParser.parse(prop);
|
|
||||||
fileId = propParser.fileId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Favorite(
|
|
||||||
fileId: fileId!,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Map <DAV:response> contents to Tag
|
|
||||||
Tag? _toTag(XmlElement element) {
|
|
||||||
String? path;
|
|
||||||
int? id;
|
|
||||||
String? displayName;
|
|
||||||
bool? userVisible;
|
|
||||||
bool? userAssignable;
|
|
||||||
|
|
||||||
for (final child in element.children.whereType<XmlElement>()) {
|
|
||||||
if (child.matchQualifiedName("href",
|
|
||||||
prefix: "DAV:", namespaces: _namespaces)) {
|
|
||||||
path = _hrefToPath(child);
|
|
||||||
} else if (child.matchQualifiedName("propstat",
|
|
||||||
prefix: "DAV:", namespaces: _namespaces)) {
|
|
||||||
final status = child.children
|
|
||||||
.whereType<XmlElement>()
|
|
||||||
.firstWhere((element) => element.matchQualifiedName("status",
|
|
||||||
prefix: "DAV:", namespaces: _namespaces))
|
|
||||||
.innerText;
|
|
||||||
if (!status.contains(" 200 ")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
final prop = child.children.whereType<XmlElement>().firstWhere(
|
|
||||||
(element) => element.matchQualifiedName("prop",
|
|
||||||
prefix: "DAV:", namespaces: _namespaces));
|
|
||||||
final propParser =
|
|
||||||
_TagPropParser(namespaces: _namespaces, logFilePath: path);
|
|
||||||
propParser.parse(prop);
|
|
||||||
id = propParser.id;
|
|
||||||
displayName = propParser.displayName;
|
|
||||||
userVisible = propParser.userVisible;
|
|
||||||
userAssignable = propParser.userAssignable;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (id == null) {
|
|
||||||
// the first returned item is not a valid tag
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Tag(
|
|
||||||
id: id,
|
|
||||||
displayName: displayName!,
|
|
||||||
userVisible: userVisible!,
|
|
||||||
userAssignable: userAssignable!,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Map <DAV:response> contents to TaggedFile
|
|
||||||
TaggedFile _toTaggedFile(XmlElement element) {
|
|
||||||
String? path;
|
|
||||||
int? fileId;
|
|
||||||
|
|
||||||
for (final child in element.children.whereType<XmlElement>()) {
|
|
||||||
if (child.matchQualifiedName("href",
|
|
||||||
prefix: "DAV:", namespaces: _namespaces)) {
|
|
||||||
path = _hrefToPath(child);
|
|
||||||
} else if (child.matchQualifiedName("propstat",
|
|
||||||
prefix: "DAV:", namespaces: _namespaces)) {
|
|
||||||
final status = child.children
|
|
||||||
.whereType<XmlElement>()
|
|
||||||
.firstWhere((element) => element.matchQualifiedName("status",
|
|
||||||
prefix: "DAV:", namespaces: _namespaces))
|
|
||||||
.innerText;
|
|
||||||
if (!status.contains(" 200 ")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
final prop = child.children.whereType<XmlElement>().firstWhere(
|
|
||||||
(element) => element.matchQualifiedName("prop",
|
|
||||||
prefix: "DAV:", namespaces: _namespaces));
|
|
||||||
final propParser =
|
|
||||||
_FileIdPropParser(namespaces: _namespaces, logFilePath: path);
|
|
||||||
propParser.parse(prop);
|
|
||||||
fileId = propParser.fileId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return TaggedFile(
|
|
||||||
fileId: fileId!,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
String _hrefToPath(XmlElement href) {
|
|
||||||
final rawPath = Uri.decodeComponent(href.innerText).trimLeftAny("/");
|
|
||||||
final pos = rawPath.indexOf("remote.php");
|
|
||||||
if (pos == -1) {
|
|
||||||
// what?
|
|
||||||
_log.warning("[_hrefToPath] Unknown href value: $rawPath");
|
|
||||||
return rawPath;
|
|
||||||
} else {
|
|
||||||
return rawPath.substring(pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var _namespaces = <String, String>{};
|
|
||||||
}
|
|
||||||
|
|
||||||
class _FilePropParser {
|
|
||||||
_FilePropParser({
|
|
||||||
this.namespaces = const {},
|
|
||||||
this.logFilePath,
|
|
||||||
});
|
|
||||||
|
|
||||||
/// Parse <DAV:prop> element contents
|
|
||||||
void parse(XmlElement element) {
|
|
||||||
for (final child in element.children.whereType<XmlElement>()) {
|
|
||||||
if (child.matchQualifiedName("getlastmodified",
|
|
||||||
prefix: "DAV:", namespaces: namespaces)) {
|
|
||||||
_lastModified = HttpDate.parse(child.innerText);
|
|
||||||
} else if (child.matchQualifiedName("getcontentlength",
|
|
||||||
prefix: "DAV:", namespaces: namespaces)) {
|
|
||||||
_contentLength = int.parse(child.innerText);
|
|
||||||
} else if (child.matchQualifiedName("getcontenttype",
|
|
||||||
prefix: "DAV:", namespaces: namespaces)) {
|
|
||||||
_contentType = child.innerText;
|
|
||||||
} else if (child.matchQualifiedName("getetag",
|
|
||||||
prefix: "DAV:", namespaces: namespaces)) {
|
|
||||||
_etag = child.innerText.replaceAll("\"", "");
|
|
||||||
} else if (child.matchQualifiedName("quota-used-bytes",
|
|
||||||
prefix: "DAV:", namespaces: namespaces)) {
|
|
||||||
_usedBytes = int.parse(child.innerText);
|
|
||||||
} else if (child.matchQualifiedName("resourcetype",
|
|
||||||
prefix: "DAV:", namespaces: namespaces)) {
|
|
||||||
_isCollection = child.children.whereType<XmlElement>().any((element) =>
|
|
||||||
element.matchQualifiedName("collection",
|
|
||||||
prefix: "DAV:", namespaces: namespaces));
|
|
||||||
} else if (child.matchQualifiedName("has-preview",
|
|
||||||
prefix: "http://nextcloud.org/ns", namespaces: namespaces)) {
|
|
||||||
_hasPreview = child.innerText == "true";
|
|
||||||
} else if (child.matchQualifiedName("fileid",
|
|
||||||
prefix: "http://owncloud.org/ns", namespaces: namespaces)) {
|
|
||||||
_fileId = int.parse(child.innerText);
|
|
||||||
} else if (child.matchQualifiedName("favorite",
|
|
||||||
prefix: "http://owncloud.org/ns", namespaces: namespaces)) {
|
|
||||||
_isFavorite = child.innerText != "0";
|
|
||||||
} else if (child.matchQualifiedName("owner-id",
|
|
||||||
prefix: "http://owncloud.org/ns", namespaces: namespaces)) {
|
|
||||||
_ownerId = child.innerText.toCi();
|
|
||||||
} else if (child.matchQualifiedName("owner-display-name",
|
|
||||||
prefix: "http://owncloud.org/ns", namespaces: namespaces)) {
|
|
||||||
_ownerDisplayName = child.innerText;
|
|
||||||
} else if (child.matchQualifiedName("trashbin-filename",
|
|
||||||
prefix: "http://nextcloud.org/ns", namespaces: namespaces)) {
|
|
||||||
_trashbinFilename = child.innerText;
|
|
||||||
} else if (child.matchQualifiedName("trashbin-original-location",
|
|
||||||
prefix: "http://nextcloud.org/ns", namespaces: namespaces)) {
|
|
||||||
_trashbinOriginalLocation = child.innerText;
|
|
||||||
} else if (child.matchQualifiedName("trashbin-deletion-time",
|
|
||||||
prefix: "http://nextcloud.org/ns", namespaces: namespaces)) {
|
|
||||||
_trashbinDeletionTime = DateTime.fromMillisecondsSinceEpoch(
|
|
||||||
int.parse(child.innerText) * 1000);
|
|
||||||
} else if (child.matchQualifiedName("is-archived",
|
|
||||||
prefix: "com.nkming.nc_photos", namespaces: namespaces)) {
|
|
||||||
_isArchived = child.innerText == "true";
|
|
||||||
} else if (child.matchQualifiedName("override-date-time",
|
|
||||||
prefix: "com.nkming.nc_photos", namespaces: namespaces)) {
|
|
||||||
_overrideDateTime = DateTime.parse(child.innerText);
|
|
||||||
} else if (child.matchQualifiedName("location",
|
|
||||||
prefix: "com.nkming.nc_photos", namespaces: namespaces)) {
|
|
||||||
_location = ImageLocation.fromJson(jsonDecode(child.innerText));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 2nd pass that depends on data in 1st pass
|
|
||||||
for (final child in element.children.whereType<XmlElement>()) {
|
|
||||||
if (child.matchQualifiedName("metadata",
|
|
||||||
prefix: "com.nkming.nc_photos", namespaces: namespaces)) {
|
|
||||||
_metadata = Metadata.fromJson(
|
|
||||||
jsonDecode(child.innerText),
|
|
||||||
upgraderV1: MetadataUpgraderV1(
|
|
||||||
fileContentType: _contentType,
|
|
||||||
logFilePath: logFilePath,
|
|
||||||
),
|
|
||||||
upgraderV2: MetadataUpgraderV2(
|
|
||||||
fileContentType: _contentType,
|
|
||||||
logFilePath: logFilePath,
|
|
||||||
),
|
|
||||||
upgraderV3: MetadataUpgraderV3(
|
|
||||||
fileContentType: _contentType,
|
|
||||||
logFilePath: logFilePath,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DateTime? get lastModified => _lastModified;
|
|
||||||
int? get contentLength => _contentLength;
|
|
||||||
String? get contentType => _contentType;
|
|
||||||
String? get etag => _etag;
|
|
||||||
int? get usedBytes => _usedBytes;
|
|
||||||
bool? get isCollection => _isCollection;
|
|
||||||
bool? get hasPreview => _hasPreview;
|
|
||||||
int? get fileId => _fileId;
|
|
||||||
bool? get isFavorite => _isFavorite;
|
|
||||||
CiString? get ownerId => _ownerId;
|
|
||||||
String? get ownerDisplayName => _ownerDisplayName;
|
|
||||||
Metadata? get metadata => _metadata;
|
|
||||||
bool? get isArchived => _isArchived;
|
|
||||||
DateTime? get overrideDateTime => _overrideDateTime;
|
|
||||||
String? get trashbinFilename => _trashbinFilename;
|
|
||||||
String? get trashbinOriginalLocation => _trashbinOriginalLocation;
|
|
||||||
DateTime? get trashbinDeletionTime => _trashbinDeletionTime;
|
|
||||||
ImageLocation? get location => _location;
|
|
||||||
|
|
||||||
final Map<String, String> namespaces;
|
|
||||||
|
|
||||||
/// File path for logging only
|
|
||||||
final String? logFilePath;
|
|
||||||
|
|
||||||
DateTime? _lastModified;
|
|
||||||
int? _contentLength;
|
|
||||||
String? _contentType;
|
|
||||||
String? _etag;
|
|
||||||
int? _usedBytes;
|
|
||||||
bool? _isCollection;
|
|
||||||
bool? _hasPreview;
|
|
||||||
int? _fileId;
|
|
||||||
bool? _isFavorite;
|
|
||||||
CiString? _ownerId;
|
|
||||||
String? _ownerDisplayName;
|
|
||||||
Metadata? _metadata;
|
|
||||||
bool? _isArchived;
|
|
||||||
DateTime? _overrideDateTime;
|
|
||||||
String? _trashbinFilename;
|
|
||||||
String? _trashbinOriginalLocation;
|
|
||||||
DateTime? _trashbinDeletionTime;
|
|
||||||
ImageLocation? _location;
|
|
||||||
}
|
|
||||||
|
|
||||||
class _FileIdPropParser {
|
|
||||||
_FileIdPropParser({
|
|
||||||
this.namespaces = const {},
|
|
||||||
this.logFilePath,
|
|
||||||
});
|
|
||||||
|
|
||||||
/// Parse <DAV:prop> element contents
|
|
||||||
void parse(XmlElement element) {
|
|
||||||
for (final child in element.children.whereType<XmlElement>()) {
|
|
||||||
if (child.matchQualifiedName("fileid",
|
|
||||||
prefix: "http://owncloud.org/ns", namespaces: namespaces)) {
|
|
||||||
_fileId = int.parse(child.innerText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int? get fileId => _fileId;
|
|
||||||
|
|
||||||
final Map<String, String> namespaces;
|
|
||||||
|
|
||||||
/// File path for logging only
|
|
||||||
final String? logFilePath;
|
|
||||||
|
|
||||||
int? _fileId;
|
|
||||||
}
|
|
||||||
|
|
||||||
class _TagPropParser {
|
|
||||||
_TagPropParser({
|
|
||||||
this.namespaces = const {},
|
|
||||||
this.logFilePath,
|
|
||||||
});
|
|
||||||
|
|
||||||
/// Parse <DAV:prop> element contents
|
|
||||||
void parse(XmlElement element) {
|
|
||||||
for (final child in element.children.whereType<XmlElement>()) {
|
|
||||||
if (child.matchQualifiedName("id",
|
|
||||||
prefix: "http://owncloud.org/ns", namespaces: namespaces)) {
|
|
||||||
_id = int.parse(child.innerText);
|
|
||||||
} else if (child.matchQualifiedName("display-name",
|
|
||||||
prefix: "http://owncloud.org/ns", namespaces: namespaces)) {
|
|
||||||
_displayName = child.innerText;
|
|
||||||
} else if (child.matchQualifiedName("user-visible",
|
|
||||||
prefix: "http://owncloud.org/ns", namespaces: namespaces)) {
|
|
||||||
_userVisible = child.innerText == "true";
|
|
||||||
} else if (child.matchQualifiedName("user-assignable",
|
|
||||||
prefix: "http://owncloud.org/ns", namespaces: namespaces)) {
|
|
||||||
_userAssignable = child.innerText == "true";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int? get id => _id;
|
|
||||||
String? get displayName => _displayName;
|
|
||||||
bool? get userVisible => _userVisible;
|
|
||||||
bool? get userAssignable => _userAssignable;
|
|
||||||
|
|
||||||
final Map<String, String> namespaces;
|
|
||||||
|
|
||||||
/// File path for logging only
|
|
||||||
final String? logFilePath;
|
|
||||||
|
|
||||||
int? _id;
|
|
||||||
String? _displayName;
|
|
||||||
bool? _userVisible;
|
|
||||||
bool? _userAssignable;
|
|
||||||
}
|
|
||||||
|
|
||||||
extension on XmlElement {
|
|
||||||
bool matchQualifiedName(
|
|
||||||
String local, {
|
|
||||||
required String prefix,
|
|
||||||
required Map<String, String> namespaces,
|
|
||||||
}) {
|
|
||||||
final localNamespaces = <String, String>{};
|
|
||||||
for (final a in attributes) {
|
|
||||||
if (a.name.prefix == "xmlns") {
|
|
||||||
localNamespaces[a.name.local] = a.value;
|
|
||||||
} else if (a.name.local == "xmlns") {
|
|
||||||
localNamespaces["!"] = a.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return name.local == local &&
|
|
||||||
(name.prefix == prefix ||
|
|
||||||
// match default namespace
|
|
||||||
(name.prefix == null && namespaces["!"] == prefix) ||
|
|
||||||
// match global namespace
|
|
||||||
namespaces.entries
|
|
||||||
.where((element2) => element2.value == prefix)
|
|
||||||
.any((element) => element.key == name.prefix) ||
|
|
||||||
// match local namespace
|
|
||||||
localNamespaces.entries
|
|
||||||
.where((element2) => element2.value == prefix)
|
|
||||||
.any((element) => element.key == name.prefix));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<File> _parseFilesIsolate(XmlDocument xml) {
|
|
||||||
app_init.initLog();
|
|
||||||
return WebdavResponseParser()._parseFiles(xml);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Favorite> _parseFavoritesIsolate(XmlDocument xml) {
|
|
||||||
app_init.initLog();
|
|
||||||
return WebdavResponseParser()._parseFavorites(xml);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Tag> _parseTagsIsolate(XmlDocument xml) {
|
|
||||||
app_init.initLog();
|
|
||||||
return WebdavResponseParser()._parseTags(xml);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<TaggedFile> _parseTaggedFilesIsolate(XmlDocument xml) {
|
|
||||||
app_init.initLog();
|
|
||||||
return WebdavResponseParser()._parseTaggedFiles(xml);
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
import 'package:nc_photos/api/api.dart';
|
import 'package:np_api/np_api.dart';
|
||||||
|
|
||||||
class CacheNotFoundException implements Exception {
|
class CacheNotFoundException implements Exception {
|
||||||
CacheNotFoundException([this.message]);
|
CacheNotFoundException([this.message]);
|
||||||
|
|
|
@ -4,8 +4,8 @@ import 'package:bloc/bloc.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/api/api.dart';
|
|
||||||
import 'package:nc_photos/exception.dart';
|
import 'package:nc_photos/exception.dart';
|
||||||
|
import 'package:nc_photos/np_api_util.dart';
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
import 'package:to_string/to_string.dart';
|
import 'package:to_string/to_string.dart';
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ class AppPasswordExchangeBloc
|
||||||
|
|
||||||
/// Query the app password for [account]
|
/// Query the app password for [account]
|
||||||
static Future<String> _exchangePassword(Account account) async {
|
static Future<String> _exchangePassword(Account account) async {
|
||||||
final response = await Api(account).request(
|
final response = await ApiUtil.fromAccount(account).request(
|
||||||
"GET",
|
"GET",
|
||||||
"ocs/v2.php/core/getapppassword",
|
"ocs/v2.php/core/getapppassword",
|
||||||
header: {
|
header: {
|
||||||
|
|
|
@ -6,7 +6,6 @@ import 'package:kiwi/kiwi.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/app_localizations.dart';
|
import 'package:nc_photos/app_localizations.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/di_container.dart';
|
import 'package:nc_photos/di_container.dart';
|
||||||
import 'package:nc_photos/entity/file_util.dart' as file_util;
|
import 'package:nc_photos/entity/file_util.dart' as file_util;
|
||||||
import 'package:nc_photos/exception.dart';
|
import 'package:nc_photos/exception.dart';
|
||||||
|
@ -17,10 +16,11 @@ import 'package:nc_photos/legacy/app_password_exchange_bloc.dart';
|
||||||
import 'package:nc_photos/mobile/self_signed_cert_manager.dart';
|
import 'package:nc_photos/mobile/self_signed_cert_manager.dart';
|
||||||
import 'package:nc_photos/platform/features.dart' as features;
|
import 'package:nc_photos/platform/features.dart' as features;
|
||||||
import 'package:nc_photos/snack_bar_manager.dart';
|
import 'package:nc_photos/snack_bar_manager.dart';
|
||||||
import 'package:nc_photos/string_extension.dart';
|
|
||||||
import 'package:nc_photos/url_launcher_util.dart';
|
import 'package:nc_photos/url_launcher_util.dart';
|
||||||
import 'package:nc_photos/use_case/ls_single_file.dart';
|
import 'package:nc_photos/use_case/ls_single_file.dart';
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
|
import 'package:np_common/string_extension.dart';
|
||||||
|
|
||||||
part 'connect.g.dart';
|
part 'connect.g.dart';
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ import 'package:kiwi/kiwi.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/app_localizations.dart';
|
import 'package:nc_photos/app_localizations.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/di_container.dart';
|
import 'package:nc_photos/di_container.dart';
|
||||||
import 'package:nc_photos/entity/sqlite/database.dart' as sql;
|
import 'package:nc_photos/entity/sqlite/database.dart' as sql;
|
||||||
import 'package:nc_photos/help_utils.dart' as help_utils;
|
import 'package:nc_photos/help_utils.dart' as help_utils;
|
||||||
|
@ -14,12 +13,13 @@ import 'package:nc_photos/legacy/connect.dart';
|
||||||
import 'package:nc_photos/platform/k.dart' as platform_k;
|
import 'package:nc_photos/platform/k.dart' as platform_k;
|
||||||
import 'package:nc_photos/pref.dart';
|
import 'package:nc_photos/pref.dart';
|
||||||
import 'package:nc_photos/pref_util.dart' as pref_util;
|
import 'package:nc_photos/pref_util.dart' as pref_util;
|
||||||
import 'package:nc_photos/string_extension.dart';
|
|
||||||
import 'package:nc_photos/theme.dart';
|
import 'package:nc_photos/theme.dart';
|
||||||
import 'package:nc_photos/url_launcher_util.dart';
|
import 'package:nc_photos/url_launcher_util.dart';
|
||||||
import 'package:nc_photos/widget/home.dart';
|
import 'package:nc_photos/widget/home.dart';
|
||||||
import 'package:nc_photos/widget/root_picker.dart';
|
import 'package:nc_photos/widget/root_picker.dart';
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
|
import 'package:np_common/string_extension.dart';
|
||||||
|
|
||||||
part 'sign_in.g.dart';
|
part 'sign_in.g.dart';
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import 'package:nc_photos/ci_string.dart';
|
import 'package:np_common/ci_string.dart';
|
||||||
|
|
||||||
/// Convert a ISO 3166-1 alpha-2 code into country name
|
/// Convert a ISO 3166-1 alpha-2 code into country name
|
||||||
String? alpha2CodeToName(String cc) => _ccMap.byCc(cc);
|
String? alpha2CodeToName(String cc) => _ccMap.byCc(cc);
|
||||||
|
|
|
@ -4,8 +4,8 @@ import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/mobile/android/self_signed_cert.dart';
|
import 'package:nc_photos/mobile/android/self_signed_cert.dart';
|
||||||
import 'package:nc_photos/type.dart';
|
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/type.dart';
|
||||||
import 'package:path/path.dart' as path_lib;
|
import 'package:path/path.dart' as path_lib;
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
|
@ -2,7 +2,7 @@ import 'dart:io';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:nc_photos/platform/universal_storage.dart' as itf;
|
import 'package:nc_photos/platform/universal_storage.dart' as itf;
|
||||||
import 'package:nc_photos/string_extension.dart';
|
import 'package:np_common/string_extension.dart';
|
||||||
import 'package:path/path.dart' as path_lib;
|
import 'package:path/path.dart' as path_lib;
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
|
||||||
|
|
14
app/lib/np_api_util.dart
Normal file
14
app/lib/np_api_util.dart
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import 'package:nc_photos/account.dart';
|
||||||
|
import 'package:np_api/np_api.dart';
|
||||||
|
|
||||||
|
class ApiUtil {
|
||||||
|
static Api fromAccount(Account account) => Api(
|
||||||
|
Uri.parse(account.url),
|
||||||
|
BasicAuth(account.username2, account.password),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class AuthUtil {
|
||||||
|
static BasicAuth fromAccount(Account account) =>
|
||||||
|
BasicAuth(account.username2, account.password);
|
||||||
|
}
|
|
@ -2,8 +2,8 @@ import 'dart:convert';
|
||||||
|
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/entity/exif.dart';
|
import 'package:nc_photos/entity/exif.dart';
|
||||||
import 'package:nc_photos/type.dart';
|
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/type.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
part 'v32.g.dart';
|
part 'v32.g.dart';
|
||||||
|
|
|
@ -3,8 +3,8 @@ import 'dart:convert';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/platform/universal_storage.dart';
|
import 'package:nc_photos/platform/universal_storage.dart';
|
||||||
import 'package:nc_photos/type.dart';
|
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/type.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
part 'v34.g.dart';
|
part 'v34.g.dart';
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/api/api.dart';
|
|
||||||
import 'package:nc_photos/entity/file.dart';
|
import 'package:nc_photos/entity/file.dart';
|
||||||
import 'package:nc_photos/entity/file_descriptor.dart';
|
import 'package:nc_photos/entity/file_descriptor.dart';
|
||||||
import 'package:nc_photos/mobile/platform.dart'
|
import 'package:nc_photos/mobile/platform.dart'
|
||||||
if (dart.library.html) 'package:nc_photos/web/platform.dart' as platform;
|
if (dart.library.html) 'package:nc_photos/web/platform.dart' as platform;
|
||||||
|
import 'package:nc_photos/np_api_util.dart';
|
||||||
import 'package:nc_photos/platform/download.dart';
|
import 'package:nc_photos/platform/download.dart';
|
||||||
|
|
||||||
class DownloadFile {
|
class DownloadFile {
|
||||||
|
@ -18,7 +18,7 @@ class DownloadFile {
|
||||||
return platform.DownloadBuilder().build(
|
return platform.DownloadBuilder().build(
|
||||||
url: url,
|
url: url,
|
||||||
headers: {
|
headers: {
|
||||||
"authorization": Api.getAuthorizationHeaderValue(account),
|
"authorization": AuthUtil.fromAccount(account).toHeaderValue(),
|
||||||
},
|
},
|
||||||
mimeType: file.contentType,
|
mimeType: file.contentType,
|
||||||
filename: file.filename,
|
filename: file.filename,
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/api/api.dart';
|
|
||||||
import 'package:nc_photos/api/api_util.dart' as api_util;
|
import 'package:nc_photos/api/api_util.dart' as api_util;
|
||||||
import 'package:nc_photos/cache_manager_util.dart';
|
import 'package:nc_photos/cache_manager_util.dart';
|
||||||
import 'package:nc_photos/entity/file.dart';
|
import 'package:nc_photos/entity/file.dart';
|
||||||
import 'package:nc_photos/k.dart' as k;
|
import 'package:nc_photos/k.dart' as k;
|
||||||
|
import 'package:nc_photos/np_api_util.dart';
|
||||||
import 'package:nc_photos/platform/k.dart' as platform_k;
|
import 'package:nc_photos/platform/k.dart' as platform_k;
|
||||||
import 'package:nc_photos_plugin/nc_photos_plugin.dart';
|
import 'package:nc_photos_plugin/nc_photos_plugin.dart';
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ class DownloadPreview {
|
||||||
);
|
);
|
||||||
final fileInfo =
|
final fileInfo =
|
||||||
await LargeImageCacheManager.inst.getSingleFile(previewUrl, headers: {
|
await LargeImageCacheManager.inst.getSingleFile(previewUrl, headers: {
|
||||||
"authorization": Api.getAuthorizationHeaderValue(account),
|
"authorization": AuthUtil.fromAccount(account).toHeaderValue(),
|
||||||
});
|
});
|
||||||
return ContentUri.getUriForFile(fileInfo.absolute.path);
|
return ContentUri.getUriForFile(fileInfo.absolute.path);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/entity/file.dart';
|
import 'package:nc_photos/entity/file.dart';
|
||||||
import 'package:nc_photos/string_extension.dart';
|
import 'package:np_common/string_extension.dart';
|
||||||
|
|
||||||
class Ls {
|
class Ls {
|
||||||
Ls(this.fileRepo);
|
Ls(this.fileRepo);
|
||||||
|
|
|
@ -2,7 +2,6 @@ import 'package:event_bus/event_bus.dart';
|
||||||
import 'package:kiwi/kiwi.dart';
|
import 'package:kiwi/kiwi.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/debug_util.dart';
|
import 'package:nc_photos/debug_util.dart';
|
||||||
import 'package:nc_photos/di_container.dart';
|
import 'package:nc_photos/di_container.dart';
|
||||||
import 'package:nc_photos/entity/album.dart';
|
import 'package:nc_photos/entity/album.dart';
|
||||||
|
@ -18,6 +17,7 @@ import 'package:nc_photos/use_case/list_share.dart';
|
||||||
import 'package:nc_photos/use_case/remove_from_album.dart';
|
import 'package:nc_photos/use_case/remove_from_album.dart';
|
||||||
import 'package:nc_photos/use_case/remove_share.dart';
|
import 'package:nc_photos/use_case/remove_share.dart';
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
|
|
||||||
part 'remove.g.dart';
|
part 'remove.g.dart';
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,11 @@ import 'dart:convert';
|
||||||
|
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/api/api.dart';
|
|
||||||
import 'package:nc_photos/entity/file_descriptor.dart';
|
import 'package:nc_photos/entity/file_descriptor.dart';
|
||||||
import 'package:nc_photos/exception.dart';
|
import 'package:nc_photos/exception.dart';
|
||||||
import 'package:nc_photos/type.dart';
|
import 'package:nc_photos/np_api_util.dart';
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/type.dart';
|
||||||
|
|
||||||
part 'request_public_link.g.dart';
|
part 'request_public_link.g.dart';
|
||||||
|
|
||||||
|
@ -14,8 +14,11 @@ part 'request_public_link.g.dart';
|
||||||
class RequestPublicLink {
|
class RequestPublicLink {
|
||||||
/// Request a temporary unique public link to [file]
|
/// Request a temporary unique public link to [file]
|
||||||
Future<String> call(Account account, FileDescriptor file) async {
|
Future<String> call(Account account, FileDescriptor file) async {
|
||||||
final response =
|
final response = await ApiUtil.fromAccount(account)
|
||||||
await Api(account).ocs().dav().direct().post(fileId: file.fdId);
|
.ocs()
|
||||||
|
.dav()
|
||||||
|
.direct()
|
||||||
|
.post(fileId: file.fdId);
|
||||||
if (!response.isGood) {
|
if (!response.isGood) {
|
||||||
_log.severe("[call] Failed requesting server: $response");
|
_log.severe("[call] Failed requesting server: $response");
|
||||||
throw ApiException(
|
throw ApiException(
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/debug_util.dart';
|
import 'package:nc_photos/debug_util.dart';
|
||||||
import 'package:nc_photos/entity/album.dart';
|
import 'package:nc_photos/entity/album.dart';
|
||||||
import 'package:nc_photos/entity/album/item.dart';
|
import 'package:nc_photos/entity/album/item.dart';
|
||||||
|
@ -13,6 +12,7 @@ import 'package:nc_photos/or_null.dart';
|
||||||
import 'package:nc_photos/use_case/create_share.dart';
|
import 'package:nc_photos/use_case/create_share.dart';
|
||||||
import 'package:nc_photos/use_case/update_album.dart';
|
import 'package:nc_photos/use_case/update_album.dart';
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
|
|
||||||
part 'share_album_with_user.g.dart';
|
part 'share_album_with_user.g.dart';
|
||||||
|
|
||||||
|
|
|
@ -9,11 +9,11 @@ import 'package:nc_photos/app_init.dart' as app_init;
|
||||||
import 'package:nc_photos/di_container.dart';
|
import 'package:nc_photos/di_container.dart';
|
||||||
import 'package:nc_photos/event/event.dart';
|
import 'package:nc_photos/event/event.dart';
|
||||||
import 'package:nc_photos/platform/k.dart' as platform_k;
|
import 'package:nc_photos/platform/k.dart' as platform_k;
|
||||||
import 'package:nc_photos/type.dart';
|
|
||||||
import 'package:nc_photos/use_case/sync_favorite.dart';
|
import 'package:nc_photos/use_case/sync_favorite.dart';
|
||||||
import 'package:nc_photos/use_case/sync_person.dart';
|
import 'package:nc_photos/use_case/sync_person.dart';
|
||||||
import 'package:nc_photos/use_case/sync_tag.dart';
|
import 'package:nc_photos/use_case/sync_tag.dart';
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/type.dart';
|
||||||
|
|
||||||
part 'startup_sync.g.dart';
|
part 'startup_sync.g.dart';
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/debug_util.dart';
|
import 'package:nc_photos/debug_util.dart';
|
||||||
import 'package:nc_photos/di_container.dart';
|
import 'package:nc_photos/di_container.dart';
|
||||||
import 'package:nc_photos/entity/album.dart';
|
import 'package:nc_photos/entity/album.dart';
|
||||||
|
@ -13,6 +12,7 @@ import 'package:nc_photos/use_case/remove_share.dart';
|
||||||
import 'package:nc_photos/use_case/unshare_file_from_album.dart';
|
import 'package:nc_photos/use_case/unshare_file_from_album.dart';
|
||||||
import 'package:nc_photos/use_case/update_album.dart';
|
import 'package:nc_photos/use_case/update_album.dart';
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
|
|
||||||
part 'unshare_album_with_user.g.dart';
|
part 'unshare_album_with_user.g.dart';
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/debug_util.dart';
|
import 'package:nc_photos/debug_util.dart';
|
||||||
import 'package:nc_photos/di_container.dart';
|
import 'package:nc_photos/di_container.dart';
|
||||||
import 'package:nc_photos/entity/album.dart';
|
import 'package:nc_photos/entity/album.dart';
|
||||||
|
@ -14,6 +13,7 @@ import 'package:nc_photos/use_case/list_album.dart';
|
||||||
import 'package:nc_photos/use_case/list_share.dart';
|
import 'package:nc_photos/use_case/list_share.dart';
|
||||||
import 'package:nc_photos/use_case/remove_share.dart';
|
import 'package:nc_photos/use_case/remove_share.dart';
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
|
|
||||||
part 'unshare_file_from_album.g.dart';
|
part 'unshare_file_from_album.g.dart';
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,10 @@ import 'package:cached_network_image/cached_network_image.dart';
|
||||||
import 'package:cached_network_image_platform_interface/cached_network_image_platform_interface.dart';
|
import 'package:cached_network_image_platform_interface/cached_network_image_platform_interface.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/api/api.dart';
|
|
||||||
import 'package:nc_photos/app_localizations.dart';
|
import 'package:nc_photos/app_localizations.dart';
|
||||||
import 'package:nc_photos/cache_manager_util.dart';
|
import 'package:nc_photos/cache_manager_util.dart';
|
||||||
import 'package:nc_photos/entity/album.dart';
|
import 'package:nc_photos/entity/album.dart';
|
||||||
|
import 'package:nc_photos/np_api_util.dart';
|
||||||
|
|
||||||
class AlbumBrowserAppBar extends StatelessWidget {
|
class AlbumBrowserAppBar extends StatelessWidget {
|
||||||
const AlbumBrowserAppBar({
|
const AlbumBrowserAppBar({
|
||||||
|
@ -124,7 +124,7 @@ Widget? _getAppBarCover(
|
||||||
cacheManager: CoverCacheManager.inst,
|
cacheManager: CoverCacheManager.inst,
|
||||||
imageUrl: coverPreviewUrl,
|
imageUrl: coverPreviewUrl,
|
||||||
httpHeaders: {
|
httpHeaders: {
|
||||||
"Authorization": Api.getAuthorizationHeaderValue(account),
|
"Authorization": AuthUtil.fromAccount(account).toHeaderValue(),
|
||||||
},
|
},
|
||||||
filterQuality: FilterQuality.high,
|
filterQuality: FilterQuality.high,
|
||||||
errorWidget: (context, url, error) {
|
errorWidget: (context, url, error) {
|
||||||
|
|
|
@ -5,7 +5,6 @@ import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/app_localizations.dart';
|
import 'package:nc_photos/app_localizations.dart';
|
||||||
import 'package:nc_photos/bloc/list_album_share_outlier.dart';
|
import 'package:nc_photos/bloc/list_album_share_outlier.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/di_container.dart';
|
import 'package:nc_photos/di_container.dart';
|
||||||
import 'package:nc_photos/entity/album.dart';
|
import 'package:nc_photos/entity/album.dart';
|
||||||
import 'package:nc_photos/entity/file.dart';
|
import 'package:nc_photos/entity/file.dart';
|
||||||
|
@ -16,13 +15,14 @@ import 'package:nc_photos/entity/share/data_source.dart';
|
||||||
import 'package:nc_photos/exception_util.dart' as exception_util;
|
import 'package:nc_photos/exception_util.dart' as exception_util;
|
||||||
import 'package:nc_photos/k.dart' as k;
|
import 'package:nc_photos/k.dart' as k;
|
||||||
import 'package:nc_photos/snack_bar_manager.dart';
|
import 'package:nc_photos/snack_bar_manager.dart';
|
||||||
import 'package:nc_photos/string_extension.dart';
|
|
||||||
import 'package:nc_photos/use_case/create_share.dart';
|
import 'package:nc_photos/use_case/create_share.dart';
|
||||||
import 'package:nc_photos/use_case/remove_share.dart';
|
import 'package:nc_photos/use_case/remove_share.dart';
|
||||||
import 'package:nc_photos/widget/empty_list_indicator.dart';
|
import 'package:nc_photos/widget/empty_list_indicator.dart';
|
||||||
import 'package:nc_photos/widget/network_thumbnail.dart';
|
import 'package:nc_photos/widget/network_thumbnail.dart';
|
||||||
import 'package:nc_photos/widget/unbounded_list_tile.dart';
|
import 'package:nc_photos/widget/unbounded_list_tile.dart';
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
|
import 'package:np_common/string_extension.dart';
|
||||||
|
|
||||||
part 'album_share_outlier_browser.g.dart';
|
part 'album_share_outlier_browser.g.dart';
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ import 'package:cached_network_image/cached_network_image.dart';
|
||||||
import 'package:cached_network_image_platform_interface/cached_network_image_platform_interface.dart';
|
import 'package:cached_network_image_platform_interface/cached_network_image_platform_interface.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/api/api.dart';
|
|
||||||
import 'package:nc_photos/api/api_util.dart' as api_util;
|
import 'package:nc_photos/api/api_util.dart' as api_util;
|
||||||
import 'package:nc_photos/app_localizations.dart';
|
import 'package:nc_photos/app_localizations.dart';
|
||||||
import 'package:nc_photos/cache_manager_util.dart';
|
import 'package:nc_photos/cache_manager_util.dart';
|
||||||
|
@ -10,6 +9,7 @@ import 'package:nc_photos/entity/album.dart';
|
||||||
import 'package:nc_photos/entity/album/provider.dart';
|
import 'package:nc_photos/entity/album/provider.dart';
|
||||||
import 'package:nc_photos/entity/file_descriptor.dart';
|
import 'package:nc_photos/entity/file_descriptor.dart';
|
||||||
import 'package:nc_photos/k.dart' as k;
|
import 'package:nc_photos/k.dart' as k;
|
||||||
|
import 'package:nc_photos/np_api_util.dart';
|
||||||
import 'package:nc_photos/theme.dart';
|
import 'package:nc_photos/theme.dart';
|
||||||
import 'package:nc_photos/widget/album_grid_item.dart';
|
import 'package:nc_photos/widget/album_grid_item.dart';
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ class AlbumGridItemBuilder {
|
||||||
cacheManager: CoverCacheManager.inst,
|
cacheManager: CoverCacheManager.inst,
|
||||||
imageUrl: previewUrl,
|
imageUrl: previewUrl,
|
||||||
httpHeaders: {
|
httpHeaders: {
|
||||||
"Authorization": Api.getAuthorizationHeaderValue(account),
|
"Authorization": AuthUtil.fromAccount(account).toHeaderValue(),
|
||||||
},
|
},
|
||||||
fadeInDuration: const Duration(),
|
fadeInDuration: const Duration(),
|
||||||
filterQuality: FilterQuality.high,
|
filterQuality: FilterQuality.high,
|
||||||
|
|
|
@ -7,7 +7,6 @@ import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/app_localizations.dart';
|
import 'package:nc_photos/app_localizations.dart';
|
||||||
import 'package:nc_photos/bloc/app_password_exchange.dart';
|
import 'package:nc_photos/bloc/app_password_exchange.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/di_container.dart';
|
import 'package:nc_photos/di_container.dart';
|
||||||
import 'package:nc_photos/entity/file_util.dart' as file_util;
|
import 'package:nc_photos/entity/file_util.dart' as file_util;
|
||||||
import 'package:nc_photos/exception.dart';
|
import 'package:nc_photos/exception.dart';
|
||||||
|
@ -17,12 +16,13 @@ import 'package:nc_photos/k.dart' as k;
|
||||||
import 'package:nc_photos/mobile/self_signed_cert_manager.dart';
|
import 'package:nc_photos/mobile/self_signed_cert_manager.dart';
|
||||||
import 'package:nc_photos/platform/features.dart' as features;
|
import 'package:nc_photos/platform/features.dart' as features;
|
||||||
import 'package:nc_photos/snack_bar_manager.dart';
|
import 'package:nc_photos/snack_bar_manager.dart';
|
||||||
import 'package:nc_photos/string_extension.dart';
|
|
||||||
import 'package:nc_photos/theme.dart';
|
import 'package:nc_photos/theme.dart';
|
||||||
import 'package:nc_photos/url_launcher_util.dart';
|
import 'package:nc_photos/url_launcher_util.dart';
|
||||||
import 'package:nc_photos/use_case/ls_single_file.dart';
|
import 'package:nc_photos/use_case/ls_single_file.dart';
|
||||||
import 'package:nc_photos/widget/cloud_progress_indicator.dart';
|
import 'package:nc_photos/widget/cloud_progress_indicator.dart';
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
|
import 'package:np_common/string_extension.dart';
|
||||||
|
|
||||||
part 'connect.g.dart';
|
part 'connect.g.dart';
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/bloc/home_search_suggestion.dart';
|
import 'package:nc_photos/bloc/home_search_suggestion.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/entity/album.dart';
|
import 'package:nc_photos/entity/album.dart';
|
||||||
import 'package:nc_photos/entity/person.dart';
|
import 'package:nc_photos/entity/person.dart';
|
||||||
import 'package:nc_photos/entity/tag.dart';
|
import 'package:nc_photos/entity/tag.dart';
|
||||||
|
@ -18,6 +17,7 @@ import 'package:nc_photos/widget/person_browser.dart';
|
||||||
import 'package:nc_photos/widget/place_browser.dart';
|
import 'package:nc_photos/widget/place_browser.dart';
|
||||||
import 'package:nc_photos/widget/tag_browser.dart';
|
import 'package:nc_photos/widget/tag_browser.dart';
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
|
|
||||||
part 'home_search_suggestion.g.dart';
|
part 'home_search_suggestion.g.dart';
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ import 'package:collection/collection.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:kiwi/kiwi.dart';
|
import 'package:kiwi/kiwi.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/api/api.dart';
|
|
||||||
import 'package:nc_photos/api/api_util.dart' as api_util;
|
import 'package:nc_photos/api/api_util.dart' as api_util;
|
||||||
import 'package:nc_photos/app_localizations.dart';
|
import 'package:nc_photos/app_localizations.dart';
|
||||||
import 'package:nc_photos/cache_manager_util.dart';
|
import 'package:nc_photos/cache_manager_util.dart';
|
||||||
|
@ -13,6 +12,7 @@ import 'package:nc_photos/entity/file_descriptor.dart';
|
||||||
import 'package:nc_photos/help_utils.dart' as help_util;
|
import 'package:nc_photos/help_utils.dart' as help_util;
|
||||||
import 'package:nc_photos/k.dart' as k;
|
import 'package:nc_photos/k.dart' as k;
|
||||||
import 'package:nc_photos/material3.dart';
|
import 'package:nc_photos/material3.dart';
|
||||||
|
import 'package:nc_photos/np_api_util.dart';
|
||||||
import 'package:nc_photos/object_extension.dart';
|
import 'package:nc_photos/object_extension.dart';
|
||||||
import 'package:nc_photos/pixel_image_provider.dart';
|
import 'package:nc_photos/pixel_image_provider.dart';
|
||||||
import 'package:nc_photos/theme.dart';
|
import 'package:nc_photos/theme.dart';
|
||||||
|
@ -282,7 +282,7 @@ class _ImageEditorState extends State<ImageEditor> {
|
||||||
3072,
|
3072,
|
||||||
_buildFilterList(),
|
_buildFilterList(),
|
||||||
headers: {
|
headers: {
|
||||||
"Authorization": Api.getAuthorizationHeaderValue(widget.account),
|
"Authorization": AuthUtil.fromAccount(widget.account).toHeaderValue(),
|
||||||
},
|
},
|
||||||
isSaveToServer: c.pref.isSaveEditResultToServerOr(),
|
isSaveToServer: c.pref.isSaveEditResultToServerOr(),
|
||||||
);
|
);
|
||||||
|
|
|
@ -8,7 +8,6 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:kiwi/kiwi.dart';
|
import 'package:kiwi/kiwi.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/api/api.dart';
|
|
||||||
import 'package:nc_photos/app_localizations.dart';
|
import 'package:nc_photos/app_localizations.dart';
|
||||||
import 'package:nc_photos/di_container.dart';
|
import 'package:nc_photos/di_container.dart';
|
||||||
import 'package:nc_photos/entity/file_descriptor.dart';
|
import 'package:nc_photos/entity/file_descriptor.dart';
|
||||||
|
@ -18,6 +17,7 @@ import 'package:nc_photos/k.dart' as k;
|
||||||
import 'package:nc_photos/mobile/android/android_info.dart';
|
import 'package:nc_photos/mobile/android/android_info.dart';
|
||||||
import 'package:nc_photos/mobile/android/content_uri_image_provider.dart';
|
import 'package:nc_photos/mobile/android/content_uri_image_provider.dart';
|
||||||
import 'package:nc_photos/mobile/android/k.dart' as android;
|
import 'package:nc_photos/mobile/android/k.dart' as android;
|
||||||
|
import 'package:nc_photos/np_api_util.dart';
|
||||||
import 'package:nc_photos/object_extension.dart';
|
import 'package:nc_photos/object_extension.dart';
|
||||||
import 'package:nc_photos/platform/k.dart' as platform_k;
|
import 'package:nc_photos/platform/k.dart' as platform_k;
|
||||||
import 'package:nc_photos/snack_bar_manager.dart';
|
import 'package:nc_photos/snack_bar_manager.dart';
|
||||||
|
@ -191,7 +191,8 @@ class _ImageEnhancerState extends State<ImageEnhancer> {
|
||||||
_c.pref.getEnhanceMaxHeightOr(),
|
_c.pref.getEnhanceMaxHeightOr(),
|
||||||
args["iteration"] ?? 8,
|
args["iteration"] ?? 8,
|
||||||
headers: {
|
headers: {
|
||||||
"Authorization": Api.getAuthorizationHeaderValue(widget.account),
|
"Authorization":
|
||||||
|
AuthUtil.fromAccount(widget.account).toHeaderValue(),
|
||||||
},
|
},
|
||||||
isSaveToServer: widget.isSaveToServer,
|
isSaveToServer: widget.isSaveToServer,
|
||||||
);
|
);
|
||||||
|
@ -205,7 +206,8 @@ class _ImageEnhancerState extends State<ImageEnhancer> {
|
||||||
_c.pref.getEnhanceMaxHeightOr(),
|
_c.pref.getEnhanceMaxHeightOr(),
|
||||||
args["radius"] ?? 16,
|
args["radius"] ?? 16,
|
||||||
headers: {
|
headers: {
|
||||||
"Authorization": Api.getAuthorizationHeaderValue(widget.account),
|
"Authorization":
|
||||||
|
AuthUtil.fromAccount(widget.account).toHeaderValue(),
|
||||||
},
|
},
|
||||||
isSaveToServer: widget.isSaveToServer,
|
isSaveToServer: widget.isSaveToServer,
|
||||||
);
|
);
|
||||||
|
@ -218,7 +220,8 @@ class _ImageEnhancerState extends State<ImageEnhancer> {
|
||||||
_c.pref.getEnhanceMaxWidthOr(),
|
_c.pref.getEnhanceMaxWidthOr(),
|
||||||
_c.pref.getEnhanceMaxHeightOr(),
|
_c.pref.getEnhanceMaxHeightOr(),
|
||||||
headers: {
|
headers: {
|
||||||
"Authorization": Api.getAuthorizationHeaderValue(widget.account),
|
"Authorization":
|
||||||
|
AuthUtil.fromAccount(widget.account).toHeaderValue(),
|
||||||
},
|
},
|
||||||
isSaveToServer: widget.isSaveToServer,
|
isSaveToServer: widget.isSaveToServer,
|
||||||
);
|
);
|
||||||
|
@ -235,7 +238,8 @@ class _ImageEnhancerState extends State<ImageEnhancer> {
|
||||||
args["styleUri"],
|
args["styleUri"],
|
||||||
args["weight"],
|
args["weight"],
|
||||||
headers: {
|
headers: {
|
||||||
"Authorization": Api.getAuthorizationHeaderValue(widget.account),
|
"Authorization":
|
||||||
|
AuthUtil.fromAccount(widget.account).toHeaderValue(),
|
||||||
},
|
},
|
||||||
isSaveToServer: widget.isSaveToServer,
|
isSaveToServer: widget.isSaveToServer,
|
||||||
);
|
);
|
||||||
|
@ -249,7 +253,8 @@ class _ImageEnhancerState extends State<ImageEnhancer> {
|
||||||
_c.pref.getEnhanceMaxHeightOr(),
|
_c.pref.getEnhanceMaxHeightOr(),
|
||||||
args["weight"],
|
args["weight"],
|
||||||
headers: {
|
headers: {
|
||||||
"Authorization": Api.getAuthorizationHeaderValue(widget.account),
|
"Authorization":
|
||||||
|
AuthUtil.fromAccount(widget.account).toHeaderValue(),
|
||||||
},
|
},
|
||||||
isSaveToServer: widget.isSaveToServer,
|
isSaveToServer: widget.isSaveToServer,
|
||||||
);
|
);
|
||||||
|
@ -262,7 +267,8 @@ class _ImageEnhancerState extends State<ImageEnhancer> {
|
||||||
_c.pref.getEnhanceMaxWidthOr(),
|
_c.pref.getEnhanceMaxWidthOr(),
|
||||||
_c.pref.getEnhanceMaxHeightOr(),
|
_c.pref.getEnhanceMaxHeightOr(),
|
||||||
headers: {
|
headers: {
|
||||||
"Authorization": Api.getAuthorizationHeaderValue(widget.account),
|
"Authorization":
|
||||||
|
AuthUtil.fromAccount(widget.account).toHeaderValue(),
|
||||||
},
|
},
|
||||||
isSaveToServer: widget.isSaveToServer,
|
isSaveToServer: widget.isSaveToServer,
|
||||||
);
|
);
|
||||||
|
|
|
@ -4,7 +4,6 @@ import 'package:flutter/gestures.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/api/api.dart';
|
|
||||||
import 'package:nc_photos/api/api_util.dart' as api_util;
|
import 'package:nc_photos/api/api_util.dart' as api_util;
|
||||||
import 'package:nc_photos/cache_manager_util.dart';
|
import 'package:nc_photos/cache_manager_util.dart';
|
||||||
import 'package:nc_photos/entity/file_descriptor.dart';
|
import 'package:nc_photos/entity/file_descriptor.dart';
|
||||||
|
@ -12,6 +11,7 @@ import 'package:nc_photos/entity/local_file.dart';
|
||||||
import 'package:nc_photos/flutter_util.dart' as flutter_util;
|
import 'package:nc_photos/flutter_util.dart' as flutter_util;
|
||||||
import 'package:nc_photos/k.dart' as k;
|
import 'package:nc_photos/k.dart' as k;
|
||||||
import 'package:nc_photos/mobile/android/content_uri_image_provider.dart';
|
import 'package:nc_photos/mobile/android/content_uri_image_provider.dart';
|
||||||
|
import 'package:nc_photos/np_api_util.dart';
|
||||||
import 'package:nc_photos/widget/cached_network_image_mod.dart' as mod;
|
import 'package:nc_photos/widget/cached_network_image_mod.dart' as mod;
|
||||||
import 'package:nc_photos/widget/network_thumbnail.dart';
|
import 'package:nc_photos/widget/network_thumbnail.dart';
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
@ -99,7 +99,7 @@ class RemoteImageViewer extends StatefulWidget {
|
||||||
LargeImageCacheManager.inst.getFileStream(
|
LargeImageCacheManager.inst.getFileStream(
|
||||||
_getImageUrl(account, file),
|
_getImageUrl(account, file),
|
||||||
headers: {
|
headers: {
|
||||||
"Authorization": Api.getAuthorizationHeaderValue(account),
|
"Authorization": AuthUtil.fromAccount(account).toHeaderValue(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -157,7 +157,7 @@ class _RemoteImageViewerState extends State<RemoteImageViewer> {
|
||||||
widget.account, widget.file),
|
widget.account, widget.file),
|
||||||
httpHeaders: {
|
httpHeaders: {
|
||||||
"Authorization":
|
"Authorization":
|
||||||
Api.getAuthorizationHeaderValue(widget.account),
|
AuthUtil.fromAccount(widget.account).toHeaderValue(),
|
||||||
},
|
},
|
||||||
fadeInDuration: const Duration(),
|
fadeInDuration: const Duration(),
|
||||||
filterQuality: FilterQuality.high,
|
filterQuality: FilterQuality.high,
|
||||||
|
@ -170,7 +170,7 @@ class _RemoteImageViewerState extends State<RemoteImageViewer> {
|
||||||
imageUrl: _getImageUrl(widget.account, widget.file),
|
imageUrl: _getImageUrl(widget.account, widget.file),
|
||||||
httpHeaders: {
|
httpHeaders: {
|
||||||
"Authorization":
|
"Authorization":
|
||||||
Api.getAuthorizationHeaderValue(widget.account),
|
AuthUtil.fromAccount(widget.account).toHeaderValue(),
|
||||||
},
|
},
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
fadeInDuration: const Duration(),
|
fadeInDuration: const Duration(),
|
||||||
|
|
|
@ -2,11 +2,11 @@ import 'package:cached_network_image/cached_network_image.dart';
|
||||||
import 'package:cached_network_image_platform_interface/cached_network_image_platform_interface.dart';
|
import 'package:cached_network_image_platform_interface/cached_network_image_platform_interface.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/api/api.dart';
|
|
||||||
import 'package:nc_photos/api/api_util.dart' as api_util;
|
import 'package:nc_photos/api/api_util.dart' as api_util;
|
||||||
import 'package:nc_photos/cache_manager_util.dart';
|
import 'package:nc_photos/cache_manager_util.dart';
|
||||||
import 'package:nc_photos/entity/file_descriptor.dart';
|
import 'package:nc_photos/entity/file_descriptor.dart';
|
||||||
import 'package:nc_photos/k.dart' as k;
|
import 'package:nc_photos/k.dart' as k;
|
||||||
|
import 'package:nc_photos/np_api_util.dart';
|
||||||
|
|
||||||
/// A square thumbnail widget for a file
|
/// A square thumbnail widget for a file
|
||||||
class NetworkRectThumbnail extends StatelessWidget {
|
class NetworkRectThumbnail extends StatelessWidget {
|
||||||
|
@ -46,7 +46,7 @@ class NetworkRectThumbnail extends StatelessWidget {
|
||||||
imageUrl: imageUrl,
|
imageUrl: imageUrl,
|
||||||
// imageUrl: "",
|
// imageUrl: "",
|
||||||
httpHeaders: {
|
httpHeaders: {
|
||||||
"Authorization": Api.getAuthorizationHeaderValue(account),
|
"Authorization": AuthUtil.fromAccount(account).toHeaderValue(),
|
||||||
},
|
},
|
||||||
fadeInDuration: const Duration(),
|
fadeInDuration: const Duration(),
|
||||||
filterQuality: FilterQuality.high,
|
filterQuality: FilterQuality.high,
|
||||||
|
|
|
@ -9,7 +9,6 @@ import 'package:nc_photos/app_localizations.dart';
|
||||||
import 'package:nc_photos/async_util.dart' as async_util;
|
import 'package:nc_photos/async_util.dart' as async_util;
|
||||||
import 'package:nc_photos/bloc/list_sharee.dart';
|
import 'package:nc_photos/bloc/list_sharee.dart';
|
||||||
import 'package:nc_photos/bloc/search_suggestion.dart';
|
import 'package:nc_photos/bloc/search_suggestion.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/di_container.dart';
|
import 'package:nc_photos/di_container.dart';
|
||||||
import 'package:nc_photos/entity/album.dart';
|
import 'package:nc_photos/entity/album.dart';
|
||||||
import 'package:nc_photos/entity/sharee.dart';
|
import 'package:nc_photos/entity/sharee.dart';
|
||||||
|
@ -21,6 +20,7 @@ import 'package:nc_photos/use_case/unshare_album_with_user.dart';
|
||||||
import 'package:nc_photos/widget/album_share_outlier_browser.dart';
|
import 'package:nc_photos/widget/album_share_outlier_browser.dart';
|
||||||
import 'package:nc_photos/widget/dialog_scaffold.dart';
|
import 'package:nc_photos/widget/dialog_scaffold.dart';
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
|
|
||||||
part 'share_album_dialog.g.dart';
|
part 'share_album_dialog.g.dart';
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ import 'package:intl/intl.dart';
|
||||||
import 'package:kiwi/kiwi.dart';
|
import 'package:kiwi/kiwi.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/api/api.dart';
|
|
||||||
import 'package:nc_photos/api/api_util.dart' as api_util;
|
import 'package:nc_photos/api/api_util.dart' as api_util;
|
||||||
import 'package:nc_photos/app_localizations.dart';
|
import 'package:nc_photos/app_localizations.dart';
|
||||||
import 'package:nc_photos/cache_manager_util.dart';
|
import 'package:nc_photos/cache_manager_util.dart';
|
||||||
|
@ -17,6 +16,7 @@ import 'package:nc_photos/entity/share.dart';
|
||||||
import 'package:nc_photos/entity/share/data_source.dart';
|
import 'package:nc_photos/entity/share/data_source.dart';
|
||||||
import 'package:nc_photos/exception_util.dart' as exception_util;
|
import 'package:nc_photos/exception_util.dart' as exception_util;
|
||||||
import 'package:nc_photos/k.dart' as k;
|
import 'package:nc_photos/k.dart' as k;
|
||||||
|
import 'package:nc_photos/np_api_util.dart';
|
||||||
import 'package:nc_photos/remote_storage_util.dart' as remote_storage_util;
|
import 'package:nc_photos/remote_storage_util.dart' as remote_storage_util;
|
||||||
import 'package:nc_photos/snack_bar_manager.dart';
|
import 'package:nc_photos/snack_bar_manager.dart';
|
||||||
import 'package:nc_photos/use_case/remove.dart';
|
import 'package:nc_photos/use_case/remove.dart';
|
||||||
|
@ -102,7 +102,7 @@ class _SharedFileViewerState extends State<SharedFileViewer> {
|
||||||
imageUrl: previewUrl,
|
imageUrl: previewUrl,
|
||||||
httpHeaders: {
|
httpHeaders: {
|
||||||
"Authorization":
|
"Authorization":
|
||||||
Api.getAuthorizationHeaderValue(widget.account),
|
AuthUtil.fromAccount(widget.account).toHeaderValue(),
|
||||||
},
|
},
|
||||||
fadeInDuration: const Duration(),
|
fadeInDuration: const Duration(),
|
||||||
filterQuality: FilterQuality.high,
|
filterQuality: FilterQuality.high,
|
||||||
|
|
|
@ -12,12 +12,12 @@ import 'package:nc_photos/iterable_extension.dart';
|
||||||
import 'package:nc_photos/legacy/sign_in.dart' as legacy;
|
import 'package:nc_photos/legacy/sign_in.dart' as legacy;
|
||||||
import 'package:nc_photos/pref.dart';
|
import 'package:nc_photos/pref.dart';
|
||||||
import 'package:nc_photos/pref_util.dart' as pref_util;
|
import 'package:nc_photos/pref_util.dart' as pref_util;
|
||||||
import 'package:nc_photos/string_extension.dart';
|
|
||||||
import 'package:nc_photos/theme.dart';
|
import 'package:nc_photos/theme.dart';
|
||||||
import 'package:nc_photos/widget/connect.dart';
|
import 'package:nc_photos/widget/connect.dart';
|
||||||
import 'package:nc_photos/widget/home.dart';
|
import 'package:nc_photos/widget/home.dart';
|
||||||
import 'package:nc_photos/widget/root_picker.dart';
|
import 'package:nc_photos/widget/root_picker.dart';
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/string_extension.dart';
|
||||||
|
|
||||||
part 'sign_in.g.dart';
|
part 'sign_in.g.dart';
|
||||||
|
|
||||||
|
|
|
@ -6,12 +6,12 @@ import 'package:nc_photos/app_localizations.dart';
|
||||||
import 'package:nc_photos/async_util.dart' as async_util;
|
import 'package:nc_photos/async_util.dart' as async_util;
|
||||||
import 'package:nc_photos/bloc/list_tag.dart';
|
import 'package:nc_photos/bloc/list_tag.dart';
|
||||||
import 'package:nc_photos/bloc/search_suggestion.dart';
|
import 'package:nc_photos/bloc/search_suggestion.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/entity/tag.dart';
|
import 'package:nc_photos/entity/tag.dart';
|
||||||
import 'package:nc_photos/exception_util.dart' as exception_util;
|
import 'package:nc_photos/exception_util.dart' as exception_util;
|
||||||
import 'package:nc_photos/k.dart' as k;
|
import 'package:nc_photos/k.dart' as k;
|
||||||
import 'package:nc_photos/snack_bar_manager.dart';
|
import 'package:nc_photos/snack_bar_manager.dart';
|
||||||
import 'package:nc_photos/widget/dialog_scaffold.dart';
|
import 'package:nc_photos/widget/dialog_scaffold.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
|
|
||||||
class TagPickerDialog extends StatefulWidget {
|
class TagPickerDialog extends StatefulWidget {
|
||||||
const TagPickerDialog({
|
const TagPickerDialog({
|
||||||
|
|
|
@ -4,13 +4,13 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:kiwi/kiwi.dart';
|
import 'package:kiwi/kiwi.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/api/api.dart';
|
|
||||||
import 'package:nc_photos/api/api_util.dart' as api_util;
|
import 'package:nc_photos/api/api_util.dart' as api_util;
|
||||||
import 'package:nc_photos/app_localizations.dart';
|
import 'package:nc_photos/app_localizations.dart';
|
||||||
import 'package:nc_photos/di_container.dart';
|
import 'package:nc_photos/di_container.dart';
|
||||||
import 'package:nc_photos/entity/file_descriptor.dart';
|
import 'package:nc_photos/entity/file_descriptor.dart';
|
||||||
import 'package:nc_photos/exception_util.dart' as exception_util;
|
import 'package:nc_photos/exception_util.dart' as exception_util;
|
||||||
import 'package:nc_photos/k.dart' as k;
|
import 'package:nc_photos/k.dart' as k;
|
||||||
|
import 'package:nc_photos/np_api_util.dart';
|
||||||
import 'package:nc_photos/platform/k.dart' as platform_k;
|
import 'package:nc_photos/platform/k.dart' as platform_k;
|
||||||
import 'package:nc_photos/snack_bar_manager.dart';
|
import 'package:nc_photos/snack_bar_manager.dart';
|
||||||
import 'package:nc_photos/use_case/request_public_link.dart';
|
import 'package:nc_photos/use_case/request_public_link.dart';
|
||||||
|
@ -110,7 +110,7 @@ class _VideoViewerState extends State<VideoViewer>
|
||||||
_controller = VideoPlayerController.network(
|
_controller = VideoPlayerController.network(
|
||||||
url,
|
url,
|
||||||
httpHeaders: {
|
httpHeaders: {
|
||||||
"Authorization": Api.getAuthorizationHeaderValue(widget.account),
|
"Authorization": AuthUtil.fromAccount(widget.account).toHeaderValue(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
await _controller.initialize();
|
await _controller.initialize();
|
||||||
|
|
|
@ -851,6 +851,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "2.0.1"
|
||||||
|
np_api:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
path: "../np_api"
|
||||||
|
relative: true
|
||||||
|
source: path
|
||||||
|
version: "0.0.1"
|
||||||
np_codegen:
|
np_codegen:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -865,6 +872,13 @@ packages:
|
||||||
relative: true
|
relative: true
|
||||||
source: path
|
source: path
|
||||||
version: "1.0.0"
|
version: "1.0.0"
|
||||||
|
np_common:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
path: "../np_common"
|
||||||
|
relative: true
|
||||||
|
source: path
|
||||||
|
version: "0.0.1"
|
||||||
octo_image:
|
octo_image:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -1556,7 +1570,7 @@ packages:
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.0+1"
|
version: "0.2.0+1"
|
||||||
xml:
|
xml:
|
||||||
dependency: "direct main"
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: xml
|
name: xml
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
|
@ -1570,5 +1584,5 @@ packages:
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.1"
|
version: "3.1.1"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=2.17.0 <3.0.0"
|
dart: ">=2.18.0 <3.0.0"
|
||||||
flutter: ">=3.3.0"
|
flutter: ">=3.3.0"
|
||||||
|
|
|
@ -92,8 +92,12 @@ dependencies:
|
||||||
native_device_orientation: ^1.1.0
|
native_device_orientation: ^1.1.0
|
||||||
nc_photos_plugin:
|
nc_photos_plugin:
|
||||||
path: ../plugin
|
path: ../plugin
|
||||||
|
np_api:
|
||||||
|
path: ../np_api
|
||||||
np_codegen:
|
np_codegen:
|
||||||
path: ../codegen
|
path: ../codegen
|
||||||
|
np_common:
|
||||||
|
path: ../np_common
|
||||||
page_view_indicators: ^2.0.0
|
page_view_indicators: ^2.0.0
|
||||||
path: ^1.8.0
|
path: ^1.8.0
|
||||||
path_provider: ^2.0.6
|
path_provider: ^2.0.6
|
||||||
|
@ -116,7 +120,6 @@ dependencies:
|
||||||
visibility_detector: ^0.3.3
|
visibility_detector: ^0.3.3
|
||||||
wakelock: ^0.6.2
|
wakelock: ^0.6.2
|
||||||
woozy_search: ^2.0.3
|
woozy_search: ^2.0.3
|
||||||
xml: ^6.1.0
|
|
||||||
|
|
||||||
dependency_overrides:
|
dependency_overrides:
|
||||||
video_player_android:
|
video_player_android:
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
import 'package:np_common/ci_string.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
|
244
app/test/api/entity_converter_test.dart
Normal file
244
app/test/api/entity_converter_test.dart
Normal file
|
@ -0,0 +1,244 @@
|
||||||
|
import 'package:nc_photos/api/entity_converter.dart';
|
||||||
|
import 'package:nc_photos/entity/file.dart';
|
||||||
|
import 'package:np_api/np_api.dart' as api;
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group("ApiFileConverter", () {
|
||||||
|
group("fromApi", () {
|
||||||
|
test("file", _files);
|
||||||
|
test("file w/ metadata", _filesMetadata);
|
||||||
|
test("file w/ is-archived", _filesIsArchived);
|
||||||
|
test("file w/ override-date-time", _filesOverrideDateTime);
|
||||||
|
test("multiple files", _filesMultiple);
|
||||||
|
test("directory", _filesDir);
|
||||||
|
test("nextcloud hosted in subdir", _filesServerHostedInSubdir);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _files() async {
|
||||||
|
final apiFile = api.File(
|
||||||
|
href: "/remote.php/dav/files/admin/Nextcloud intro.mp4",
|
||||||
|
contentLength: 3963036,
|
||||||
|
contentType: "video/mp4",
|
||||||
|
etag: "1324f58d4d5c8d81bed6e4ed9d5ea862",
|
||||||
|
lastModified: DateTime.utc(2021, 1, 1, 2, 3, 4),
|
||||||
|
hasPreview: false,
|
||||||
|
fileId: 123,
|
||||||
|
isCollection: false,
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
ApiFileConverter.fromApi(apiFile),
|
||||||
|
File(
|
||||||
|
path: "remote.php/dav/files/admin/Nextcloud intro.mp4",
|
||||||
|
contentLength: 3963036,
|
||||||
|
contentType: "video/mp4",
|
||||||
|
etag: "1324f58d4d5c8d81bed6e4ed9d5ea862",
|
||||||
|
lastModified: DateTime.utc(2021, 1, 1, 2, 3, 4),
|
||||||
|
hasPreview: false,
|
||||||
|
fileId: 123,
|
||||||
|
isCollection: false,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _filesMetadata() async {
|
||||||
|
final apiFile = api.File(
|
||||||
|
href: "/remote.php/dav/files/admin/Photos/Nextcloud community.jpg",
|
||||||
|
contentLength: 797325,
|
||||||
|
contentType: "image/jpeg",
|
||||||
|
etag: "8950e39a034e369237d9285e2d815a50",
|
||||||
|
lastModified: DateTime.utc(2021, 1, 1, 2, 3, 4),
|
||||||
|
hasPreview: true,
|
||||||
|
fileId: 123,
|
||||||
|
isCollection: false,
|
||||||
|
customProperties: {
|
||||||
|
"com.nkming.nc_photos:metadata":
|
||||||
|
"{\"version\":2,\"lastUpdated\":\"2021-01-02T03:04:05.678Z\",\"fileEtag\":\"8950e39a034e369237d9285e2d815a50\",\"imageWidth\":3000,\"imageHeight\":2000}",
|
||||||
|
},
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
ApiFileConverter.fromApi(apiFile),
|
||||||
|
File(
|
||||||
|
path: "remote.php/dav/files/admin/Photos/Nextcloud community.jpg",
|
||||||
|
contentLength: 797325,
|
||||||
|
contentType: "image/jpeg",
|
||||||
|
etag: "8950e39a034e369237d9285e2d815a50",
|
||||||
|
lastModified: DateTime.utc(2021, 1, 1, 2, 3, 4),
|
||||||
|
hasPreview: true,
|
||||||
|
fileId: 123,
|
||||||
|
isCollection: false,
|
||||||
|
metadata: Metadata(
|
||||||
|
lastUpdated: DateTime.utc(2021, 1, 2, 3, 4, 5, 678),
|
||||||
|
fileEtag: "8950e39a034e369237d9285e2d815a50",
|
||||||
|
imageWidth: 3000,
|
||||||
|
imageHeight: 2000,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _filesIsArchived() async {
|
||||||
|
final apiFile = api.File(
|
||||||
|
href: "/remote.php/dav/files/admin/Photos/Nextcloud community.jpg",
|
||||||
|
contentLength: 797325,
|
||||||
|
contentType: "image/jpeg",
|
||||||
|
etag: "8950e39a034e369237d9285e2d815a50",
|
||||||
|
lastModified: DateTime.utc(2021, 1, 1, 2, 3, 4),
|
||||||
|
hasPreview: true,
|
||||||
|
isCollection: false,
|
||||||
|
customProperties: {
|
||||||
|
"com.nkming.nc_photos:is-archived": "true",
|
||||||
|
},
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
ApiFileConverter.fromApi(apiFile),
|
||||||
|
File(
|
||||||
|
path: "remote.php/dav/files/admin/Photos/Nextcloud community.jpg",
|
||||||
|
contentLength: 797325,
|
||||||
|
contentType: "image/jpeg",
|
||||||
|
etag: "8950e39a034e369237d9285e2d815a50",
|
||||||
|
lastModified: DateTime.utc(2021, 1, 1, 2, 3, 4),
|
||||||
|
hasPreview: true,
|
||||||
|
isCollection: false,
|
||||||
|
isArchived: true,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _filesOverrideDateTime() async {
|
||||||
|
final apiFile = api.File(
|
||||||
|
href: "/remote.php/dav/files/admin/Photos/Nextcloud community.jpg",
|
||||||
|
contentLength: 797325,
|
||||||
|
contentType: "image/jpeg",
|
||||||
|
etag: "8950e39a034e369237d9285e2d815a50",
|
||||||
|
lastModified: DateTime.utc(2021, 1, 1, 2, 3, 4),
|
||||||
|
hasPreview: true,
|
||||||
|
isCollection: false,
|
||||||
|
customProperties: {
|
||||||
|
"com.nkming.nc_photos:override-date-time": "2021-01-02T03:04:05.000Z",
|
||||||
|
},
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
ApiFileConverter.fromApi(apiFile),
|
||||||
|
File(
|
||||||
|
path: "remote.php/dav/files/admin/Photos/Nextcloud community.jpg",
|
||||||
|
contentLength: 797325,
|
||||||
|
contentType: "image/jpeg",
|
||||||
|
etag: "8950e39a034e369237d9285e2d815a50",
|
||||||
|
lastModified: DateTime.utc(2021, 1, 1, 2, 3, 4),
|
||||||
|
hasPreview: true,
|
||||||
|
isCollection: false,
|
||||||
|
overrideDateTime: DateTime.utc(2021, 1, 2, 3, 4, 5),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _filesMultiple() async {
|
||||||
|
final apiFiles = [
|
||||||
|
api.File(
|
||||||
|
href: "/remote.php/dav/files/admin/Nextcloud intro.mp4",
|
||||||
|
contentLength: 3963036,
|
||||||
|
contentType: "video/mp4",
|
||||||
|
etag: "1324f58d4d5c8d81bed6e4ed9d5ea862",
|
||||||
|
lastModified: DateTime.utc(2021, 1, 1, 2, 3, 4),
|
||||||
|
hasPreview: false,
|
||||||
|
fileId: 123,
|
||||||
|
isCollection: false,
|
||||||
|
),
|
||||||
|
api.File(
|
||||||
|
href: "/remote.php/dav/files/admin/Nextcloud.png",
|
||||||
|
contentLength: 50598,
|
||||||
|
contentType: "image/png",
|
||||||
|
etag: "48689d5b17c449d9db492ffe8f7ab8a6",
|
||||||
|
lastModified: DateTime.utc(2021, 1, 2, 3, 4, 5),
|
||||||
|
hasPreview: true,
|
||||||
|
fileId: 124,
|
||||||
|
isCollection: false,
|
||||||
|
customProperties: {
|
||||||
|
"com.nkming.nc_photos:metadata":
|
||||||
|
"{\"version\":2,\"lastUpdated\":\"2021-01-02T03:04:05.678000Z\",\"fileEtag\":\"48689d5b17c449d9db492ffe8f7ab8a6\",\"imageWidth\":500,\"imageHeight\":500}",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
];
|
||||||
|
expect(
|
||||||
|
apiFiles.map(ApiFileConverter.fromApi).toList(),
|
||||||
|
[
|
||||||
|
File(
|
||||||
|
path: "remote.php/dav/files/admin/Nextcloud intro.mp4",
|
||||||
|
contentLength: 3963036,
|
||||||
|
contentType: "video/mp4",
|
||||||
|
etag: "1324f58d4d5c8d81bed6e4ed9d5ea862",
|
||||||
|
lastModified: DateTime.utc(2021, 1, 1, 2, 3, 4),
|
||||||
|
hasPreview: false,
|
||||||
|
fileId: 123,
|
||||||
|
isCollection: false,
|
||||||
|
),
|
||||||
|
File(
|
||||||
|
path: "remote.php/dav/files/admin/Nextcloud.png",
|
||||||
|
contentLength: 50598,
|
||||||
|
contentType: "image/png",
|
||||||
|
etag: "48689d5b17c449d9db492ffe8f7ab8a6",
|
||||||
|
lastModified: DateTime.utc(2021, 1, 2, 3, 4, 5),
|
||||||
|
hasPreview: true,
|
||||||
|
fileId: 124,
|
||||||
|
isCollection: false,
|
||||||
|
metadata: Metadata(
|
||||||
|
fileEtag: "48689d5b17c449d9db492ffe8f7ab8a6",
|
||||||
|
imageWidth: 500,
|
||||||
|
imageHeight: 500,
|
||||||
|
lastUpdated: DateTime.utc(2021, 1, 2, 3, 4, 5, 678),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _filesDir() async {
|
||||||
|
final apiFile = api.File(
|
||||||
|
href: "/remote.php/dav/files/admin/Photos/",
|
||||||
|
etag: "123456789abcd",
|
||||||
|
lastModified: DateTime.utc(2021, 1, 1, 2, 3, 4),
|
||||||
|
isCollection: true,
|
||||||
|
hasPreview: false,
|
||||||
|
fileId: 123,
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
ApiFileConverter.fromApi(apiFile),
|
||||||
|
File(
|
||||||
|
path: "remote.php/dav/files/admin/Photos",
|
||||||
|
etag: "123456789abcd",
|
||||||
|
lastModified: DateTime.utc(2021, 1, 1, 2, 3, 4),
|
||||||
|
isCollection: true,
|
||||||
|
hasPreview: false,
|
||||||
|
fileId: 123,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _filesServerHostedInSubdir() async {
|
||||||
|
final apiFile = api.File(
|
||||||
|
href: "/nextcloud/remote.php/dav/files/admin/Nextcloud intro.mp4",
|
||||||
|
contentLength: 3963036,
|
||||||
|
contentType: "video/mp4",
|
||||||
|
etag: "1324f58d4d5c8d81bed6e4ed9d5ea862",
|
||||||
|
lastModified: DateTime.utc(2021, 1, 1, 2, 3, 4),
|
||||||
|
hasPreview: false,
|
||||||
|
fileId: 123,
|
||||||
|
isCollection: false,
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
ApiFileConverter.fromApi(apiFile),
|
||||||
|
File(
|
||||||
|
path: "remote.php/dav/files/admin/Nextcloud intro.mp4",
|
||||||
|
contentLength: 3963036,
|
||||||
|
contentType: "video/mp4",
|
||||||
|
etag: "1324f58d4d5c8d81bed6e4ed9d5ea862",
|
||||||
|
lastModified: DateTime.utc(2021, 1, 1, 2, 3, 4),
|
||||||
|
hasPreview: false,
|
||||||
|
fileId: 123,
|
||||||
|
isCollection: false,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,8 +1,8 @@
|
||||||
import 'package:bloc_test/bloc_test.dart';
|
import 'package:bloc_test/bloc_test.dart';
|
||||||
import 'package:nc_photos/bloc/list_album_share_outlier.dart';
|
import 'package:nc_photos/bloc/list_album_share_outlier.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/di_container.dart';
|
import 'package:nc_photos/di_container.dart';
|
||||||
import 'package:nc_photos/entity/sqlite/database.dart' as sql;
|
import 'package:nc_photos/entity/sqlite/database.dart' as sql;
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
import '../mock_type.dart';
|
import '../mock_type.dart';
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/di_container.dart';
|
import 'package:nc_photos/di_container.dart';
|
||||||
import 'package:nc_photos/entity/album.dart';
|
import 'package:nc_photos/entity/album.dart';
|
||||||
import 'package:nc_photos/entity/album/cover_provider.dart';
|
import 'package:nc_photos/entity/album/cover_provider.dart';
|
||||||
|
@ -9,6 +8,7 @@ import 'package:nc_photos/entity/album/sort_provider.dart';
|
||||||
import 'package:nc_photos/entity/sqlite/database.dart' as sql;
|
import 'package:nc_photos/entity/sqlite/database.dart' as sql;
|
||||||
import 'package:nc_photos/exception.dart';
|
import 'package:nc_photos/exception.dart';
|
||||||
import 'package:nc_photos/or_null.dart';
|
import 'package:nc_photos/or_null.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
import '../../test_util.dart' as util;
|
import '../../test_util.dart' as util;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/entity/album/item.dart';
|
import 'package:nc_photos/entity/album/item.dart';
|
||||||
import 'package:nc_photos/entity/album/sort_provider.dart';
|
import 'package:nc_photos/entity/album/sort_provider.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
import '../../test_util.dart' as util;
|
import '../../test_util.dart' as util;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/entity/album.dart';
|
import 'package:nc_photos/entity/album.dart';
|
||||||
import 'package:nc_photos/entity/album/cover_provider.dart';
|
import 'package:nc_photos/entity/album/cover_provider.dart';
|
||||||
import 'package:nc_photos/entity/album/item.dart';
|
import 'package:nc_photos/entity/album/item.dart';
|
||||||
|
@ -7,7 +6,8 @@ import 'package:nc_photos/entity/album/provider.dart';
|
||||||
import 'package:nc_photos/entity/album/sort_provider.dart';
|
import 'package:nc_photos/entity/album/sort_provider.dart';
|
||||||
import 'package:nc_photos/entity/album/upgrader.dart';
|
import 'package:nc_photos/entity/album/upgrader.dart';
|
||||||
import 'package:nc_photos/entity/file.dart';
|
import 'package:nc_photos/entity/file.dart';
|
||||||
import 'package:nc_photos/type.dart';
|
import 'package:np_common/ci_string.dart';
|
||||||
|
import 'package:np_common/type.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
import '../test_util.dart' as util;
|
import '../test_util.dart' as util;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/entity/exif.dart';
|
import 'package:nc_photos/entity/exif.dart';
|
||||||
import 'package:nc_photos/entity/file.dart';
|
import 'package:nc_photos/entity/file.dart';
|
||||||
import 'package:nc_photos/entity/file_descriptor.dart';
|
import 'package:nc_photos/entity/file_descriptor.dart';
|
||||||
import 'package:nc_photos/or_null.dart';
|
import 'package:nc_photos/or_null.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
|
|
@ -4,7 +4,6 @@ import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:event_bus/event_bus.dart';
|
import 'package:event_bus/event_bus.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/di_container.dart';
|
import 'package:nc_photos/di_container.dart';
|
||||||
import 'package:nc_photos/entity/album.dart';
|
import 'package:nc_photos/entity/album.dart';
|
||||||
import 'package:nc_photos/entity/favorite.dart';
|
import 'package:nc_photos/entity/favorite.dart';
|
||||||
|
@ -19,6 +18,7 @@ import 'package:nc_photos/entity/tag.dart';
|
||||||
import 'package:nc_photos/exception_event.dart';
|
import 'package:nc_photos/exception_event.dart';
|
||||||
import 'package:nc_photos/future_util.dart' as future_util;
|
import 'package:nc_photos/future_util.dart' as future_util;
|
||||||
import 'package:nc_photos/or_null.dart';
|
import 'package:nc_photos/or_null.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
import 'package:path/path.dart' as path_lib;
|
import 'package:path/path.dart' as path_lib;
|
||||||
|
|
||||||
/// Mock of [AlbumRepo] where all methods will throw UnimplementedError
|
/// Mock of [AlbumRepo] where all methods will throw UnimplementedError
|
||||||
|
|
|
@ -5,7 +5,6 @@ import 'package:equatable/equatable.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:nc_photos/account.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/entity/album.dart';
|
import 'package:nc_photos/entity/album.dart';
|
||||||
import 'package:nc_photos/entity/album/cover_provider.dart';
|
import 'package:nc_photos/entity/album/cover_provider.dart';
|
||||||
import 'package:nc_photos/entity/album/item.dart';
|
import 'package:nc_photos/entity/album/item.dart';
|
||||||
|
@ -19,6 +18,7 @@ import 'package:nc_photos/entity/sqlite/database.dart' as sql;
|
||||||
import 'package:nc_photos/entity/sqlite/type_converter.dart';
|
import 'package:nc_photos/entity/sqlite/type_converter.dart';
|
||||||
import 'package:nc_photos/iterable_extension.dart';
|
import 'package:nc_photos/iterable_extension.dart';
|
||||||
import 'package:nc_photos/or_null.dart';
|
import 'package:nc_photos/or_null.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
import 'package:tuple/tuple.dart';
|
import 'package:tuple/tuple.dart';
|
||||||
|
|
||||||
class FilesBuilder {
|
class FilesBuilder {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import 'package:event_bus/event_bus.dart';
|
import 'package:event_bus/event_bus.dart';
|
||||||
import 'package:kiwi/kiwi.dart';
|
import 'package:kiwi/kiwi.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/di_container.dart';
|
import 'package:nc_photos/di_container.dart';
|
||||||
import 'package:nc_photos/entity/album.dart';
|
import 'package:nc_photos/entity/album.dart';
|
||||||
import 'package:nc_photos/entity/album/cover_provider.dart';
|
import 'package:nc_photos/entity/album/cover_provider.dart';
|
||||||
|
@ -12,6 +11,7 @@ import 'package:nc_photos/entity/sqlite/database.dart' as sql;
|
||||||
import 'package:nc_photos/or_null.dart';
|
import 'package:nc_photos/or_null.dart';
|
||||||
import 'package:nc_photos/pref.dart';
|
import 'package:nc_photos/pref.dart';
|
||||||
import 'package:nc_photos/use_case/add_to_album.dart';
|
import 'package:nc_photos/use_case/add_to_album.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
import '../mock_type.dart';
|
import '../mock_type.dart';
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import 'package:event_bus/event_bus.dart';
|
import 'package:event_bus/event_bus.dart';
|
||||||
import 'package:kiwi/kiwi.dart';
|
import 'package:kiwi/kiwi.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/or_null.dart';
|
import 'package:nc_photos/or_null.dart';
|
||||||
import 'package:nc_photos/use_case/share_album_with_user.dart';
|
import 'package:nc_photos/use_case/share_album_with_user.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
import '../mock_type.dart';
|
import '../mock_type.dart';
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import 'package:event_bus/event_bus.dart';
|
import 'package:event_bus/event_bus.dart';
|
||||||
import 'package:kiwi/kiwi.dart';
|
import 'package:kiwi/kiwi.dart';
|
||||||
import 'package:nc_photos/ci_string.dart';
|
|
||||||
import 'package:nc_photos/di_container.dart';
|
import 'package:nc_photos/di_container.dart';
|
||||||
import 'package:nc_photos/use_case/unshare_album_with_user.dart';
|
import 'package:nc_photos/use_case/unshare_album_with_user.dart';
|
||||||
|
import 'package:np_common/ci_string.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
import '../mock_type.dart';
|
import '../mock_type.dart';
|
||||||
|
|
30
np_api/.gitignore
vendored
Normal file
30
np_api/.gitignore
vendored
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
# Miscellaneous
|
||||||
|
*.class
|
||||||
|
*.log
|
||||||
|
*.pyc
|
||||||
|
*.swp
|
||||||
|
.DS_Store
|
||||||
|
.atom/
|
||||||
|
.buildlog/
|
||||||
|
.history
|
||||||
|
.svn/
|
||||||
|
migrate_working_dir/
|
||||||
|
|
||||||
|
# IntelliJ related
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
# The .vscode folder contains launch configuration and tasks you configure in
|
||||||
|
# VS Code which you may wish to be included in version control, so this line
|
||||||
|
# is commented out by default.
|
||||||
|
#.vscode/
|
||||||
|
|
||||||
|
# Flutter/Dart/Pub related
|
||||||
|
# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
|
||||||
|
/pubspec.lock
|
||||||
|
**/doc/api/
|
||||||
|
.dart_tool/
|
||||||
|
.packages
|
||||||
|
build/
|
10
np_api/.metadata
Normal file
10
np_api/.metadata
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# This file tracks properties of this Flutter project.
|
||||||
|
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||||
|
#
|
||||||
|
# This file should be version controlled and should not be manually edited.
|
||||||
|
|
||||||
|
version:
|
||||||
|
revision: 135454af32477f815a7525073027a3ff9eff1bfd
|
||||||
|
channel: stable
|
||||||
|
|
||||||
|
project_type: package
|
7
np_api/analysis_options.yaml
Normal file
7
np_api/analysis_options.yaml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
include: package:flutter_lints/flutter.yaml
|
||||||
|
|
||||||
|
linter:
|
||||||
|
rules:
|
||||||
|
unawaited_futures: true
|
||||||
|
avoid_void_async: true
|
||||||
|
directives_ordering: true
|
11
np_api/lib/np_api.dart
Normal file
11
np_api/lib/np_api.dart
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
export 'src/api.dart';
|
||||||
|
export 'src/entity/entity.dart';
|
||||||
|
export 'src/entity/face_parser.dart';
|
||||||
|
export 'src/entity/favorite_parser.dart';
|
||||||
|
export 'src/entity/file_parser.dart';
|
||||||
|
export 'src/entity/person_parser.dart';
|
||||||
|
export 'src/entity/share_parser.dart';
|
||||||
|
export 'src/entity/sharee_parser.dart';
|
||||||
|
export 'src/entity/tag_parser.dart';
|
||||||
|
export 'src/entity/tagged_file_parser.dart';
|
||||||
|
export 'src/type.dart';
|
|
@ -1,12 +1,9 @@
|
||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.dart';
|
import 'package:np_api/src/type.dart';
|
||||||
import 'package:nc_photos/string_extension.dart';
|
import 'package:np_api/src/util.dart';
|
||||||
import 'package:np_codegen/np_codegen.dart';
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
import 'package:to_string/to_string.dart';
|
|
||||||
import 'package:xml/xml.dart';
|
import 'package:xml/xml.dart';
|
||||||
|
|
||||||
part 'api.g.dart';
|
part 'api.g.dart';
|
||||||
|
@ -16,52 +13,11 @@ part 'files_api.dart';
|
||||||
part 'files_sharing_api.dart';
|
part 'files_sharing_api.dart';
|
||||||
part 'systemtag_api.dart';
|
part 'systemtag_api.dart';
|
||||||
|
|
||||||
@toString
|
|
||||||
class Response {
|
|
||||||
Response(this.statusCode, this.headers, this.body);
|
|
||||||
|
|
||||||
bool get isGood => _isHttpStatusGood(statusCode);
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() => _$toString();
|
|
||||||
|
|
||||||
final int statusCode;
|
|
||||||
@Format(r"...")
|
|
||||||
final Map<String, String> headers;
|
|
||||||
|
|
||||||
/// Content of the response body, String if isResponseString == true during
|
|
||||||
/// request, Uint8List otherwise
|
|
||||||
@Format(
|
|
||||||
r"${kDebugMode ? body.toString().replaceAll(RegExp(r'\n\t'), '').slice(0, 200) : '...'}")
|
|
||||||
final dynamic body;
|
|
||||||
}
|
|
||||||
|
|
||||||
class BasicAuth {
|
|
||||||
BasicAuth(this.username, this.password);
|
|
||||||
|
|
||||||
BasicAuth.fromAccount(Account account)
|
|
||||||
: this(
|
|
||||||
account.username2,
|
|
||||||
account.password,
|
|
||||||
);
|
|
||||||
|
|
||||||
@override
|
|
||||||
toString() {
|
|
||||||
final authString = base64.encode(utf8.encode("$username:$password"));
|
|
||||||
return "Basic $authString";
|
|
||||||
}
|
|
||||||
|
|
||||||
final String username;
|
|
||||||
final String password;
|
|
||||||
}
|
|
||||||
|
|
||||||
@npLog
|
@npLog
|
||||||
class Api {
|
class Api {
|
||||||
Api(Account account)
|
const Api(this.baseUrl, BasicAuth this.auth);
|
||||||
: _baseUrl = Uri.parse(account.url),
|
|
||||||
_auth = BasicAuth.fromAccount(account);
|
|
||||||
|
|
||||||
Api.fromBaseUrl(Uri baseUrl) : _baseUrl = baseUrl;
|
const Api.fromBaseUrl(this.baseUrl) : auth = null;
|
||||||
|
|
||||||
ApiFiles files() => ApiFiles(this);
|
ApiFiles files() => ApiFiles(this);
|
||||||
|
|
||||||
|
@ -71,10 +27,6 @@ class Api {
|
||||||
|
|
||||||
ApiSystemtagsRelations systemtagsRelations() => ApiSystemtagsRelations(this);
|
ApiSystemtagsRelations systemtagsRelations() => ApiSystemtagsRelations(this);
|
||||||
|
|
||||||
static String getAuthorizationHeaderValue(Account account) {
|
|
||||||
return BasicAuth.fromAccount(account).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Response> request(
|
Future<Response> request(
|
||||||
String method,
|
String method,
|
||||||
String endpoint, {
|
String endpoint, {
|
||||||
|
@ -86,9 +38,9 @@ class Api {
|
||||||
}) async {
|
}) async {
|
||||||
final url = _makeUri(endpoint, queryParameters: queryParameters);
|
final url = _makeUri(endpoint, queryParameters: queryParameters);
|
||||||
final req = http.Request(method, url);
|
final req = http.Request(method, url);
|
||||||
if (_auth != null) {
|
if (auth != null) {
|
||||||
req.headers.addAll({
|
req.headers.addAll({
|
||||||
"authorization": _auth.toString(),
|
"authorization": auth!.toHeaderValue(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (header != null) {
|
if (header != null) {
|
||||||
|
@ -104,7 +56,7 @@ class Api {
|
||||||
}
|
}
|
||||||
final response =
|
final response =
|
||||||
await http.Response.fromStream(await http.Client().send(req));
|
await http.Response.fromStream(await http.Client().send(req));
|
||||||
if (!_isHttpStatusGood(response.statusCode)) {
|
if (!isHttpStatusGood(response.statusCode)) {
|
||||||
if (response.statusCode == 404) {
|
if (response.statusCode == 404) {
|
||||||
_log.severe(
|
_log.severe(
|
||||||
"[request] HTTP $method (${response.statusCode}): $endpoint",
|
"[request] HTTP $method (${response.statusCode}): $endpoint",
|
||||||
|
@ -124,20 +76,18 @@ class Api {
|
||||||
String endpoint, {
|
String endpoint, {
|
||||||
Map<String, String>? queryParameters,
|
Map<String, String>? queryParameters,
|
||||||
}) {
|
}) {
|
||||||
final path = _baseUrl.path + "/$endpoint";
|
final path = "${baseUrl.path}/$endpoint";
|
||||||
if (_baseUrl.scheme == "http") {
|
if (baseUrl.scheme == "http") {
|
||||||
return Uri.http(_baseUrl.authority, path, queryParameters);
|
return Uri.http(baseUrl.authority, path, queryParameters);
|
||||||
} else {
|
} else {
|
||||||
return Uri.https(_baseUrl.authority, path, queryParameters);
|
return Uri.https(baseUrl.authority, path, queryParameters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final Uri _baseUrl;
|
final Uri baseUrl;
|
||||||
BasicAuth? _auth;
|
final BasicAuth? auth;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _isHttpStatusGood(int status) => status ~/ 100 == 2;
|
|
||||||
|
|
||||||
class ApiOcs {
|
class ApiOcs {
|
||||||
ApiOcs(this._api);
|
ApiOcs(this._api);
|
||||||
|
|
|
@ -10,21 +10,21 @@ extension _$ApiNpLog on Api {
|
||||||
// ignore: unused_element
|
// ignore: unused_element
|
||||||
Logger get _log => log;
|
Logger get _log => log;
|
||||||
|
|
||||||
static final log = Logger("api.api.Api");
|
static final log = Logger("src.api.Api");
|
||||||
}
|
}
|
||||||
|
|
||||||
extension _$ApiOcsDavDirectNpLog on ApiOcsDavDirect {
|
extension _$ApiOcsDavDirectNpLog on ApiOcsDavDirect {
|
||||||
// ignore: unused_element
|
// ignore: unused_element
|
||||||
Logger get _log => log;
|
Logger get _log => log;
|
||||||
|
|
||||||
static final log = Logger("api.api.ApiOcsDavDirect");
|
static final log = Logger("src.api.ApiOcsDavDirect");
|
||||||
}
|
}
|
||||||
|
|
||||||
extension _$ApiOcsFacerecognitionPersonsNpLog on ApiOcsFacerecognitionPersons {
|
extension _$ApiOcsFacerecognitionPersonsNpLog on ApiOcsFacerecognitionPersons {
|
||||||
// ignore: unused_element
|
// ignore: unused_element
|
||||||
Logger get _log => log;
|
Logger get _log => log;
|
||||||
|
|
||||||
static final log = Logger("api.api.ApiOcsFacerecognitionPersons");
|
static final log = Logger("src.api.ApiOcsFacerecognitionPersons");
|
||||||
}
|
}
|
||||||
|
|
||||||
extension _$ApiOcsFacerecognitionPersonFacesNpLog
|
extension _$ApiOcsFacerecognitionPersonFacesNpLog
|
||||||
|
@ -32,58 +32,47 @@ extension _$ApiOcsFacerecognitionPersonFacesNpLog
|
||||||
// ignore: unused_element
|
// ignore: unused_element
|
||||||
Logger get _log => log;
|
Logger get _log => log;
|
||||||
|
|
||||||
static final log = Logger("api.api.ApiOcsFacerecognitionPersonFaces");
|
static final log = Logger("src.api.ApiOcsFacerecognitionPersonFaces");
|
||||||
}
|
}
|
||||||
|
|
||||||
extension _$ApiFilesNpLog on ApiFiles {
|
extension _$ApiFilesNpLog on ApiFiles {
|
||||||
// ignore: unused_element
|
// ignore: unused_element
|
||||||
Logger get _log => log;
|
Logger get _log => log;
|
||||||
|
|
||||||
static final log = Logger("api.api.ApiFiles");
|
static final log = Logger("src.api.ApiFiles");
|
||||||
}
|
}
|
||||||
|
|
||||||
extension _$ApiOcsFilesSharingSharesNpLog on ApiOcsFilesSharingShares {
|
extension _$ApiOcsFilesSharingSharesNpLog on ApiOcsFilesSharingShares {
|
||||||
// ignore: unused_element
|
// ignore: unused_element
|
||||||
Logger get _log => log;
|
Logger get _log => log;
|
||||||
|
|
||||||
static final log = Logger("api.api.ApiOcsFilesSharingShares");
|
static final log = Logger("src.api.ApiOcsFilesSharingShares");
|
||||||
}
|
}
|
||||||
|
|
||||||
extension _$ApiOcsFilesSharingShareNpLog on ApiOcsFilesSharingShare {
|
extension _$ApiOcsFilesSharingShareNpLog on ApiOcsFilesSharingShare {
|
||||||
// ignore: unused_element
|
// ignore: unused_element
|
||||||
Logger get _log => log;
|
Logger get _log => log;
|
||||||
|
|
||||||
static final log = Logger("api.api.ApiOcsFilesSharingShare");
|
static final log = Logger("src.api.ApiOcsFilesSharingShare");
|
||||||
}
|
}
|
||||||
|
|
||||||
extension _$ApiOcsFilesSharingShareesNpLog on ApiOcsFilesSharingSharees {
|
extension _$ApiOcsFilesSharingShareesNpLog on ApiOcsFilesSharingSharees {
|
||||||
// ignore: unused_element
|
// ignore: unused_element
|
||||||
Logger get _log => log;
|
Logger get _log => log;
|
||||||
|
|
||||||
static final log = Logger("api.api.ApiOcsFilesSharingSharees");
|
static final log = Logger("src.api.ApiOcsFilesSharingSharees");
|
||||||
}
|
}
|
||||||
|
|
||||||
extension _$ApiSystemtagsNpLog on ApiSystemtags {
|
extension _$ApiSystemtagsNpLog on ApiSystemtags {
|
||||||
// ignore: unused_element
|
// ignore: unused_element
|
||||||
Logger get _log => log;
|
Logger get _log => log;
|
||||||
|
|
||||||
static final log = Logger("api.api.ApiSystemtags");
|
static final log = Logger("src.api.ApiSystemtags");
|
||||||
}
|
}
|
||||||
|
|
||||||
extension _$ApiSystemtagsRelationsFilesNpLog on ApiSystemtagsRelationsFiles {
|
extension _$ApiSystemtagsRelationsFilesNpLog on ApiSystemtagsRelationsFiles {
|
||||||
// ignore: unused_element
|
// ignore: unused_element
|
||||||
Logger get _log => log;
|
Logger get _log => log;
|
||||||
|
|
||||||
static final log = Logger("api.api.ApiSystemtagsRelationsFiles");
|
static final log = Logger("src.api.ApiSystemtagsRelationsFiles");
|
||||||
}
|
|
||||||
|
|
||||||
// **************************************************************************
|
|
||||||
// ToStringGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
extension _$ResponseToString on Response {
|
|
||||||
String _$toString() {
|
|
||||||
// ignore: unnecessary_string_interpolations
|
|
||||||
return "Response {statusCode: $statusCode, headers: ..., body: ${kDebugMode ? body.toString().replaceAll(RegExp(r'\n\t'), '').slice(0, 200) : '...'}}";
|
|
||||||
}
|
|
||||||
}
|
}
|
257
np_api/lib/src/entity/entity.dart
Normal file
257
np_api/lib/src/entity/entity.dart
Normal file
|
@ -0,0 +1,257 @@
|
||||||
|
import 'package:equatable/equatable.dart';
|
||||||
|
import 'package:to_string/to_string.dart';
|
||||||
|
|
||||||
|
part 'entity.g.dart';
|
||||||
|
|
||||||
|
@toString
|
||||||
|
class Face with EquatableMixin {
|
||||||
|
const Face({
|
||||||
|
required this.id,
|
||||||
|
required this.fileId,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => _$toString();
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [
|
||||||
|
id,
|
||||||
|
fileId,
|
||||||
|
];
|
||||||
|
|
||||||
|
final int id;
|
||||||
|
final int fileId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@toString
|
||||||
|
class Favorite with EquatableMixin {
|
||||||
|
const Favorite({
|
||||||
|
required this.href,
|
||||||
|
required this.fileId,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => _$toString();
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [
|
||||||
|
href,
|
||||||
|
fileId,
|
||||||
|
];
|
||||||
|
|
||||||
|
final String href;
|
||||||
|
final int fileId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ToString(ignoreNull: true)
|
||||||
|
class File with EquatableMixin {
|
||||||
|
const File({
|
||||||
|
required this.href,
|
||||||
|
this.lastModified,
|
||||||
|
this.etag,
|
||||||
|
this.contentType,
|
||||||
|
this.isCollection,
|
||||||
|
this.contentLength,
|
||||||
|
this.fileId,
|
||||||
|
this.favorite,
|
||||||
|
this.ownerId,
|
||||||
|
this.ownerDisplayName,
|
||||||
|
this.hasPreview,
|
||||||
|
this.trashbinFilename,
|
||||||
|
this.trashbinOriginalLocation,
|
||||||
|
this.trashbinDeletionTime,
|
||||||
|
this.customProperties,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => _$toString();
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [
|
||||||
|
href,
|
||||||
|
lastModified,
|
||||||
|
etag,
|
||||||
|
contentType,
|
||||||
|
isCollection,
|
||||||
|
contentLength,
|
||||||
|
fileId,
|
||||||
|
favorite,
|
||||||
|
ownerId,
|
||||||
|
ownerDisplayName,
|
||||||
|
hasPreview,
|
||||||
|
trashbinFilename,
|
||||||
|
trashbinOriginalLocation,
|
||||||
|
trashbinDeletionTime,
|
||||||
|
customProperties,
|
||||||
|
];
|
||||||
|
|
||||||
|
final String href;
|
||||||
|
final DateTime? lastModified;
|
||||||
|
final String? etag;
|
||||||
|
final String? contentType;
|
||||||
|
final bool? isCollection;
|
||||||
|
final int? contentLength;
|
||||||
|
final int? fileId;
|
||||||
|
final bool? favorite;
|
||||||
|
final String? ownerId;
|
||||||
|
final String? ownerDisplayName;
|
||||||
|
final bool? hasPreview;
|
||||||
|
final String? trashbinFilename;
|
||||||
|
final String? trashbinOriginalLocation;
|
||||||
|
final DateTime? trashbinDeletionTime;
|
||||||
|
final Map<String, String>? customProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
@toString
|
||||||
|
class Person with EquatableMixin {
|
||||||
|
const Person({
|
||||||
|
required this.name,
|
||||||
|
required this.thumbFaceId,
|
||||||
|
required this.count,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => _$toString();
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [
|
||||||
|
name,
|
||||||
|
thumbFaceId,
|
||||||
|
count,
|
||||||
|
];
|
||||||
|
|
||||||
|
final String name;
|
||||||
|
final int thumbFaceId;
|
||||||
|
final int count;
|
||||||
|
}
|
||||||
|
|
||||||
|
@toString
|
||||||
|
class Share with EquatableMixin {
|
||||||
|
const Share({
|
||||||
|
required this.id,
|
||||||
|
required this.shareType,
|
||||||
|
required this.stime,
|
||||||
|
required this.uidOwner,
|
||||||
|
required this.displaynameOwner,
|
||||||
|
required this.uidFileOwner,
|
||||||
|
required this.path,
|
||||||
|
required this.itemType,
|
||||||
|
required this.mimeType,
|
||||||
|
required this.itemSource,
|
||||||
|
required this.shareWith,
|
||||||
|
required this.shareWithDisplayName,
|
||||||
|
required this.url,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => _$toString();
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [
|
||||||
|
id,
|
||||||
|
shareType,
|
||||||
|
stime,
|
||||||
|
uidOwner,
|
||||||
|
displaynameOwner,
|
||||||
|
uidFileOwner,
|
||||||
|
path,
|
||||||
|
itemType,
|
||||||
|
mimeType,
|
||||||
|
itemSource,
|
||||||
|
shareWith,
|
||||||
|
shareWithDisplayName,
|
||||||
|
url,
|
||||||
|
];
|
||||||
|
|
||||||
|
final String id;
|
||||||
|
final int shareType;
|
||||||
|
final int stime;
|
||||||
|
final String uidOwner;
|
||||||
|
final String displaynameOwner;
|
||||||
|
final String uidFileOwner;
|
||||||
|
final String path;
|
||||||
|
final String itemType;
|
||||||
|
final String mimeType;
|
||||||
|
final int itemSource;
|
||||||
|
final String? shareWith;
|
||||||
|
final String shareWithDisplayName;
|
||||||
|
final String? url;
|
||||||
|
}
|
||||||
|
|
||||||
|
@toString
|
||||||
|
class Sharee with EquatableMixin {
|
||||||
|
const Sharee({
|
||||||
|
required this.type,
|
||||||
|
required this.label,
|
||||||
|
required this.shareType,
|
||||||
|
required this.shareWith,
|
||||||
|
required this.shareWithDisplayNameUnique,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => _$toString();
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [
|
||||||
|
type,
|
||||||
|
label,
|
||||||
|
shareType,
|
||||||
|
shareWith,
|
||||||
|
shareWithDisplayNameUnique,
|
||||||
|
];
|
||||||
|
|
||||||
|
final String type;
|
||||||
|
final String label;
|
||||||
|
final int shareType;
|
||||||
|
final String shareWith;
|
||||||
|
final String? shareWithDisplayNameUnique;
|
||||||
|
}
|
||||||
|
|
||||||
|
@toString
|
||||||
|
class Tag with EquatableMixin {
|
||||||
|
const Tag({
|
||||||
|
required this.href,
|
||||||
|
required this.id,
|
||||||
|
required this.displayName,
|
||||||
|
required this.userVisible,
|
||||||
|
required this.userAssignable,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => _$toString();
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [
|
||||||
|
href,
|
||||||
|
id,
|
||||||
|
displayName,
|
||||||
|
userVisible,
|
||||||
|
userAssignable,
|
||||||
|
];
|
||||||
|
|
||||||
|
final String href;
|
||||||
|
final int id;
|
||||||
|
final String displayName;
|
||||||
|
final bool userVisible;
|
||||||
|
final bool userAssignable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@toString
|
||||||
|
class TaggedFile with EquatableMixin {
|
||||||
|
const TaggedFile({
|
||||||
|
required this.href,
|
||||||
|
required this.fileId,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => _$toString();
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get props => [
|
||||||
|
href,
|
||||||
|
fileId,
|
||||||
|
];
|
||||||
|
|
||||||
|
final String href;
|
||||||
|
final int fileId;
|
||||||
|
}
|
63
np_api/lib/src/entity/entity.g.dart
Normal file
63
np_api/lib/src/entity/entity.g.dart
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'entity.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// ToStringGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
extension _$FaceToString on Face {
|
||||||
|
String _$toString() {
|
||||||
|
// ignore: unnecessary_string_interpolations
|
||||||
|
return "Face {id: $id, fileId: $fileId}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension _$FavoriteToString on Favorite {
|
||||||
|
String _$toString() {
|
||||||
|
// ignore: unnecessary_string_interpolations
|
||||||
|
return "Favorite {href: $href, fileId: $fileId}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension _$FileToString on File {
|
||||||
|
String _$toString() {
|
||||||
|
// ignore: unnecessary_string_interpolations
|
||||||
|
return "File {href: $href, ${lastModified == null ? "" : "lastModified: $lastModified, "}${etag == null ? "" : "etag: $etag, "}${contentType == null ? "" : "contentType: $contentType, "}${isCollection == null ? "" : "isCollection: $isCollection, "}${contentLength == null ? "" : "contentLength: $contentLength, "}${fileId == null ? "" : "fileId: $fileId, "}${favorite == null ? "" : "favorite: $favorite, "}${ownerId == null ? "" : "ownerId: $ownerId, "}${ownerDisplayName == null ? "" : "ownerDisplayName: $ownerDisplayName, "}${hasPreview == null ? "" : "hasPreview: $hasPreview, "}${trashbinFilename == null ? "" : "trashbinFilename: $trashbinFilename, "}${trashbinOriginalLocation == null ? "" : "trashbinOriginalLocation: $trashbinOriginalLocation, "}${trashbinDeletionTime == null ? "" : "trashbinDeletionTime: $trashbinDeletionTime, "}${customProperties == null ? "" : "customProperties: $customProperties"}}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension _$PersonToString on Person {
|
||||||
|
String _$toString() {
|
||||||
|
// ignore: unnecessary_string_interpolations
|
||||||
|
return "Person {name: $name, thumbFaceId: $thumbFaceId, count: $count}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension _$ShareToString on Share {
|
||||||
|
String _$toString() {
|
||||||
|
// ignore: unnecessary_string_interpolations
|
||||||
|
return "Share {id: $id, shareType: $shareType, stime: $stime, uidOwner: $uidOwner, displaynameOwner: $displaynameOwner, uidFileOwner: $uidFileOwner, path: $path, itemType: $itemType, mimeType: $mimeType, itemSource: $itemSource, shareWith: $shareWith, shareWithDisplayName: $shareWithDisplayName, url: $url}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension _$ShareeToString on Sharee {
|
||||||
|
String _$toString() {
|
||||||
|
// ignore: unnecessary_string_interpolations
|
||||||
|
return "Sharee {type: $type, label: $label, shareType: $shareType, shareWith: $shareWith, shareWithDisplayNameUnique: $shareWithDisplayNameUnique}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension _$TagToString on Tag {
|
||||||
|
String _$toString() {
|
||||||
|
// ignore: unnecessary_string_interpolations
|
||||||
|
return "Tag {href: $href, id: $id, displayName: $displayName, userVisible: $userVisible, userAssignable: $userAssignable}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension _$TaggedFileToString on TaggedFile {
|
||||||
|
String _$toString() {
|
||||||
|
// ignore: unnecessary_string_interpolations
|
||||||
|
return "TaggedFile {href: $href, fileId: $fileId}";
|
||||||
|
}
|
||||||
|
}
|
42
np_api/lib/src/entity/face_parser.dart
Normal file
42
np_api/lib/src/entity/face_parser.dart
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:logging/logging.dart';
|
||||||
|
import 'package:np_api/src/entity/entity.dart';
|
||||||
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/log.dart';
|
||||||
|
import 'package:np_common/type.dart';
|
||||||
|
|
||||||
|
part 'face_parser.g.dart';
|
||||||
|
|
||||||
|
@npLog
|
||||||
|
class FaceParser {
|
||||||
|
Future<List<Face>> parse(String response) =>
|
||||||
|
compute(_parseFacesIsolate, response);
|
||||||
|
|
||||||
|
List<Face> _parse(JsonObj json) {
|
||||||
|
final jsons = json["ocs"]["data"].cast<JsonObj>();
|
||||||
|
final products = <Face>[];
|
||||||
|
for (final j in jsons) {
|
||||||
|
try {
|
||||||
|
products.add(_parseSingle(j));
|
||||||
|
} catch (e) {
|
||||||
|
_log.severe("[_parse] Failed parsing json: ${jsonEncode(j)}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return products;
|
||||||
|
}
|
||||||
|
|
||||||
|
Face _parseSingle(JsonObj json) {
|
||||||
|
return Face(
|
||||||
|
id: json["id"],
|
||||||
|
fileId: json["fileId"],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Face> _parseFacesIsolate(String response) {
|
||||||
|
initLog();
|
||||||
|
final json = (jsonDecode(response) as Map).cast<String, dynamic>();
|
||||||
|
return FaceParser()._parse(json);
|
||||||
|
}
|
14
np_api/lib/src/entity/face_parser.g.dart
Normal file
14
np_api/lib/src/entity/face_parser.g.dart
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'face_parser.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// NpLogGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
extension _$FaceParserNpLog on FaceParser {
|
||||||
|
// ignore: unused_element
|
||||||
|
Logger get _log => log;
|
||||||
|
|
||||||
|
static final log = Logger("src.entity.face_parser.FaceParser");
|
||||||
|
}
|
74
np_api/lib/src/entity/favorite_parser.dart
Normal file
74
np_api/lib/src/entity/favorite_parser.dart
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:np_api/src/entity/entity.dart';
|
||||||
|
import 'package:np_api/src/entity/parser.dart';
|
||||||
|
import 'package:np_common/log.dart';
|
||||||
|
import 'package:xml/xml.dart';
|
||||||
|
|
||||||
|
class FavoriteParser extends XmlResponseParser {
|
||||||
|
Future<List<Favorite>> parse(String response) =>
|
||||||
|
compute(_parseFavoritesIsolate, response);
|
||||||
|
|
||||||
|
List<Favorite> _parse(XmlDocument xml) => parseT<Favorite>(xml, _toFavorite);
|
||||||
|
|
||||||
|
/// Map <DAV:response> contents to Favorite
|
||||||
|
Favorite _toFavorite(XmlElement element) {
|
||||||
|
String? href;
|
||||||
|
int? fileId;
|
||||||
|
|
||||||
|
for (final child in element.children.whereType<XmlElement>()) {
|
||||||
|
if (child.matchQualifiedName("href",
|
||||||
|
prefix: "DAV:", namespaces: namespaces)) {
|
||||||
|
href = Uri.decodeComponent(child.innerText);
|
||||||
|
} else if (child.matchQualifiedName("propstat",
|
||||||
|
prefix: "DAV:", namespaces: namespaces)) {
|
||||||
|
final status = child.children
|
||||||
|
.whereType<XmlElement>()
|
||||||
|
.firstWhere((element) => element.matchQualifiedName("status",
|
||||||
|
prefix: "DAV:", namespaces: namespaces))
|
||||||
|
.innerText;
|
||||||
|
if (!status.contains(" 200 ")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final prop = child.children.whereType<XmlElement>().firstWhere(
|
||||||
|
(element) => element.matchQualifiedName("prop",
|
||||||
|
prefix: "DAV:", namespaces: namespaces));
|
||||||
|
final propParser = _PropParser(namespaces: namespaces);
|
||||||
|
propParser.parse(prop);
|
||||||
|
fileId = propParser.fileId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Favorite(
|
||||||
|
href: href!,
|
||||||
|
fileId: fileId!,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PropParser {
|
||||||
|
_PropParser({
|
||||||
|
this.namespaces = const {},
|
||||||
|
});
|
||||||
|
|
||||||
|
/// Parse <DAV:prop> element contents
|
||||||
|
void parse(XmlElement element) {
|
||||||
|
for (final child in element.children.whereType<XmlElement>()) {
|
||||||
|
if (child.matchQualifiedName("fileid",
|
||||||
|
prefix: "http://owncloud.org/ns", namespaces: namespaces)) {
|
||||||
|
_fileId = int.parse(child.innerText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int? get fileId => _fileId;
|
||||||
|
|
||||||
|
final Map<String, String> namespaces;
|
||||||
|
|
||||||
|
int? _fileId;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Favorite> _parseFavoritesIsolate(String response) {
|
||||||
|
initLog();
|
||||||
|
final xml = XmlDocument.parse(response);
|
||||||
|
return FavoriteParser()._parse(xml);
|
||||||
|
}
|
202
np_api/lib/src/entity/file_parser.dart
Normal file
202
np_api/lib/src/entity/file_parser.dart
Normal file
|
@ -0,0 +1,202 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:logging/logging.dart';
|
||||||
|
import 'package:np_api/src/entity/entity.dart';
|
||||||
|
import 'package:np_api/src/entity/parser.dart';
|
||||||
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/log.dart';
|
||||||
|
import 'package:xml/xml.dart';
|
||||||
|
|
||||||
|
part 'file_parser.g.dart';
|
||||||
|
|
||||||
|
@npLog
|
||||||
|
class FileParser extends XmlResponseParser {
|
||||||
|
Future<List<File>> parse(String response) =>
|
||||||
|
compute(_parseFilesIsolate, response);
|
||||||
|
|
||||||
|
List<File> _parse(XmlDocument xml) => parseT<File>(xml, _toFile);
|
||||||
|
|
||||||
|
/// Map <DAV:response> contents to File
|
||||||
|
File _toFile(XmlElement element) {
|
||||||
|
String? href;
|
||||||
|
DateTime? lastModified;
|
||||||
|
String? etag;
|
||||||
|
String? contentType;
|
||||||
|
bool? isCollection;
|
||||||
|
int? contentLength;
|
||||||
|
int? fileId;
|
||||||
|
bool? favorite;
|
||||||
|
String? ownerId;
|
||||||
|
String? ownerDisplayName;
|
||||||
|
bool? hasPreview;
|
||||||
|
String? trashbinFilename;
|
||||||
|
String? trashbinOriginalLocation;
|
||||||
|
DateTime? trashbinDeletionTime;
|
||||||
|
Map<String, String>? customProperties;
|
||||||
|
|
||||||
|
for (final child in element.children.whereType<XmlElement>()) {
|
||||||
|
if (child.matchQualifiedName("href",
|
||||||
|
prefix: "DAV:", namespaces: namespaces)) {
|
||||||
|
href = Uri.decodeComponent(child.innerText);
|
||||||
|
} else if (child.matchQualifiedName("propstat",
|
||||||
|
prefix: "DAV:", namespaces: namespaces)) {
|
||||||
|
final status = child.children
|
||||||
|
.whereType<XmlElement>()
|
||||||
|
.firstWhere((element) => element.matchQualifiedName("status",
|
||||||
|
prefix: "DAV:", namespaces: namespaces))
|
||||||
|
.innerText;
|
||||||
|
if (!status.contains(" 200 ")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final prop = child.children.whereType<XmlElement>().firstWhere(
|
||||||
|
(element) => element.matchQualifiedName("prop",
|
||||||
|
prefix: "DAV:", namespaces: namespaces));
|
||||||
|
final propParser = _PropParser(namespaces: namespaces);
|
||||||
|
propParser.parse(prop);
|
||||||
|
contentLength = propParser.contentLength;
|
||||||
|
contentType = propParser.contentType;
|
||||||
|
etag = propParser.etag;
|
||||||
|
lastModified = propParser.lastModified;
|
||||||
|
isCollection = propParser.isCollection;
|
||||||
|
hasPreview = propParser.hasPreview;
|
||||||
|
fileId = propParser.fileId;
|
||||||
|
ownerId = propParser.ownerId;
|
||||||
|
ownerDisplayName = propParser.ownerDisplayName;
|
||||||
|
trashbinFilename = propParser.trashbinFilename;
|
||||||
|
trashbinOriginalLocation = propParser.trashbinOriginalLocation;
|
||||||
|
trashbinDeletionTime = propParser.trashbinDeletionTime;
|
||||||
|
customProperties = propParser.customProperties;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return File(
|
||||||
|
href: href!,
|
||||||
|
lastModified: lastModified,
|
||||||
|
etag: etag,
|
||||||
|
contentType: contentType,
|
||||||
|
isCollection: isCollection,
|
||||||
|
contentLength: contentLength,
|
||||||
|
fileId: fileId,
|
||||||
|
favorite: favorite,
|
||||||
|
ownerId: ownerId,
|
||||||
|
ownerDisplayName: ownerDisplayName,
|
||||||
|
hasPreview: hasPreview,
|
||||||
|
trashbinFilename: trashbinFilename,
|
||||||
|
trashbinOriginalLocation: trashbinOriginalLocation,
|
||||||
|
trashbinDeletionTime: trashbinDeletionTime,
|
||||||
|
customProperties: customProperties,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PropParser {
|
||||||
|
_PropParser({
|
||||||
|
this.namespaces = const {},
|
||||||
|
});
|
||||||
|
|
||||||
|
/// Parse <DAV:prop> element contents
|
||||||
|
void parse(XmlElement element) {
|
||||||
|
for (final child in element.children.whereType<XmlElement>()) {
|
||||||
|
if (child.matchQualifiedName("getlastmodified",
|
||||||
|
prefix: "DAV:", namespaces: namespaces)) {
|
||||||
|
_lastModified = HttpDate.parse(child.innerText);
|
||||||
|
} else if (child.matchQualifiedName("getetag",
|
||||||
|
prefix: "DAV:", namespaces: namespaces)) {
|
||||||
|
_etag = child.innerText.replaceAll("\"", "");
|
||||||
|
} else if (child.matchQualifiedName("getcontenttype",
|
||||||
|
prefix: "DAV:", namespaces: namespaces)) {
|
||||||
|
_contentType = child.innerText;
|
||||||
|
} else if (child.matchQualifiedName("resourcetype",
|
||||||
|
prefix: "DAV:", namespaces: namespaces)) {
|
||||||
|
_isCollection = child.children.whereType<XmlElement>().any((element) =>
|
||||||
|
element.matchQualifiedName("collection",
|
||||||
|
prefix: "DAV:", namespaces: namespaces));
|
||||||
|
} else if (child.matchQualifiedName("getcontentlength",
|
||||||
|
prefix: "DAV:", namespaces: namespaces)) {
|
||||||
|
_contentLength = int.parse(child.innerText);
|
||||||
|
} else if (child.matchQualifiedName("fileid",
|
||||||
|
prefix: "http://owncloud.org/ns", namespaces: namespaces)) {
|
||||||
|
_fileId = int.parse(child.innerText);
|
||||||
|
} else if (child.matchQualifiedName("favorite",
|
||||||
|
prefix: "http://owncloud.org/ns", namespaces: namespaces)) {
|
||||||
|
_favorite = child.innerText != "0";
|
||||||
|
} else if (child.matchQualifiedName("owner-id",
|
||||||
|
prefix: "http://owncloud.org/ns", namespaces: namespaces)) {
|
||||||
|
_ownerId = child.innerText;
|
||||||
|
} else if (child.matchQualifiedName("owner-display-name",
|
||||||
|
prefix: "http://owncloud.org/ns", namespaces: namespaces)) {
|
||||||
|
_ownerDisplayName = child.innerText;
|
||||||
|
} else if (child.matchQualifiedName("has-preview",
|
||||||
|
prefix: "http://nextcloud.org/ns", namespaces: namespaces)) {
|
||||||
|
_hasPreview = child.innerText == "true";
|
||||||
|
} else if (child.matchQualifiedName("trashbin-filename",
|
||||||
|
prefix: "http://nextcloud.org/ns", namespaces: namespaces)) {
|
||||||
|
_trashbinFilename = child.innerText;
|
||||||
|
} else if (child.matchQualifiedName("trashbin-original-location",
|
||||||
|
prefix: "http://nextcloud.org/ns", namespaces: namespaces)) {
|
||||||
|
_trashbinOriginalLocation = child.innerText;
|
||||||
|
} else if (child.matchQualifiedName("trashbin-deletion-time",
|
||||||
|
prefix: "http://nextcloud.org/ns", namespaces: namespaces)) {
|
||||||
|
_trashbinDeletionTime = DateTime.fromMillisecondsSinceEpoch(
|
||||||
|
int.parse(child.innerText) * 1000);
|
||||||
|
} else {
|
||||||
|
final key = child.name.prefix == null
|
||||||
|
? child.localName
|
||||||
|
: "${_expandNamespace(child, namespaces)}:${child.localName}";
|
||||||
|
(_customProperties ??= {})[key] = child.innerText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime? get lastModified => _lastModified;
|
||||||
|
String? get etag => _etag;
|
||||||
|
String? get contentType => _contentType;
|
||||||
|
bool? get isCollection => _isCollection;
|
||||||
|
int? get contentLength => _contentLength;
|
||||||
|
int? get fileId => _fileId;
|
||||||
|
bool? get favorite => _favorite;
|
||||||
|
String? get ownerId => _ownerId;
|
||||||
|
String? get ownerDisplayName => _ownerDisplayName;
|
||||||
|
bool? get hasPreview => _hasPreview;
|
||||||
|
String? get trashbinFilename => _trashbinFilename;
|
||||||
|
String? get trashbinOriginalLocation => _trashbinOriginalLocation;
|
||||||
|
DateTime? get trashbinDeletionTime => _trashbinDeletionTime;
|
||||||
|
Map<String, String>? get customProperties => _customProperties;
|
||||||
|
|
||||||
|
final Map<String, String> namespaces;
|
||||||
|
|
||||||
|
DateTime? _lastModified;
|
||||||
|
String? _etag;
|
||||||
|
String? _contentType;
|
||||||
|
bool? _isCollection;
|
||||||
|
int? _contentLength;
|
||||||
|
int? _fileId;
|
||||||
|
bool? _favorite;
|
||||||
|
String? _ownerId;
|
||||||
|
String? _ownerDisplayName;
|
||||||
|
bool? _hasPreview;
|
||||||
|
String? _trashbinFilename;
|
||||||
|
String? _trashbinOriginalLocation;
|
||||||
|
DateTime? _trashbinDeletionTime;
|
||||||
|
Map<String, String>? _customProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<File> _parseFilesIsolate(String response) {
|
||||||
|
initLog();
|
||||||
|
final xml = XmlDocument.parse(response);
|
||||||
|
return FileParser()._parse(xml);
|
||||||
|
}
|
||||||
|
|
||||||
|
String _expandNamespace(XmlElement element, Map<String, String> namespaces) {
|
||||||
|
if (namespaces.containsKey(element.name.prefix)) {
|
||||||
|
return namespaces[element.name.prefix]!;
|
||||||
|
}
|
||||||
|
final localNamespaces = <String, String>{};
|
||||||
|
for (final a in element.attributes) {
|
||||||
|
if (a.name.prefix == "xmlns") {
|
||||||
|
localNamespaces[a.name.local] = a.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return localNamespaces[element.name.prefix] ?? element.name.prefix!;
|
||||||
|
}
|
14
np_api/lib/src/entity/file_parser.g.dart
Normal file
14
np_api/lib/src/entity/file_parser.g.dart
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'file_parser.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// NpLogGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
extension _$FileParserNpLog on FileParser {
|
||||||
|
// ignore: unused_element
|
||||||
|
Logger get _log => log;
|
||||||
|
|
||||||
|
static final log = Logger("src.entity.file_parser.FileParser");
|
||||||
|
}
|
85
np_api/lib/src/entity/parser.dart
Normal file
85
np_api/lib/src/entity/parser.dart
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:logging/logging.dart';
|
||||||
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:xml/xml.dart';
|
||||||
|
|
||||||
|
part 'parser.g.dart';
|
||||||
|
|
||||||
|
@npLog
|
||||||
|
class XmlResponseParser {
|
||||||
|
List<T> parseT<T>(XmlDocument xml, T? Function(XmlElement) mapper) {
|
||||||
|
namespaces = _parseNamespaces(xml);
|
||||||
|
final body = () {
|
||||||
|
try {
|
||||||
|
return xml.children.whereType<XmlElement>().firstWhere((element) =>
|
||||||
|
element.matchQualifiedName("multistatus",
|
||||||
|
prefix: "DAV:", namespaces: namespaces));
|
||||||
|
} catch (_) {
|
||||||
|
_log.shout("[_parse] Missing element: multistatus");
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
return body.children
|
||||||
|
.whereType<XmlElement>()
|
||||||
|
.where((e) => e.matchQualifiedName("response",
|
||||||
|
prefix: "DAV:", namespaces: namespaces))
|
||||||
|
.map((e) {
|
||||||
|
try {
|
||||||
|
return mapper(e);
|
||||||
|
} catch (e, stackTrace) {
|
||||||
|
_log.shout("[_parse] Failed parsing XML", e, stackTrace);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.whereType<T>()
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, String> _parseNamespaces(XmlDocument xml) {
|
||||||
|
final namespaces = <String, String>{};
|
||||||
|
final xmlContent = xml.descendants.whereType<XmlElement>().firstWhere(
|
||||||
|
(element) => !element.name.qualified.startsWith("?"),
|
||||||
|
orElse: () => XmlElement(XmlName.fromString("")));
|
||||||
|
for (final a in xmlContent.attributes) {
|
||||||
|
if (a.name.prefix == "xmlns") {
|
||||||
|
namespaces[a.name.local] = a.value;
|
||||||
|
} else if (a.name.local == "xmlns") {
|
||||||
|
namespaces["!"] = a.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// _log.fine("[_parseNamespaces] Namespaces: $namespaces");
|
||||||
|
return namespaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
var namespaces = <String, String>{};
|
||||||
|
}
|
||||||
|
|
||||||
|
extension XmlElementExtension on XmlElement {
|
||||||
|
bool matchQualifiedName(
|
||||||
|
String local, {
|
||||||
|
required String prefix,
|
||||||
|
required Map<String, String> namespaces,
|
||||||
|
}) {
|
||||||
|
final localNamespaces = <String, String>{};
|
||||||
|
for (final a in attributes) {
|
||||||
|
if (a.name.prefix == "xmlns") {
|
||||||
|
localNamespaces[a.name.local] = a.value;
|
||||||
|
} else if (a.name.local == "xmlns") {
|
||||||
|
localNamespaces["!"] = a.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return name.local == local &&
|
||||||
|
(name.prefix == prefix ||
|
||||||
|
// match default namespace
|
||||||
|
(name.prefix == null && namespaces["!"] == prefix) ||
|
||||||
|
// match global namespace
|
||||||
|
namespaces.entries
|
||||||
|
.where((element2) => element2.value == prefix)
|
||||||
|
.any((element) => element.key == name.prefix) ||
|
||||||
|
// match local namespace
|
||||||
|
localNamespaces.entries
|
||||||
|
.where((element2) => element2.value == prefix)
|
||||||
|
.any((element) => element.key == name.prefix));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,15 +1,14 @@
|
||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
part of 'webdav_response_parser.dart';
|
part of 'parser.dart';
|
||||||
|
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
// NpLogGenerator
|
// NpLogGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
extension _$WebdavResponseParserNpLog on WebdavResponseParser {
|
extension _$XmlResponseParserNpLog on XmlResponseParser {
|
||||||
// ignore: unused_element
|
// ignore: unused_element
|
||||||
Logger get _log => log;
|
Logger get _log => log;
|
||||||
|
|
||||||
static final log =
|
static final log = Logger("src.entity.parser.XmlResponseParser");
|
||||||
Logger("entity.webdav_response_parser.WebdavResponseParser");
|
|
||||||
}
|
}
|
43
np_api/lib/src/entity/person_parser.dart
Normal file
43
np_api/lib/src/entity/person_parser.dart
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:logging/logging.dart';
|
||||||
|
import 'package:np_api/src/entity/entity.dart';
|
||||||
|
import 'package:np_codegen/np_codegen.dart';
|
||||||
|
import 'package:np_common/log.dart';
|
||||||
|
import 'package:np_common/type.dart';
|
||||||
|
|
||||||
|
part 'person_parser.g.dart';
|
||||||
|
|
||||||
|
@npLog
|
||||||
|
class PersonParser {
|
||||||
|
Future<List<Person>> parse(String response) =>
|
||||||
|
compute(_parsePersonsIsolate, response);
|
||||||
|
|
||||||
|
List<Person> _parse(JsonObj json) {
|
||||||
|
final jsons = json["ocs"]["data"].cast<JsonObj>();
|
||||||
|
final products = <Person>[];
|
||||||
|
for (final j in jsons) {
|
||||||
|
try {
|
||||||
|
products.add(_parseSingle(j));
|
||||||
|
} catch (e) {
|
||||||
|
_log.severe("[_parse] Failed parsing json: ${jsonEncode(j)}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return products;
|
||||||
|
}
|
||||||
|
|
||||||
|
Person _parseSingle(JsonObj json) {
|
||||||
|
return Person(
|
||||||
|
name: json["name"],
|
||||||
|
thumbFaceId: json["thumbFaceId"],
|
||||||
|
count: json["count"],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Person> _parsePersonsIsolate(String response) {
|
||||||
|
initLog();
|
||||||
|
final json = (jsonDecode(response) as Map).cast<String, dynamic>();
|
||||||
|
return PersonParser()._parse(json);
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue