Browse Source

Merge pull request #592 from nextcloud/refactor/nextcloud

Refactor/nextcloud
pull/581/head
Nikolas Rimikis 1 year ago committed by GitHub
parent
commit
79d3afc15d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      packages/dynamite/dynamite/lib/src/openapi_builder.dart
  2. 2
      packages/dynamite/dynamite_runtime/lib/src/http_client.dart
  3. 2
      packages/neon/neon/lib/src/pages/settings.dart
  4. 5
      packages/nextcloud/lib/src/api/core.openapi.dart
  5. 5
      packages/nextcloud/lib/src/api/files_sharing.openapi.dart
  6. 5
      packages/nextcloud/lib/src/api/news.openapi.dart
  7. 9
      packages/nextcloud/lib/src/api/notes.openapi.dart
  8. 5
      packages/nextcloud/lib/src/api/notifications.openapi.dart
  9. 5
      packages/nextcloud/lib/src/api/provisioning_api.openapi.dart
  10. 5
      packages/nextcloud/lib/src/api/settings.openapi.dart
  11. 5
      packages/nextcloud/lib/src/api/theming.openapi.dart
  12. 5
      packages/nextcloud/lib/src/api/uppush.openapi.dart
  13. 5
      packages/nextcloud/lib/src/api/user_status.openapi.dart
  14. 5
      packages/nextcloud/lib/src/client.dart
  15. 89
      packages/nextcloud/lib/src/webdav/client.dart
  16. 10
      packages/nextcloud/test/webdav_test.dart

6
packages/dynamite/dynamite/lib/src/openapi_builder.dart

@ -144,11 +144,9 @@ class OpenAPIBuilder implements Builder {
), ),
) )
..body = Block.of([ ..body = Block.of([
const Code('final data = await response.bodyBytes;'),
const Code(''),
const Code('String body;'), const Code('String body;'),
const Code('try {'), const Code('try {'),
const Code('body = utf8.decode(data);'), const Code('body = await response.body;'),
const Code('} on FormatException {'), const Code('} on FormatException {'),
const Code("body = 'binary';"), const Code("body = 'binary';"),
const Code('}'), const Code('}'),
@ -541,7 +539,7 @@ class OpenAPIBuilder implements Builder {
code.write('if ($parameterName != null) {'); code.write('if ($parameterName != null) {');
} }
code.write( code.write(
'_body = Uint8List.fromList(utf8.encode(${result.encode(parameterName, mimeType: mimeType)}));', '_body = utf8.encode(${result.encode(parameterName, mimeType: mimeType)}) as Uint8List;',
); );
if (dartParameterNullable) { if (dartParameterNullable) {
code.write('}'); code.write('}');

2
packages/dynamite/dynamite_runtime/lib/src/http_client.dart

@ -140,7 +140,7 @@ class DynamiteClient {
request.headers.add(header.key, header.value); request.headers.add(header.key, header.value);
} }
if (body != null) { if (body != null) {
request.add(body.toList()); request.add(body);
} }
if (cookieJar != null) { if (cookieJar != null) {
request.cookies.addAll(await cookieJar!.loadForRequest(uri)); request.cookies.addAll(await cookieJar!.loadForRequest(uri));

2
packages/neon/neon/lib/src/pages/settings.dart

@ -260,7 +260,7 @@ class _SettingsPageState extends State<SettingsPage> {
), ),
), ),
); );
await saveFileWithPickDialog(fileName, Uint8List.fromList(utf8.encode(data))); await saveFileWithPickDialog(fileName, utf8.encode(data) as Uint8List);
} catch (e, s) { } catch (e, s) {
debugPrint(e.toString()); debugPrint(e.toString());
debugPrint(s.toString()); debugPrint(s.toString());

5
packages/nextcloud/lib/src/api/core.openapi.dart

@ -1,6 +1,5 @@
// ignore_for_file: camel_case_types // ignore_for_file: camel_case_types
// ignore_for_file: public_member_api_docs // ignore_for_file: public_member_api_docs
import 'dart:convert';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:built_collection/built_collection.dart'; import 'package:built_collection/built_collection.dart';
@ -34,11 +33,9 @@ class CoreApiException extends DynamiteApiException {
); );
static Future<CoreApiException> fromResponse(final HttpClientResponse response) async { static Future<CoreApiException> fromResponse(final HttpClientResponse response) async {
final data = await response.bodyBytes;
String body; String body;
try { try {
body = utf8.decode(data); body = await response.body;
} on FormatException { } on FormatException {
body = 'binary'; body = 'binary';
} }

5
packages/nextcloud/lib/src/api/files_sharing.openapi.dart

@ -1,6 +1,5 @@
// ignore_for_file: camel_case_types // ignore_for_file: camel_case_types
// ignore_for_file: public_member_api_docs // ignore_for_file: public_member_api_docs
import 'dart:convert';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:built_collection/built_collection.dart'; import 'package:built_collection/built_collection.dart';
@ -34,11 +33,9 @@ class FilesSharingApiException extends DynamiteApiException {
); );
static Future<FilesSharingApiException> fromResponse(final HttpClientResponse response) async { static Future<FilesSharingApiException> fromResponse(final HttpClientResponse response) async {
final data = await response.bodyBytes;
String body; String body;
try { try {
body = utf8.decode(data); body = await response.body;
} on FormatException { } on FormatException {
body = 'binary'; body = 'binary';
} }

5
packages/nextcloud/lib/src/api/news.openapi.dart

@ -1,6 +1,5 @@
// ignore_for_file: camel_case_types // ignore_for_file: camel_case_types
// ignore_for_file: public_member_api_docs // ignore_for_file: public_member_api_docs
import 'dart:convert';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:built_collection/built_collection.dart'; import 'package:built_collection/built_collection.dart';
@ -34,11 +33,9 @@ class NewsApiException extends DynamiteApiException {
); );
static Future<NewsApiException> fromResponse(final HttpClientResponse response) async { static Future<NewsApiException> fromResponse(final HttpClientResponse response) async {
final data = await response.bodyBytes;
String body; String body;
try { try {
body = utf8.decode(data); body = await response.body;
} on FormatException { } on FormatException {
body = 'binary'; body = 'binary';
} }

9
packages/nextcloud/lib/src/api/notes.openapi.dart

@ -34,11 +34,9 @@ class NotesApiException extends DynamiteApiException {
); );
static Future<NotesApiException> fromResponse(final HttpClientResponse response) async { static Future<NotesApiException> fromResponse(final HttpClientResponse response) async {
final data = await response.bodyBytes;
String body; String body;
try { try {
body = utf8.decode(data); body = await response.body;
} on FormatException { } on FormatException {
body = 'binary'; body = 'binary';
} }
@ -336,9 +334,8 @@ class NotesClient extends DynamiteClient {
} }
// coverage:ignore-end // coverage:ignore-end
headers['Content-Type'] = 'application/json'; headers['Content-Type'] = 'application/json';
body = Uint8List.fromList( body = utf8.encode(json.encode(_jsonSerializers.serialize(settings, specifiedType: const FullType(NotesSettings))))
utf8.encode(json.encode(_jsonSerializers.serialize(settings, specifiedType: const FullType(NotesSettings)))), as Uint8List;
);
final response = await doRequest( final response = await doRequest(
'put', 'put',
Uri(path: path, queryParameters: queryParameters.isNotEmpty ? queryParameters : null).toString(), Uri(path: path, queryParameters: queryParameters.isNotEmpty ? queryParameters : null).toString(),

5
packages/nextcloud/lib/src/api/notifications.openapi.dart

@ -1,6 +1,5 @@
// ignore_for_file: camel_case_types // ignore_for_file: camel_case_types
// ignore_for_file: public_member_api_docs // ignore_for_file: public_member_api_docs
import 'dart:convert';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:built_collection/built_collection.dart'; import 'package:built_collection/built_collection.dart';
@ -34,11 +33,9 @@ class NotificationsApiException extends DynamiteApiException {
); );
static Future<NotificationsApiException> fromResponse(final HttpClientResponse response) async { static Future<NotificationsApiException> fromResponse(final HttpClientResponse response) async {
final data = await response.bodyBytes;
String body; String body;
try { try {
body = utf8.decode(data); body = await response.body;
} on FormatException { } on FormatException {
body = 'binary'; body = 'binary';
} }

5
packages/nextcloud/lib/src/api/provisioning_api.openapi.dart

@ -1,6 +1,5 @@
// ignore_for_file: camel_case_types // ignore_for_file: camel_case_types
// ignore_for_file: public_member_api_docs // ignore_for_file: public_member_api_docs
import 'dart:convert';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:built_collection/built_collection.dart'; import 'package:built_collection/built_collection.dart';
@ -34,11 +33,9 @@ class ProvisioningApiApiException extends DynamiteApiException {
); );
static Future<ProvisioningApiApiException> fromResponse(final HttpClientResponse response) async { static Future<ProvisioningApiApiException> fromResponse(final HttpClientResponse response) async {
final data = await response.bodyBytes;
String body; String body;
try { try {
body = utf8.decode(data); body = await response.body;
} on FormatException { } on FormatException {
body = 'binary'; body = 'binary';
} }

5
packages/nextcloud/lib/src/api/settings.openapi.dart

@ -1,6 +1,5 @@
// ignore_for_file: camel_case_types // ignore_for_file: camel_case_types
// ignore_for_file: public_member_api_docs // ignore_for_file: public_member_api_docs
import 'dart:convert';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:built_value/built_value.dart'; import 'package:built_value/built_value.dart';
@ -32,11 +31,9 @@ class SettingsApiException extends DynamiteApiException {
); );
static Future<SettingsApiException> fromResponse(final HttpClientResponse response) async { static Future<SettingsApiException> fromResponse(final HttpClientResponse response) async {
final data = await response.bodyBytes;
String body; String body;
try { try {
body = utf8.decode(data); body = await response.body;
} on FormatException { } on FormatException {
body = 'binary'; body = 'binary';
} }

5
packages/nextcloud/lib/src/api/theming.openapi.dart

@ -1,6 +1,5 @@
// ignore_for_file: camel_case_types // ignore_for_file: camel_case_types
// ignore_for_file: public_member_api_docs // ignore_for_file: public_member_api_docs
import 'dart:convert';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:built_collection/built_collection.dart'; import 'package:built_collection/built_collection.dart';
@ -34,11 +33,9 @@ class ThemingApiException extends DynamiteApiException {
); );
static Future<ThemingApiException> fromResponse(final HttpClientResponse response) async { static Future<ThemingApiException> fromResponse(final HttpClientResponse response) async {
final data = await response.bodyBytes;
String body; String body;
try { try {
body = utf8.decode(data); body = await response.body;
} on FormatException { } on FormatException {
body = 'binary'; body = 'binary';
} }

5
packages/nextcloud/lib/src/api/uppush.openapi.dart

@ -1,6 +1,5 @@
// ignore_for_file: camel_case_types // ignore_for_file: camel_case_types
// ignore_for_file: public_member_api_docs // ignore_for_file: public_member_api_docs
import 'dart:convert';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:built_collection/built_collection.dart'; import 'package:built_collection/built_collection.dart';
@ -33,11 +32,9 @@ class UppushApiException extends DynamiteApiException {
); );
static Future<UppushApiException> fromResponse(final HttpClientResponse response) async { static Future<UppushApiException> fromResponse(final HttpClientResponse response) async {
final data = await response.bodyBytes;
String body; String body;
try { try {
body = utf8.decode(data); body = await response.body;
} on FormatException { } on FormatException {
body = 'binary'; body = 'binary';
} }

5
packages/nextcloud/lib/src/api/user_status.openapi.dart

@ -1,6 +1,5 @@
// ignore_for_file: camel_case_types // ignore_for_file: camel_case_types
// ignore_for_file: public_member_api_docs // ignore_for_file: public_member_api_docs
import 'dart:convert';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:built_collection/built_collection.dart'; import 'package:built_collection/built_collection.dart';
@ -34,11 +33,9 @@ class UserStatusApiException extends DynamiteApiException {
); );
static Future<UserStatusApiException> fromResponse(final HttpClientResponse response) async { static Future<UserStatusApiException> fromResponse(final HttpClientResponse response) async {
final data = await response.bodyBytes;
String body; String body;
try { try {
body = utf8.decode(data); body = await response.body;
} on FormatException { } on FormatException {
body = 'binary'; body = 'binary';
} }

5
packages/nextcloud/lib/src/client.dart

@ -27,10 +27,7 @@ class NextcloudClient extends DynamiteClient {
final String? userAgentOverride, final String? userAgentOverride,
super.cookieJar, super.cookieJar,
}) : super( }) : super(
baseHeaders: (<String, String?>{ baseHeaders: language != null ? {'Accept-Language': language} : null,
'Accept-Language': language,
}..removeWhere((final _, final value) => value == null))
.cast<String, String>(),
userAgent: userAgentOverride ?? appType.userAgent, userAgent: userAgentOverride ?? appType.userAgent,
authentications: [ authentications: [
if (appPassword != null) ...[ if (appPassword != null) ...[

89
packages/nextcloud/lib/src/webdav/client.dart

@ -22,9 +22,12 @@ class WebDavClient {
Future<HttpClientResponse> _send( Future<HttpClientResponse> _send(
final String method, final String method,
final String url, { final String url, {
final Stream<Uint8List>? data, final Stream<Uint8List>? dataStream,
final Uint8List? data,
final Map<String, String>? headers, final Map<String, String>? headers,
}) async { }) async {
assert(dataStream == null || data == null, 'Only one of dataStream or data can be specified.');
final request = await HttpClient().openUrl( final request = await HttpClient().openUrl(
method, method,
Uri.parse(url), Uri.parse(url),
@ -33,14 +36,17 @@ class WebDavClient {
for (final header in { for (final header in {
HttpHeaders.contentTypeHeader: 'application/xml', HttpHeaders.contentTypeHeader: 'application/xml',
...?rootClient.baseHeaders, ...?rootClient.baseHeaders,
if (headers != null) ...headers, ...?headers,
if (rootClient.authentications.isNotEmpty) ...rootClient.authentications.first.headers, ...?rootClient.authentications.firstOrNull?.headers,
}.entries) { }.entries) {
request.headers.add(header.key, header.value); request.headers.add(header.key, header.value);
} }
if (data != null) { if (data != null) {
await request.addStream(data); request.add(data);
}
if (dataStream != null) {
await request.addStream(dataStream);
} }
final response = await request.close(); final response = await request.close();
@ -49,7 +55,7 @@ class WebDavClient {
throw DynamiteApiException( throw DynamiteApiException(
response.statusCode, response.statusCode,
response.responseHeaders, response.responseHeaders,
utf8.decode(await response.bodyBytes), await response.body,
); );
} }
@ -78,24 +84,16 @@ class WebDavClient {
Future<WebDavMultistatus> _parseResponse(final HttpClientResponse response) async => Future<WebDavMultistatus> _parseResponse(final HttpClientResponse response) async =>
WebDavMultistatus.fromXmlElement(xml.XmlDocument.parse(await response.body).rootElement); WebDavMultistatus.fromXmlElement(xml.XmlDocument.parse(await response.body).rootElement);
Map<String, String>? _getUploadHeaders({ Map<String, String> _getUploadHeaders({
required final DateTime? lastModified, required final DateTime? lastModified,
required final DateTime? created, required final DateTime? created,
required final int? contentLength, required final int? contentLength,
}) { }) =>
final headers = <String, String>{ {
if (lastModified != null) ...{ if (lastModified != null) 'X-OC-Mtime': (lastModified.millisecondsSinceEpoch ~/ 1000).toString(),
'X-OC-Mtime': (lastModified.millisecondsSinceEpoch ~/ 1000).toString(), if (created != null) 'X-OC-CTime': (created.millisecondsSinceEpoch ~/ 1000).toString(),
}, if (contentLength != null) HttpHeaders.contentLengthHeader: contentLength.toString(),
if (created != null) ...{
'X-OC-CTime': (created.millisecondsSinceEpoch ~/ 1000).toString(),
},
if (contentLength != null) ...{
'Content-Length': contentLength.toString(),
},
}; };
return headers.isNotEmpty ? headers : null;
}
/// Gets the WebDAV capabilities of the server. /// Gets the WebDAV capabilities of the server.
Future<WebDavOptions> options() async { Future<WebDavOptions> options() async {
@ -103,8 +101,8 @@ class WebDavClient {
'OPTIONS', 'OPTIONS',
_constructPath(), _constructPath(),
); );
final davCapabilities = response.headers['dav']?.cast<String>().first ?? ''; final davCapabilities = response.headers['dav']?.first ?? '';
final davSearchCapabilities = response.headers['dasl']?.cast<String>().first ?? ''; final davSearchCapabilities = response.headers['dasl']?.first ?? '';
return WebDavOptions( return WebDavOptions(
davCapabilities.split(',').map((final e) => e.trim()).where((final e) => e.isNotEmpty).toSet(), davCapabilities.split(',').map((final e) => e.trim()).where((final e) => e.isNotEmpty).toSet(),
davSearchCapabilities.split(',').map((final e) => e.trim()).where((final e) => e.isNotEmpty).toSet(), davSearchCapabilities.split(',').map((final e) => e.trim()).where((final e) => e.isNotEmpty).toSet(),
@ -138,12 +136,15 @@ class WebDavClient {
final DateTime? lastModified, final DateTime? lastModified,
final DateTime? created, final DateTime? created,
}) => }) =>
putStream( _send(
Stream.value(localData), 'PUT',
path, _constructPath(path),
data: localData,
headers: _getUploadHeaders(
lastModified: lastModified, lastModified: lastModified,
created: created, created: created,
contentLength: localData.lengthInBytes, contentLength: null,
),
); );
/// Puts a new file at [path] with [localData] as content. /// Puts a new file at [path] with [localData] as content.
@ -162,7 +163,7 @@ class WebDavClient {
_send( _send(
'PUT', 'PUT',
_constructPath(path), _constructPath(path),
data: localData, dataStream: localData,
headers: _getUploadHeaders( headers: _getUploadHeaders(
lastModified: lastModified, lastModified: lastModified,
created: created, created: created,
@ -188,7 +189,7 @@ class WebDavClient {
file.openRead().map((final chunk) { file.openRead().map((final chunk) {
uploaded += chunk.length; uploaded += chunk.length;
onProgress?.call(uploaded / fileStat.size); onProgress?.call(uploaded / fileStat.size);
return Uint8List.fromList(chunk); return chunk as Uint8List;
}), }),
path, path,
lastModified: lastModified, lastModified: lastModified,
@ -246,20 +247,10 @@ class WebDavClient {
await _send( await _send(
'PROPFIND', 'PROPFIND',
_constructPath(path), _constructPath(path),
data: Stream.value( data: utf8.encode(
Uint8List.fromList( WebDavPropfind(prop: prop ?? WebDavPropWithoutValues()).toXmlElement(namespaces: namespaces).toXmlString(),
utf8.encode( ) as Uint8List,
WebDavPropfind(prop: prop ?? WebDavPropWithoutValues()) headers: depth != null ? {'Depth': depth.value} : null,
.toXmlElement(namespaces: namespaces)
.toXmlString(),
),
),
),
headers: {
if (depth != null) ...{
'Depth': depth.value,
},
},
), ),
); );
@ -276,16 +267,12 @@ class WebDavClient {
await _send( await _send(
'REPORT', 'REPORT',
_constructPath(path), _constructPath(path),
data: Stream.value( data: utf8.encode(
Uint8List.fromList(
utf8.encode(
WebDavOcFilterFiles( WebDavOcFilterFiles(
filterRules: filterRules, filterRules: filterRules,
prop: prop ?? WebDavPropWithoutValues(), // coverage:ignore-line prop: prop ?? WebDavPropWithoutValues(), // coverage:ignore-line
).toXmlElement(namespaces: namespaces).toXmlString(), ).toXmlElement(namespaces: namespaces).toXmlString(),
), ) as Uint8List,
),
),
), ),
); );
@ -303,16 +290,12 @@ class WebDavClient {
final response = await _send( final response = await _send(
'PROPPATCH', 'PROPPATCH',
_constructPath(path), _constructPath(path),
data: Stream.value( data: utf8.encode(
Uint8List.fromList(
utf8.encode(
WebDavPropertyupdate( WebDavPropertyupdate(
set: set != null ? WebDavSet(prop: set) : null, set: set != null ? WebDavSet(prop: set) : null,
remove: remove != null ? WebDavRemove(prop: remove) : null, remove: remove != null ? WebDavRemove(prop: remove) : null,
).toXmlElement(namespaces: namespaces).toXmlString(), ).toXmlElement(namespaces: namespaces).toXmlString(),
), ) as Uint8List,
),
),
); );
final data = await _parseResponse(response); final data = await _parseResponse(response);
for (final a in data.responses) { for (final a in data.responses) {

10
packages/nextcloud/test/webdav_test.dart

@ -137,7 +137,7 @@ void main() {
}); });
test('Get directory props', () async { test('Get directory props', () async {
final data = Uint8List.fromList(utf8.encode('test')); final data = utf8.encode('test') as Uint8List;
await client.webdav.mkcol('test'); await client.webdav.mkcol('test');
await client.webdav.put(data, 'test/test.txt'); await client.webdav.put(data, 'test/test.txt');
@ -169,7 +169,7 @@ void main() {
}); });
test('Filter files', () async { test('Filter files', () async {
final response = await client.webdav.put(Uint8List.fromList(utf8.encode('test')), 'test.txt'); final response = await client.webdav.put(utf8.encode('test') as Uint8List, 'test.txt');
final id = response.headers['oc-fileid']!.first; final id = response.headers['oc-fileid']!.first;
await client.webdav.proppatch( await client.webdav.proppatch(
'test.txt', 'test.txt',
@ -202,7 +202,7 @@ void main() {
final uploadTime = DateTime.now(); final uploadTime = DateTime.now();
await client.webdav.put( await client.webdav.put(
Uint8List.fromList(utf8.encode('test')), utf8.encode('test') as Uint8List,
'test.txt', 'test.txt',
lastModified: lastModifiedDate, lastModified: lastModifiedDate,
created: createdDate, created: createdDate,
@ -237,7 +237,7 @@ void main() {
}); });
test('Remove properties', () async { test('Remove properties', () async {
await client.webdav.put(Uint8List.fromList(utf8.encode('test')), 'test.txt'); await client.webdav.put(utf8.encode('test') as Uint8List, 'test.txt');
var updated = await client.webdav.proppatch( var updated = await client.webdav.proppatch(
'test.txt', 'test.txt',
@ -323,7 +323,7 @@ void main() {
('put_get_utf8_segment', 'res-%e2%82%ac'), ('put_get_utf8_segment', 'res-%e2%82%ac'),
]) { ]) {
test(name, () async { test(name, () async {
final content = Uint8List.fromList(utf8.encode('This is a test file')); final content = utf8.encode('This is a test file') as Uint8List;
final response = await client.webdav.put(content, path); final response = await client.webdav.put(content, path);
expect(response.statusCode, 201); expect(response.statusCode, 201);

Loading…
Cancel
Save