Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Gdrive shortcuts #377

Merged
merged 4 commits into from
Jun 17, 2024
Merged

Gdrive shortcuts #377

merged 4 commits into from
Jun 17, 2024

Conversation

Jackabomb
Copy link
Contributor

@Jackabomb Jackabomb commented Apr 22, 2023

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 then My 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 like My 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.

-GetChildrenByParentItem now resolves (aka "passes-through") shortcuts.
-That is, it knows how to identify shortcuts and returns the object they point to rather than the zero-byte, fairly useless shortcut itself.
-Shortcuts appear as the type (file vs. folder) of the underlying target and can be navigated and chosen in the open from cloud dialog.
-Added shortcut dereferencing to GetFileByPath. This makes shortcuts work with opening and saving.
Note that copy and delete might not do what you expect. They will operate on the final target, not on the shortcut itself.
In particular, if you try to delete a shortcut to a folder, KeeAnywhere will instead try to delete the underlying real folder!
This will fail for folders not owned by you (i.e. shared with you, with a shortcut in My Drive), but it may succeed for your own shortcut-ed (i.e. symlinked) folders!
Be warned! This behavior should probably be considered a defect and fixed.
…nderlying file/folder.

Added a resolveFinalShortcut parameter to GetFileByPath so that we can select whether or not the last element in a path should be resolved or not.
If this parameter is set to true, shortcuts are always resolved, and the underlying file is always returned.
If this parameter is set to false, shortcuts in the path are resolved, but not the last element.
Added nextPageToken to the fields being requested.
I forgot that if I don't put it in the request fields, it will *always*
be set to null. Downside of using the Fields parameter is, you have to
put everything in there manually, or you won't have it.
@Jackabomb
Copy link
Contributor Author

Also fixes #379.

@Kyrodan Kyrodan added this to the 2.1.0 milestone Jun 17, 2024
@Kyrodan Kyrodan merged commit 8a1e1f7 into Kyrodan:master Jun 17, 2024
@Jackabomb
Copy link
Contributor Author

Hooray! Thank you! It is exciting to see this merged in! It is my first accepted PR.

# for free to join this conversation on GitHub. Already have an account? # to comment