Support copying remote file

This commit is contained in:
Ming Ming 2021-05-20 23:43:53 +08:00
parent 5b6467d299
commit e300f043bb
2 changed files with 85 additions and 0 deletions

View file

@ -335,5 +335,23 @@ class _Files {
}
}
/// A file or folder can be copied by sending a COPY request to the file or
/// folder and specifying the [destinationUrl] as full url
Future<Response> copy({
@required String path,
@required String destinationUrl,
bool overwrite,
}) async {
try {
return await _api.request("COPY", path, header: {
"Destination": destinationUrl,
if (overwrite != null) "Overwrite": overwrite ? "T" : "F",
});
} catch (e) {
_log.severe("[copy] Failed while delete", e);
rethrow;
}
}
static final _log = Logger("api.api._Files");
}

View file

@ -374,6 +374,20 @@ class FileRepo {
Future<void> updateMetadata(Account account, File file, Metadata metadata) =>
this.dataSrc.updateMetadata(account, file, metadata);
/// See [FileDataSource.copy]
Future<void> copy(
Account account,
File f,
String destination, {
bool shouldOverwrite,
}) =>
this.dataSrc.copy(
account,
f,
destination,
shouldOverwrite: shouldOverwrite,
);
final FileDataSource dataSrc;
}
@ -395,6 +409,17 @@ abstract class FileDataSource {
/// This will completely replace the metadata of the file [f]. Partial update
/// is not supported
Future<void> updateMetadata(Account account, File f, Metadata metadata);
/// Copy [f] to [destination]
///
/// [destination] should be a relative WebDAV path like
/// remote.php/dav/files/admin/new/location
Future<void> copy(
Account account,
File f,
String destination, {
bool shouldOverwrite,
});
}
class FileWebdavDataSource implements FileDataSource {
@ -509,6 +534,27 @@ class FileWebdavDataSource implements FileDataSource {
}
}
@override
copy(
Account account,
File f,
String destination, {
bool shouldOverwrite,
}) async {
_log.info("[copy] ${f.path} to $destination");
final response = await Api(account).files().copy(
path: f.path,
destinationUrl: "${account.url}/$destination",
overwrite: shouldOverwrite,
);
if (!response.isGood) {
_log.severe("[copy] Failed requesting sever: $response");
throw ApiException(
response: response,
message: "Failed communicating with server: ${response.statusCode}");
}
}
static final _log = Logger("entity.file.FileWebdavDataSource");
}
@ -574,6 +620,16 @@ class FileAppDbDataSource implements FileDataSource {
});
}
@override
copy(
Account account,
File f,
String destination, {
bool shouldOverwrite,
}) async {
// do nothing
}
Future<List<File>> _doList(ObjectStore store, Account account, File f) async {
final index = store.index(AppDbFileEntry.indexName);
final path = AppDbFileEntry.toPath(account, f);
@ -676,6 +732,17 @@ class FileCachedDataSource implements FileDataSource {
.then((_) => _appDbSrc.updateMetadata(account, f, metadata));
}
@override
copy(
Account account,
File f,
String destination, {
bool shouldOverwrite,
}) async {
await _remoteSrc.copy(account, f, destination,
shouldOverwrite: shouldOverwrite);
}
Future<void> _cacheResult(Account account, File f, List<File> result) {
return AppDb.use((db) async {
final transaction = db.transaction(AppDb.fileStoreName, idbModeReadWrite);