50 lines
2.3 KiB
Dart
50 lines
2.3 KiB
Dart
import '../l10n/tr.dart';
|
|
import 'webdav.dart' show DavItem, DavException;
|
|
|
|
/// 원격 저장소 (WebDAV · SFTP) 의 공통 동작. vfs 가 경로의 서버 종류 (dav:// · sftp://) 에 맞는 것을 부른다.
|
|
/// 경로 [rel] 은 서버 기준 ("/" 로 시작, 맨 위는 "/").
|
|
abstract class RemoteClient {
|
|
Future<List<DavItem>> list(String rel);
|
|
|
|
/// 없으면 null
|
|
Future<DavItem?> stat(String rel);
|
|
|
|
/// 폴더를 만든다 (위 폴더까지). 서버마다 [remoteMkdirs] 를 부른다 - 이미 폴더면 그대로, 같은 이름의 파일이 있으면 [RemoteNameIsFile]
|
|
Future<void> mkdirs(String rel);
|
|
|
|
/// 지우기 (폴더면 안의 것까지)
|
|
Future<void> delete(String rel);
|
|
|
|
/// 같은 서버 안에서 옮기기 · 이름 바꾸기
|
|
Future<void> move(String from, String to, {bool overwrite = false});
|
|
Future<Stream<List<int>>> openRead(String rel);
|
|
Future<void> write(String rel, Stream<List<int>> data, {int? length});
|
|
|
|
/// (남은 공간, 쓴 공간) - 모르면 null
|
|
Future<(int?, int?)> quota();
|
|
void close();
|
|
}
|
|
|
|
/// modular_sync #6 RemoteFs: 같은 이름의 파일이 있어 폴더를 만들 수 없음 - 서버 종류와 상관없이 같은 오류 (F11: 예전에는 SFTP · SMB 만 알리고
|
|
/// FTP 는 조용히 넘어가 뒤의 쓰기가 엉뚱한 오류로, WebDAV 는 서버 오류로 끝났다)
|
|
class RemoteNameIsFile extends DavException {
|
|
RemoteNameIsFile(this.rel) : super(trf('같은 이름의 파일이 있어 폴더를 만들 수 없습니다: {0}', [rel]));
|
|
final String rel;
|
|
}
|
|
|
|
/// 원격 경로의 위 폴더 ("/a/b" → "/a", 맨 위는 "/")
|
|
String remoteParent(String rel) => rel.lastIndexOf('/') <= 0 ? '/' : rel.substring(0, rel.lastIndexOf('/'));
|
|
|
|
/// 약속 (#6, 모든 원격 서버의 mkdirs): [rel] 까지 폴더를 만든다. 이미 폴더면 그대로 · 같은 이름의 파일이면 [RemoteNameIsFile] ·
|
|
/// 위 폴더부터 차례로. 서버마다 다른 것은 한 칸 만들기 [mkdirOne] 뿐 (그 사이 다른 곳이 만들었으면 그대로 두는 것은 [mkdirOne] 이)
|
|
Future<void> remoteMkdirs(RemoteClient c, String rel, Future<void> Function(String rel) mkdirOne) async {
|
|
if (rel == '/' || rel.isEmpty) return;
|
|
final st = await c.stat(rel);
|
|
if (st != null) {
|
|
if (st.isDir) return;
|
|
throw RemoteNameIsFile(rel);
|
|
}
|
|
await remoteMkdirs(c, remoteParent(rel), mkdirOne);
|
|
await mkdirOne(rel);
|
|
}
|