Browse Source

Merge pull request #531 from provokateurin/feature/webdav-file-operations

Feature/webdav file operations
pull/534/head
Kate 1 year ago committed by GitHub
parent
commit
7ae040b860
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 54
      packages/nextcloud/lib/src/webdav/client.dart
  2. 1
      packages/nextcloud/test/files/test.txt
  3. 36
      packages/nextcloud/test/webdav_test.dart

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

@ -1,3 +1,4 @@
import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'dart:typed_data'; import 'dart:typed_data';
@ -169,6 +170,33 @@ class WebDavClient {
), ),
); );
/// Puts a new file at [path] with [file] as content.
///
/// [lastModified] sets the date when the file was last modified on the server.
/// [created] sets the date when the file was created on the server.
/// See http://www.webdav.org/specs/rfc2518.html#METHOD_PUT for more information.
Future<HttpClientResponse> putFile(
final File file,
final FileStat fileStat,
final String path, {
final DateTime? lastModified,
final DateTime? created,
final Function(double progres)? onProgress,
}) async {
var uploaded = 0;
return putStream(
file.openRead().map((final chunk) {
uploaded += chunk.length;
onProgress?.call(uploaded / fileStat.size * 100);
return Uint8List.fromList(chunk);
}),
path,
lastModified: lastModified,
created: created,
contentLength: fileStat.size,
);
}
/// Gets the content of the file at [path]. /// Gets the content of the file at [path].
Future<Uint8List> get(final String path) async => (await getStream(path)).bodyBytes; Future<Uint8List> get(final String path) async => (await getStream(path)).bodyBytes;
@ -178,6 +206,32 @@ class WebDavClient {
_constructPath(path), _constructPath(path),
); );
/// Gets the content of the file at [path].
Future getFile(
final String path,
final File file, {
final Function(double progress)? onProgress,
}) async {
final sink = file.openWrite();
final response = await getStream(path);
if (response.contentLength > 0) {
final completer = Completer();
var downloaded = 0;
response.listen((final chunk) async {
sink.add(chunk);
downloaded += chunk.length;
onProgress?.call(downloaded / response.contentLength * 100);
if (downloaded >= response.contentLength) {
completer.complete();
}
});
await completer.future;
}
await sink.close();
}
/// Retrieves the props for the resource at [path]. /// Retrieves the props for the resource at [path].
/// ///
/// Optionally populates the given [prop]s on the returned files. /// Optionally populates the given [prop]s on the returned files.

1
packages/nextcloud/test/files/test.txt

@ -1 +0,0 @@
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

36
packages/nextcloud/test/webdav_test.dart

@ -2,6 +2,7 @@
library webdav_test; library webdav_test;
import 'dart:convert'; import 'dart:convert';
import 'dart:io';
import 'dart:math'; import 'dart:math';
import 'dart:typed_data'; import 'dart:typed_data';
@ -196,17 +197,21 @@ void main() {
}); });
test('Set properties', () async { test('Set properties', () async {
final lastModifiedDate = DateTime.utc(1972, 3);
final createdDate = DateTime.utc(1971, 2); final createdDate = DateTime.utc(1971, 2);
final createdEpoch = createdDate.millisecondsSinceEpoch ~/ 1000;
final uploadTime = DateTime.now(); final uploadTime = DateTime.now();
await client.webdav.put(Uint8List.fromList(utf8.encode('test')), 'test.txt'); await client.webdav.put(
Uint8List.fromList(utf8.encode('test')),
'test.txt',
lastModified: lastModifiedDate,
created: createdDate,
);
final updated = await client.webdav.proppatch( final updated = await client.webdav.proppatch(
'test.txt', 'test.txt',
set: WebDavProp( set: WebDavProp(
ocfavorite: 1, ocfavorite: 1,
nccreationtime: createdEpoch,
), ),
); );
expect(updated, isTrue); expect(updated, isTrue);
@ -215,6 +220,7 @@ void main() {
'test.txt', 'test.txt',
prop: WebDavPropWithoutValues.fromBools( prop: WebDavPropWithoutValues.fromBools(
ocfavorite: true, ocfavorite: true,
davgetlastmodified: true,
nccreationtime: true, nccreationtime: true,
ncuploadtime: true, ncuploadtime: true,
), ),
@ -225,6 +231,7 @@ void main() {
.first .first
.prop; .prop;
expect(props.ocfavorite, 1); expect(props.ocfavorite, 1);
expect(webdavDateFormat.parseUtc(props.davgetlastmodified!), lastModifiedDate);
expect(DateTime.fromMillisecondsSinceEpoch(props.nccreationtime! * 1000).isAtSameMomentAs(createdDate), isTrue); expect(DateTime.fromMillisecondsSinceEpoch(props.nccreationtime! * 1000).isAtSameMomentAs(createdDate), isTrue);
expectDateInReasonableTimeRange(DateTime.fromMillisecondsSinceEpoch(props.ncuploadtime! * 1000), uploadTime); expectDateInReasonableTimeRange(DateTime.fromMillisecondsSinceEpoch(props.ncuploadtime! * 1000), uploadTime);
}); });
@ -277,6 +284,29 @@ void main() {
expect(props.ocfavorite, 0); expect(props.ocfavorite, 0);
}); });
test('Upload and download file', () async {
final destinationDir = Directory.systemTemp.createTempSync();
final destination = File('${destinationDir.path}/test.png');
final source = File('test/files/test.png');
final progressValues = <double>[];
await client.webdav.putFile(
source,
source.statSync(),
'test.png',
onProgress: progressValues.add,
);
await client.webdav.getFile(
'test.png',
destination,
onProgress: progressValues.add,
);
expect(progressValues, [100.0, 100.0]);
expect(destination.readAsBytesSync(), source.readAsBytesSync());
destinationDir.deleteSync(recursive: true);
});
group('litmus', () { group('litmus', () {
group('basic', () { group('basic', () {
test('options', () async { test('options', () async {

Loading…
Cancel
Save