Skip to content

Commit

Permalink
Merge pull request #9 from umjammer/develop
Browse files Browse the repository at this point in the history
0.0.6
  • Loading branch information
umjammer authored Mar 4, 2020
2 parents a65ee0d + c4d8029 commit 5115e83
Show file tree
Hide file tree
Showing 17 changed files with 344 additions and 53 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ fuse for java and many file systems.
| hfs+ (dmg) || | | | | | | | | [hfsexplorer](https://github.com/umjammer/hfsexplorer) |
| gathered || | | | | | | | | |
| cyberduck || | | | | | | | | [vavi-nio-file-cyberduck](https://github.com/umjammer/vavi-nio-file-cyberduck), [cyberduck](https://github.com/iterate-ch/cyberduck) |
| discutils (vhd/ntfs) || | | | | | | | | [vavi-nio-file-discutils](https://github.com/umjammer/vavi-nio-file-discutils) |
| discutils (vdi/ntfs) || | | | | | | | | [vavi-nio-file-discutils](https://github.com/umjammer/vavi-nio-file-discutils) |


# TODO
Expand Down
13 changes: 9 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,18 @@

<groupId>vavi</groupId>
<artifactId>vavi-apps-fuse</artifactId>
<version>0.0.6-SNAPSHOT</version>
<version>0.0.6</version>
<packaging>jar</packaging>

<name>vavi-apps-fuse</name>
<url>https://github.com/umjammer/vavi-apps-fuse</url>
<description>0.0.5
<description>0.0.6

improve google drive
add google drive ocr capability
gatheredfs alias

0.0.5

relive fuse-jna as generic
make onedrive (cyberduck engine) work
Expand Down Expand Up @@ -43,8 +49,7 @@ TODO

apple photos.app

google automatic authentication (how to click button)
</description>
google automatic authentication (how to click button)</description>
<scm>
<url>https://github.com/umjammer/vavi-apps-fuse</url>
</scm>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public FileTime lastModifiedTime() {
if (FileSystem.class.isInstance(entry)) {
return FileTime.fromMillis(0);
} else if (Path.class.isInstance(entry)) {
System.err.println("@@@: " + entry + ", " + Path.class.cast(entry).getFileSystem().provider());
return Files.getLastModifiedTime(Path.class.cast(entry));
} else {
throw new IllegalStateException("unsupported type: " + entry.getClass().getName());
Expand Down
32 changes: 29 additions & 3 deletions src/main/java/vavi/nio/file/gathered/GatheredFileSystemDriver.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@

import com.github.fge.filesystem.driver.UnixLikeFileSystemDriverBase;
import com.github.fge.filesystem.provider.FileSystemFactoryProvider;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;

import vavi.nio.file.Util;
import vavi.util.Debug;
Expand All @@ -53,15 +55,21 @@ public final class GatheredFileSystemDriver extends UnixLikeFileSystemDriverBase
/** should be unaccessible from outer */
private final Map<String, FileSystem> fileSystems;

private BiMap<String, String> nameMap;

/**
* @param env
*/
@SuppressWarnings("unchecked")
public GatheredFileSystemDriver(final FileStore fileStore,
final FileSystemFactoryProvider provider,
final Map<String, FileSystem> fileSystems,
final Map<String, ?> env) throws IOException {
super(fileStore, provider);
this.fileSystems = fileSystems;
if (env.containsKey(GatheredFileSystemProvider.ENV_NAME_MAP)) {
this.nameMap = HashBiMap.create(Map.class.cast(env.get(GatheredFileSystemProvider.ENV_NAME_MAP)));
}
}

@Nonnull
Expand Down Expand Up @@ -144,13 +152,31 @@ public Object getPathMetadata(final Path path) throws IOException {
}
}

/** id -> display name */
private String encodeFsName(String id) throws IOException {
if (nameMap != null) {
return nameMap.get(id);
} else {
return URLEncoder.encode(id, "utf-8");
}
}

/** display name -> id */
private String decodeFsName(String path) throws IOException {
if (nameMap != null) {
return nameMap.inverse().get(path);
} else {
return URLDecoder.decode(path, "utf-8");
}
}

/** */
private List<Path> getDirectoryEntries(final Path dir) throws IOException {
if (dir.getNameCount() == 0) {
List<Path> list = new ArrayList<>(fileSystems.size());

for (String id : fileSystems.keySet()) {
Path childPath = dir.resolve(URLEncoder.encode(id, "utf-8"));
Path childPath = dir.resolve(encodeFsName(id));
list.add(childPath);
}

Expand All @@ -161,12 +187,12 @@ private List<Path> getDirectoryEntries(final Path dir) throws IOException {
}

/** */
private FileSystem getFileSystemOf(Path path) throws IOException {
FileSystem getFileSystemOf(Path path) throws IOException {
Debug.println("path: " + path);
if (path.getNameCount() == 0) {
return path.getFileSystem();
} else {
String first = URLDecoder.decode(path.getName(0).toString(), "utf-8");
String first = decodeFsName(path.getName(0).toString());
Debug.println("first: " + first);
if (!fileSystems.containsKey(first)) {
throw new NoSuchFileException(path.toString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public final class GatheredFileSystemProvider extends FileSystemProviderBase {

public static final String ENV_FILESYSTEMS = "fileSystems";

public static final String ENV_NAME_MAP = "nameMap";

public GatheredFileSystemProvider() {
super(new GatheredFileSystemRepository());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,4 @@ public FileSystemDriver createDriver(final URI uri, final Map<String, ?> env) th
GatheredFileStore fileStore = new GatheredFileStore(factoryProvider.getAttributesFactory());
return new GatheredFileSystemDriver(fileStore, factoryProvider, fileSystems, env);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@ public enum GoogleDriveCopyOption implements CopyOption {
EXPORT_AS_GDOCS("application/vnd.google-apps.document");

/** */
private String mimeType;
private String value;

/** */
private GoogleDriveCopyOption(String mimeType) {
this.mimeType = mimeType;
private GoogleDriveCopyOption(String value) {
this.value = value;
}

/** */
public String getMimeType() {
return mimeType;
public String getValue() {
return value;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,10 @@ public GoogleDriveFileSystemDriver(final FileStore fileStore,
{
// TODO datetime
// File root = drive.files().get("fileId=root").execute();
entryCache.put("/", new File().setName("/").setId("root").setMimeType(MIME_TYPE_DIR).setModifiedTime(new DateTime(0)).setSize(0L));
entryCache.put("/", new File().setName("/").setId("root").setMimeType(MIME_TYPE_DIR).setModifiedTime(new DateTime(System.currentTimeMillis())).setSize(0L));
}

/**
* TODO when the parent is not cached
* @see #ignoreAppleDouble
*/
public File getEntry(Path path) throws IOException {
Expand All @@ -107,14 +106,30 @@ public File getEntry(Path path) throws IOException {
throw new NoSuchFileException("ignore apple double file: " + path);
}

File entry = drive.files().get(toPathString(path)).execute(); // TODO
File entry;
if (path.getNameCount() == 0) {
entry = drive.files().get(toPathString(path)).execute();
cache.putFile(path, entry);
return entry;
} else {
List<Path> siblings;
if (!cache.containsFolder(path.getParent())) {
siblings = getDirectoryEntries(path.getParent());
} else {
siblings = cache.getFolder(path.getParent());
}
for (int i = 0; i < siblings.size(); i++) { // avoid ConcurrentModificationException
Path p = siblings.get(i);
if (p.getFileName().equals(path.getFileName())) {
return cache.getEntry(p);
}
}
throw new NoSuchFileException(path.toString());
}
//System.err.println("GOT: path: " + path + ", id: " + entry.getId());
cache.putFile(path, entry);
return entry;
}
} catch (GoogleJsonResponseException e) {
if (e.getMessage().startsWith("404")) {
// TODO when a deep directory is specified at first, like '/Books/Novels'
// cache
if (cache.containsFile(path)) {
cache.removeEntry(path);
Expand Down Expand Up @@ -148,9 +163,15 @@ public InputStream newInputStream(final Path path, final Set<? extends OpenOptio
throw new IsDirectoryException("path: " + path);
}

// TODO
// TODO detect automatically?
ByteArrayOutputStream baos = new ByteArrayOutputStream();
drive.files().get(entry.getId()).executeMediaAndDownloadTo(baos);
if (options.stream().anyMatch(o -> GoogleDriveOpenOption.class.isInstance(o))) {
GoogleDriveOpenOption option = GoogleDriveOpenOption.class
.cast(options.stream().filter(o -> GoogleDriveOpenOption.class.isInstance(o)).findFirst().get());
drive.files().export(entry.getId(), option.getValue()).executeMediaAndDownloadTo(baos);
} else {
drive.files().get(entry.getId()).executeMediaAndDownloadTo(baos);
}
return new ByteArrayInputStream(baos.toByteArray());
}

Expand All @@ -171,11 +192,11 @@ public OutputStream newOutputStream(final Path path, final Set<? extends OpenOpt
options.forEach(o -> { System.err.println("newOutputStream: " + o); });
}

// TODO mime type
if (options.stream().anyMatch(o -> GoogleDriveCopyOption.class.isInstance(o))) {
String mimeType = options.stream()
.filter(o -> GoogleDriveCopyOption.class.isInstance(o))
.map(o -> GoogleDriveCopyOption.class.cast(o).getMimeType()).findFirst().get();
// TODO detect automatically?
if (options.stream().anyMatch(o -> GoogleDriveOpenOption.class.isInstance(o))) {
@SuppressWarnings("unused")
GoogleDriveOpenOption option = GoogleDriveOpenOption.class
.cast(options.stream().filter(o -> GoogleDriveOpenOption.class.isInstance(o)).findFirst().get());
}

return new Util.OutputStreamForUploading() {
Expand Down Expand Up @@ -272,7 +293,7 @@ protected long getLeftOver() throws IOException {
@Override
public void close() throws IOException {
if (lock != null) {
System.out.println("SeekableByteChannelForWriting::close: scpecial: " + path);
System.out.println("SeekableByteChannelForWriting::close: scpecial: " + path);
return;
}
super.close();
Expand Down Expand Up @@ -321,7 +342,7 @@ public void copy(final Path source, final Path target, final Set<CopyOption> opt
}
}

copyEntry(source, target);
copyEntry(source, target, options);
}

@Override
Expand Down Expand Up @@ -464,13 +485,16 @@ private void removeEntry(Path path) throws IOException {
}

/** */
private void copyEntry(final Path source, final Path target) throws IOException {
private void copyEntry(final Path source, final Path target, Set<CopyOption> options) throws IOException {
final File sourceEntry = cache.getEntry(source);
File targetParentEntry = cache.getEntry(target.getParent());
if (!isFolder(sourceEntry)) {
File entry = new File();
entry.setName(toFilenameString(target));
entry.setParents(Arrays.asList(targetParentEntry.getId()));
if (options.stream().anyMatch(o -> o.equals(GoogleDriveCopyOption.EXPORT_AS_GDOCS))) {
entry.setMimeType(GoogleDriveCopyOption.EXPORT_AS_GDOCS.getValue());
}
File newEntry = drive.files().copy(sourceEntry.getId(), entry)
.setFields("id, parents, name, size, mimeType, createdTime").execute();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public class GoogleDriveFileSystemOptionsFactory extends FileSystemOptionsFactor

public GoogleDriveFileSystemOptionsFactory() {
addLinkOption(LinkOption.NOFOLLOW_LINKS);
addCopyOption(GoogleDriveCopyOption.EXPORT_AS_GDOCS);
addReadOpenOption(GoogleDriveOpenOption.EXPORT_WITH_GDOCS_DOCX);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import com.github.fge.filesystem.driver.FileSystemDriver;
import com.github.fge.filesystem.provider.FileSystemRepositoryBase;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.services.drive.Drive;

import vavi.net.auth.oauth2.google.GoogleAuthenticator;
Expand Down Expand Up @@ -74,8 +76,16 @@ public FileSystemDriver createDriver(final URI uri, final Map<String, ?> env) th
GoogleAuthenticator<Credential> authenticator = getAuthenticator();
Credential credential = authenticator.authorize(email);
Drive drive = new Drive.Builder(authenticator.getHttpTransport(), authenticator.getJsonFactory(), credential)
.setApplicationName(APPLICATION_NAME)
.build();
.setHttpRequestInitializer(new HttpRequestInitializer() {
@Override
public void initialize(HttpRequest httpRequest) throws IOException {
credential.initialize(httpRequest);
httpRequest.setConnectTimeout(30 * 1000);
httpRequest.setReadTimeout(30 * 1000);
}
})
.setApplicationName(APPLICATION_NAME)
.build();

GoogleDriveFileStore fileStore = new GoogleDriveFileStore(drive, factoryProvider.getAttributesFactory());
return new GoogleDriveFileSystemDriver(fileStore, factoryProvider, drive, env);
Expand Down
37 changes: 37 additions & 0 deletions src/main/java/vavi/nio/file/googledrive/GoogleDriveOpenOption.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2017 by Naohide Sano, All rights reserved.
*
* Programmed by Naohide Sano
*/

package vavi.nio.file.googledrive;

import java.nio.file.OpenOption;


/**
* GoogleDriveOpenOption.
*
* @author <a href="mailto:[email protected]">Naohide Sano</a> (umjammer)
* @version 0.00 2017/03/01 umjammer initial version <br>
*/
public enum GoogleDriveOpenOption implements OpenOption {

EXPORT_WITH_GDOCS_DOCX("application/vnd.openxmlformats-officedocument.wordprocessingml.document"),
EXPORT_WITH_GDOCS_XLSX("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");

/** */
private String value;

/** */
private GoogleDriveOpenOption(String value) {
this.value = value;
}

/** */
public String getValue() {
return value;
}
}

/* */
Loading

0 comments on commit 5115e83

Please sign in to comment.