From 8aee1e9e85d3ba65c109590bfba209ab2dd2c7b8 Mon Sep 17 00:00:00 2001 From: Reinhard Pointner Date: Wed, 23 Jan 2019 15:36:53 +0700 Subject: [PATCH] Improved support for File DnD on Linux if File URIs are not escaped correctly (i.e. contain literal [ or ] in the File URI which is not allowed as per URI spec). See https://www.filebot.net/forums/viewtopic.php?f=11&t=9651 --- source/net/filebot/platform/gnome/GVFS.java | 3 +-- .../filebot/platform/gnome/NativeGVFS.java | 7 +++---- .../filebot/platform/gnome/PlatformGVFS.java | 20 +++++++++++++++++-- .../filebot/ui/transfer/FileTransferable.java | 3 +-- test/net/filebot/gio/PlatformGVFSTest.java | 17 +++++++++------- 5 files changed, 33 insertions(+), 17 deletions(-) diff --git a/source/net/filebot/platform/gnome/GVFS.java b/source/net/filebot/platform/gnome/GVFS.java index 7f3d0d62..6b73909c 100644 --- a/source/net/filebot/platform/gnome/GVFS.java +++ b/source/net/filebot/platform/gnome/GVFS.java @@ -1,13 +1,12 @@ package net.filebot.platform.gnome; import java.io.File; -import java.net.URI; import net.filebot.util.SystemProperty; public interface GVFS { - File getPathForURI(URI uri); + File getPathForURI(String resource); public static GVFS getDefaultVFS() { GVFS gvfs = SystemProperty.of("net.filebot.gio.GVFS", path -> new PlatformGVFS(new File(path))).get(); diff --git a/source/net/filebot/platform/gnome/NativeGVFS.java b/source/net/filebot/platform/gnome/NativeGVFS.java index c593fc85..fc56ede4 100644 --- a/source/net/filebot/platform/gnome/NativeGVFS.java +++ b/source/net/filebot/platform/gnome/NativeGVFS.java @@ -2,7 +2,6 @@ package net.filebot.platform.gnome; import java.io.File; -import java.net.URI; import com.sun.jna.Native; import com.sun.jna.Pointer; @@ -12,8 +11,8 @@ public class NativeGVFS implements GVFS { private static final LibGIO lib_gio = (LibGIO) Native.loadLibrary("gio-2.0", LibGIO.class); private static final Pointer gvfs = lib_gio.g_vfs_get_default(); - public File getPathForURI(URI uri) { - Pointer gfile = lib_gio.g_vfs_get_file_for_uri(gvfs, uri.toString()); + public File getPathForURI(String resource) { + Pointer gfile = lib_gio.g_vfs_get_file_for_uri(gvfs, resource); Pointer chars = lib_gio.g_file_get_path(gfile); try { @@ -21,7 +20,7 @@ public class NativeGVFS implements GVFS { return new File(chars.getString(0)); } - throw new IllegalArgumentException("Failed to locate local path: " + uri); + throw new IllegalArgumentException("Failed to locate local path: " + resource); } finally { lib_gio.g_object_unref(gfile); lib_gio.g_free(chars); diff --git a/source/net/filebot/platform/gnome/PlatformGVFS.java b/source/net/filebot/platform/gnome/PlatformGVFS.java index 5504ebf1..e4aa9e37 100644 --- a/source/net/filebot/platform/gnome/PlatformGVFS.java +++ b/source/net/filebot/platform/gnome/PlatformGVFS.java @@ -6,6 +6,7 @@ import static java.util.stream.Collectors.*; import java.io.File; import java.net.URI; +import java.net.URISyntaxException; import java.util.List; public class PlatformGVFS implements GVFS { @@ -16,8 +17,23 @@ public class PlatformGVFS implements GVFS { this.gvfs = gvfs; } - public File getPathForURI(URI uri) { - return Protocol.forName(uri.getScheme()).getFile(gvfs, uri); + public File getPathForURI(String resource) { + return getPathForURI(parseURI(resource)); + } + + public File getPathForURI(URI resource) { + return Protocol.forName(resource.getScheme()).getFile(gvfs, resource); + } + + public URI parseURI(String resource) { + try { + // DIRTY WORK AROUND: Square Brackets [] are reserved as per RFC2732 but some file managers (e.g. KDE Dolphin) don't URI encode them correctly + resource = resource.replace("[", "%5B").replace("]", "%5D"); + + return new URI(resource); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } } @Override diff --git a/source/net/filebot/ui/transfer/FileTransferable.java b/source/net/filebot/ui/transfer/FileTransferable.java index e6be3dcf..12c86603 100644 --- a/source/net/filebot/ui/transfer/FileTransferable.java +++ b/source/net/filebot/ui/transfer/FileTransferable.java @@ -11,7 +11,6 @@ import java.awt.datatransfer.UnsupportedFlavorException; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; -import java.net.URI; import java.nio.CharBuffer; import java.util.ArrayList; import java.util.Arrays; @@ -112,7 +111,7 @@ public class FileTransferable implements Transferable { } try { - File file = GVFS.getDefaultVFS().getPathForURI(new URI(line)); + File file = GVFS.getDefaultVFS().getPathForURI(line); if (file == null || !file.exists()) { throw new FileNotFoundException(file.getPath()); diff --git a/test/net/filebot/gio/PlatformGVFSTest.java b/test/net/filebot/gio/PlatformGVFSTest.java index 582e1efc..ed0a74b0 100644 --- a/test/net/filebot/gio/PlatformGVFSTest.java +++ b/test/net/filebot/gio/PlatformGVFSTest.java @@ -3,31 +3,34 @@ package net.filebot.gio; import static org.junit.Assert.*; import java.io.File; -import java.net.URI; import org.junit.Test; -import net.filebot.platform.gnome.GVFS; import net.filebot.platform.gnome.PlatformGVFS; public class PlatformGVFSTest { - GVFS gvfs = new PlatformGVFS(new File("gvfs")); + PlatformGVFS gvfs = new PlatformGVFS(new File("gvfs")); @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()); - assertEquals("gvfs/smb-share:server=192.168.0.1,share=test/a file with spaces.txt", gvfs.getPathForURI(new URI("smb://192.168.0.1/test/a%20file%20with%20spaces.txt")).getPath()); + assertEquals("gvfs/smb-share:server=10.0.1.5,share=data/Movies/Avatar.mp4", gvfs.getPathForURI("smb://10.0.1.5/data/Movies/Avatar.mp4").getPath()); + assertEquals("gvfs/smb-share:server=192.168.0.1,share=test/a file with spaces.txt", gvfs.getPathForURI("smb://192.168.0.1/test/a%20file%20with%20spaces.txt").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()); + assertEquals("gvfs/afp-volume:host=10.0.1.5,user=reinhard,volume=data/Movies/Avatar.mp4", gvfs.getPathForURI("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()); + assertEquals("gvfs/sftp:host=myserver.org,user=nico/home/Movies/Avatar.mp4", gvfs.getPathForURI("sftp://nico@myserver.org/home/Movies/Avatar.mp4").getPath()); + } + + @Test + public void fileWithSquareBrackets() throws Exception { + assertEquals("/home/media/Alias - 1x01 - [test].mp4", gvfs.parseURI("file:///home/media/Alias%20-%201x01%20-%20[test].mp4").getPath()); } }