Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR implements shortcuts for Google Drive.
Both shortcuts to files and shortcuts to folders are supported. Multiple folder-shortcuts in a path are supported. The target files and folders can be on your own drive or under "shared with me", but Shared Drive support (a GSuite feature) is another matter.
Fixes #223, fixes #232, fixes #310, fixes #337, fixes #339, fixes #356, and fixes #379. Or at least provides a workaround.
With shortcuts, users will now be have a way to access shared files, which I know is very useful for users like me who want to share databases! We can create a shortcut to the shared file or folder in our own drive and access the file(s) that way.
Method and Rationale
This PR first adds the ability to recognize shortcuts by their unique mime type, "application/vnd.google-apps.shortcut".
Next, when parsing the Google Drive tree for the "Open from Cloud" dialog, I treat shortcuts specially: a shortcut returns the data for its target instead of itself. Basically, the rest of KeeAnywhere has no idea shortcuts even exist. The Google Drive layer pretends that the files were directly included in that directory, kind of like hard links. I understand this is similar to the original structure Google Drive used, which shortcuts were introduced to replace.
Finally, load, save, copy, and delete are modified to also transparently follow shortcuts anywhere in the URL path. Again, this presents a view of the tree rather like hard-links in UNIX. (Technically, this change is implemented in the GetFileByPath routine that all four rely on)
Caveats
There is one exception. Delete will delete the shortcut itself if the shortcut is the last item in the path. Why? Think what would happen if I tried to delete
My Drive/foo.kdbx
. If we delete the underlying file thenMy Drive/foo.kdbx
won't be deleted at all, because it represents the shortcut. In fact, it will stay there forever! But some other file likeMy Drive/this/is/some/buried/folder/foo.kdbx
would disappear instead! This would not be the expected behavior at all! For now, I think it's a moot point. I see delete is only called by the remote backup routine. The URLs it passes always point to real files, previously created by the backup function. But if delete ever becomes used more widely, we'll be ready to do it right.Also, because shortcuts are exposed as "hard-link" style items, there's no way to know from the interface (file picker UI) if something is a shortcut or not. They look the same as "real" files and folders. I think this is not so bad for now, because at least it works now and also that's how it used to be before Google started changing everything over to shortcuts.
Conclusion and Help Needed
A lot of time and effort went into this PR for me, because I am not used to .NET or C#. But I really love using this plugin and want to help!
I would really appreciate someone looking over this to see if it makes sense or if I missed a better way to do things. This is a bigger change than I have made so far. It involved some tricky stuff I'm not sure I got right, particularly with the asynchronous programming stuff and the Select calls in GetChildrenByParentPath.