Guess GVFS folder based on keywords (see https://wiki.gnome.org/Projects/gvfs/doc)

This commit is contained in:
Reinhard Pointner 2016-11-18 23:51:13 +08:00
parent 9c2cfe9cf6
commit ca218231ba
5 changed files with 83 additions and 16 deletions

View File

@ -10,7 +10,7 @@ public interface GVFS {
File getPathForURI(URI uri); File getPathForURI(URI uri);
public static GVFS getDefaultVFS() { public static GVFS getDefaultVFS() {
return SystemProperty.of("net.filebot.gio.GVFS", PlatformGVFS::new, NativeGVFS::new).get(); return SystemProperty.of("net.filebot.gio.GVFS", path -> new PlatformGVFS(new File(path)), NativeGVFS::new).get();
} }
} }

View File

@ -17,10 +17,11 @@ public class NativeGVFS implements GVFS {
Pointer chars = lib_gio.g_file_get_path(gfile); Pointer chars = lib_gio.g_file_get_path(gfile);
try { try {
if (chars != null) if (chars != null) {
return new File(chars.getString(0)); return new File(chars.getString(0));
else }
return null;
throw new IllegalArgumentException("Failed to locate local path: " + uri);
} finally { } finally {
lib_gio.g_object_unref(gfile); lib_gio.g_object_unref(gfile);
lib_gio.g_free(chars); lib_gio.g_free(chars);

View File

@ -8,19 +8,43 @@ public class PlatformGVFS implements GVFS {
private final File gvfs; private final File gvfs;
public PlatformGVFS(String gvfs) { public PlatformGVFS(File gvfs) {
this.gvfs = new File(gvfs); if (gvfs.list() == null) {
throw new IllegalArgumentException(gvfs.getPath() + " is not a valid directory");
}
this.gvfs = gvfs;
} }
public File getPathForURI(URI uri) { public File getPathForURI(URI uri) {
// e.g. smb://10.0.1.5/data/Movies/Avatar.mp4 -> /run/user/1000/gvfs/smb-share:server=10.0.1.5,share=data/Movies/Avatar.mp4 if ("file".equals(uri.getScheme())) {
switch (uri.getScheme()) {
case "file":
return new File(uri); return new File(uri);
default:
return new File(gvfs, uri.getScheme() + "-share:server=" + uri.getHost() + ",share=" + uri.getPath().substring(1));
} }
// e.g. smb://10.0.1.5/data/Movies/Avatar.mp4 -> /run/user/1000/gvfs/smb-share:server=10.0.1.5,share=data/Movies/Avatar.mp4
// e.g. afp://reinhard@10.0.1.5/data/Movies/Avatar.mp4 -> /run/user/1000/gvfs/afp-volume:host=10.0.1.5,user=reinhard,volume=data/Movies/Avatar.mp4
// e.g. sftp://reinhard@10.0.1.5/home/Movies/Avatar.mp4 -> /run/user/1000/gvfs/sftp:host=10.0.1.5,user=reinhard/home/Movies/Avatar.mp4
// guess GVFS folder based on keywords (see https://wiki.gnome.org/Projects/gvfs/doc)
for (String mount : gvfs.list()) {
if (mount.startsWith(uri.getScheme()) && mount.contains(uri.getHost())) {
if (uri.getUserInfo() != null && !mount.contains(uri.getUserInfo()))
continue;
if (uri.getPort() > 0 && !mount.contains(String.valueOf(uri.getPort())))
continue;
String path = uri.getPath().substring(1);
String share = path.substring(0, path.indexOf('/'));
if (mount.endsWith(share)) {
path = path.substring(share.length()).substring(1);
}
return new File(new File(gvfs, mount), path);
}
}
throw new IllegalArgumentException("Failed to locate local path: " + uri);
} }
} }

View File

@ -107,8 +107,7 @@ public class FileTransferable implements Transferable {
} }
try { try {
URI uri = new URI(line); File file = GVFS.getDefaultVFS().getPathForURI(new URI(line));
File file = GVFS.getDefaultVFS().getPathForURI(uri);
if (file == null || !file.exists()) { if (file == null || !file.exists()) {
throw new FileNotFoundException(line); throw new FileNotFoundException(line);
@ -116,8 +115,7 @@ public class FileTransferable implements Transferable {
files.add(file); files.add(file);
} catch (Throwable e) { } catch (Throwable e) {
// URISyntaxException, IllegalArgumentException, FileNotFoundException, LinkageError, etc debug.warning(e::toString);
debug.warning("Invalid file URI: " + line);
} }
} }

View File

@ -0,0 +1,44 @@
package net.filebot.gio;
import static java.util.Arrays.*;
import static org.junit.Assert.*;
import java.io.File;
import java.net.URI;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class PlatformGVFSTest {
static File gvfsRoot = new File("gvfs");
static String[] shares = { "smb-share:server=10.0.1.5,share=data", "afp-volume:host=10.0.1.5,user=reinhard,volume=data", "sftp:host=myserver.org,user=nico" };
GVFS gvfs = new PlatformGVFS(gvfsRoot);
@BeforeClass
public static void before() throws Exception {
stream(shares).forEach(f -> new File(gvfsRoot, f).mkdirs());
}
@AfterClass
public static void after() throws Exception {
}
@Test
public void smb() throws Exception {
assertEquals("gvfs/smb-share:server=10.0.1.5,share=data/Movies/Avatar.mp4", gvfs.getPathForURI(new URI("smb://10.0.1.5/data/Movies/Avatar.mp4")).getPath());
}
@Test
public void afp() throws Exception {
assertEquals("gvfs/afp-volume:host=10.0.1.5,user=reinhard,volume=data/Movies/Avatar.mp4", gvfs.getPathForURI(new URI("afp://reinhard@10.0.1.5/data/Movies/Avatar.mp4")).getPath());
}
@Test
public void sftp() throws Exception {
assertEquals("gvfs/sftp:host=myserver.org,user=nico/home/Movies/Avatar.mp4", gvfs.getPathForURI(new URI("sftp://nico@myserver.org/home/Movies/Avatar.mp4")).getPath());
}
}