Windows 경로 입력의 smb:// · cifs:// 를 \서버\공유 로 (190)
관리자 지시 (179 보충): 주소가 틀린 줄 알지 않게, Windows 는 smb://서버/공유 (cifs:// 도) 를 \서버\공유 로 바꿔 연다. %20 같은 주소 글자는 풀고 한글은 그대로. 바꿔도 못 열면 "Windows 의 네트워크 공유는 \서버\공유 형식 (바꾼 경로)" 를 알린다. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>fix_mkv
parent
df508e3d2d
commit
a94009524c
|
|
@ -1936,6 +1936,7 @@
|
|||
"폴더가 들어 있을 때": "When folders are included",
|
||||
"폴더가 아닙니다: {0}": "Not a folder: {0}",
|
||||
"폴더가 없거나 열 수 없습니다": "The folder does not exist or cannot be opened",
|
||||
"폴더가 없거나 열 수 없습니다. Windows 의 네트워크 공유는 \\\\서버\\공유 형식입니다 (바꾼 경로: {0})": "The folder does not exist or cannot be opened. On Windows, network shares use the \\\\server\\share form (converted path: {0})",
|
||||
"폴더가 없거나 열 수 없습니다: {0}": "The folder doesn't exist or can't be opened: {0}",
|
||||
"폴더가 없습니다": "The folder does not exist",
|
||||
"폴더는 보여도 그 안의 동영상 · 파일은 이 권한이 있어야 보입니다. 허용 화면에서 JJ_MKVMaker 를 켜고 돌아오세요.": "Folders are shown, but the videos and files inside need this permission. Turn on JJ_MKVMaker on the permission screen and come back.",
|
||||
|
|
|
|||
|
|
@ -1936,6 +1936,7 @@
|
|||
"폴더가 들어 있을 때": "フォルダーを含むとき",
|
||||
"폴더가 아닙니다: {0}": "フォルダーではありません: {0}",
|
||||
"폴더가 없거나 열 수 없습니다": "フォルダーがないか開けません",
|
||||
"폴더가 없거나 열 수 없습니다. Windows 의 네트워크 공유는 \\\\서버\\공유 형식입니다 (바꾼 경로: {0})": "フォルダーが存在しないか開けません。Windows のネットワーク共有は \\\\サーバー\\共有 の形式です (変換したパス: {0})",
|
||||
"폴더가 없거나 열 수 없습니다: {0}": "フォルダーがないか、開けません: {0}",
|
||||
"폴더가 없습니다": "フォルダーがありません",
|
||||
"폴더는 보여도 그 안의 동영상 · 파일은 이 권한이 있어야 보입니다. 허용 화면에서 JJ_MKVMaker 를 켜고 돌아오세요.": "フォルダーは見えても、中の動画・ファイルはこの権限が必要です。許可画面で JJ_MKVMaker をオンにして戻ってください。",
|
||||
|
|
|
|||
|
|
@ -1936,6 +1936,7 @@
|
|||
"폴더가 들어 있을 때": "包含文件夹时",
|
||||
"폴더가 아닙니다: {0}": "不是文件夹: {0}",
|
||||
"폴더가 없거나 열 수 없습니다": "文件夹不存在或无法打开",
|
||||
"폴더가 없거나 열 수 없습니다. Windows 의 네트워크 공유는 \\\\서버\\공유 형식입니다 (바꾼 경로: {0})": "文件夹不存在或无法打开。Windows 的网络共享格式为 \\\\服务器\\共享(转换后的路径:{0})",
|
||||
"폴더가 없거나 열 수 없습니다: {0}": "文件夹不存在或无法打开: {0}",
|
||||
"폴더가 없습니다": "文件夹不存在",
|
||||
"폴더는 보여도 그 안의 동영상 · 파일은 이 권한이 있어야 보입니다. 허용 화면에서 JJ_MKVMaker 를 켜고 돌아오세요.": "虽然能看到文件夹,但其中的视频和文件需要此权限。请在权限界面开启 JJ_MKVMaker 后返回。",
|
||||
|
|
|
|||
|
|
@ -74,6 +74,10 @@ class ExplorerPage extends StatefulWidget {
|
|||
@visibleForTesting
|
||||
static bool? debugAndroidPaths;
|
||||
|
||||
/// 시험: 경로 입력 창이 넣은 경로를 고쳐 쓰고 확인하는 것 (갈 경로, 칸 아래 이유)
|
||||
@visibleForTesting
|
||||
static Future<(String?, String?)> checkPathForTest(String input) => _ExplorerPageState.checkEnteredPath(input);
|
||||
|
||||
static const routeName = 'explorer';
|
||||
static const rsyncRouteName = 'rsync';
|
||||
static int _open = 0, _openRsync = 0;
|
||||
|
|
@ -3216,6 +3220,9 @@ class _ExplorerPageState extends State<ExplorerPage> {
|
|||
if (path.isEmpty) return (null, null);
|
||||
// 179: Android 는 네트워크 공유 (SMB) 를 아직 못 연다 - 폴더가 없다고 하지 않고 WebDAV 로 안내
|
||||
if ((ExplorerPage.debugAndroidPaths ?? Platform.isAndroid) && looksLikeSmb(path)) return (null, smbNotSupported);
|
||||
// 190: Windows 는 smb:// · cifs:// 주소를 \\서버\공유 로 바꿔 연다 (주소가 틀린 줄 알지 않게)
|
||||
final unc = Platform.isWindows ? smbToUnc(path) : null;
|
||||
if (unc != null) path = unc;
|
||||
if (Platform.isWindows && RegExp(r'^\\\\[^\\/]+[\\/]?$').hasMatch(path)) {
|
||||
return (null, tr('네트워크 공유는 공유 폴더 이름까지 넣으세요 (예: \\\\NAS\\영상).'));
|
||||
}
|
||||
|
|
@ -3226,6 +3233,9 @@ class _ExplorerPageState extends State<ExplorerPage> {
|
|||
} catch (_) {
|
||||
ok = false;
|
||||
}
|
||||
if (!ok && unc != null) {
|
||||
return (null, trf('폴더가 없거나 열 수 없습니다. Windows 의 네트워크 공유는 \\\\서버\\공유 형식입니다 (바꾼 경로: {0})', [unc]));
|
||||
}
|
||||
return ok ? (path, null) : (null, tr('폴더가 없거나 열 수 없습니다'));
|
||||
}
|
||||
|
||||
|
|
@ -3870,6 +3880,24 @@ class _PatternDialogState extends State<_PatternDialog> {
|
|||
/// 179: SMB 경로 (smb:// · \\서버\공유)
|
||||
bool looksLikeSmb(String path) => RegExp(r'^(smb|cifs)://', caseSensitive: false).hasMatch(path) || path.startsWith(r'\\');
|
||||
|
||||
/// 190: smb://서버/공유/폴더 (cifs:// 도) → \\서버\공유\폴더. SMB 주소가 아니면 null
|
||||
String? smbToUnc(String path) {
|
||||
final m = RegExp(r'^(smb|cifs)://(.+)$', caseSensitive: false).firstMatch(path.trim());
|
||||
if (m == null) return null;
|
||||
final parts = m.group(2)!.split(RegExp(r'[/\\]+')).where((s) => s.isNotEmpty).map(_decodeSmbPart).toList();
|
||||
if (parts.isEmpty) return null;
|
||||
return '\\\\${parts.join('\\')}';
|
||||
}
|
||||
|
||||
/// %20 같은 주소 글자는 풀고, 한글 등 그대로 쓴 글자는 그대로
|
||||
String _decodeSmbPart(String s) {
|
||||
try {
|
||||
return Uri.decodeComponent(s);
|
||||
} catch (_) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
String get smbNotSupported => tr('네트워크 공유 (SMB) 는 아직 지원하지 않습니다. WebDAV 탭을 쓰세요');
|
||||
|
||||
class _PathDialog extends StatefulWidget {
|
||||
|
|
|
|||
|
|
@ -408,6 +408,19 @@ void main() {
|
|||
expect(find.textContaining(right), findsWidgets);
|
||||
});
|
||||
|
||||
test('190: Windows 경로 입력의 smb:// · cifs:// 는 \\\\서버\\공유 로 바꿔 열고, 못 열면 그 형식을 알린다', () async {
|
||||
expect(smbToUnc('smb://nas/영상/2024'), r'\\nas\영상\2024');
|
||||
expect(smbToUnc('CIFS://nas.local/share/'), r'\\nas.local\share');
|
||||
expect(smbToUnc('smb://nas/My%20Videos'), r'\\nas\My Videos');
|
||||
expect(smbToUnc(r'\\nas\share'), isNull);
|
||||
expect(smbToUnc('D:/x'), isNull);
|
||||
if (!Platform.isWindows) return;
|
||||
final (path, error) = await ExplorerPage.checkPathForTest('smb://localhost/jj_no_such_share_190');
|
||||
expect(path, isNull);
|
||||
expect(error, contains(r'\\localhost\jj_no_such_share_190'));
|
||||
expect(error, contains('형식'));
|
||||
});
|
||||
|
||||
testWidgets('179: Android 에서 SMB 경로를 넣으면 "아직 지원하지 않음 · WebDAV" 안내와 [WebDAV 서버 추가]', (tester) async {
|
||||
ExplorerPage.debugAndroidPaths = true;
|
||||
addTearDown(() => ExplorerPage.debugAndroidPaths = null);
|
||||
|
|
|
|||
Loading…
Reference in New Issue