Flow.Launcher icon indicating copy to clipboard operation
Flow.Launcher copied to clipboard

Feature: Add support for local plugin installation

Open flooxo opened this issue 1 year ago • 21 comments

This PR closes #2252.

Description

The new method uses plugin.UrlDownload to store the local path of the zip file. First, the corresponding values are read from the plugin.json file. Then it is installed like any other plugin, except that the zip file is not downloaded.

Changes

Add a new method so that plugins can now also be installed locally from a zip file Example: pm install c:\plugin.zip.

flooxo avatar Feb 01 '24 16:02 flooxo

Open questions

  • [ ] The icon is not displayed correctly in the installation command because the path from the zip file cannot be used
  • [ ] How should update recommendations be handled (should it also be possible to use pm update <localPath>, as this is automatically suggested if the plugin is already installed)
  • [ ] After the installation the zip is always deleted, which may not be desired, how to avoid this?

flooxo avatar Feb 01 '24 16:02 flooxo

I am thinking:

The icon is not displayed correctly in the installation command because the path from the zip file cannot be used

Use a custom icon, or can we load the zip icon?

How should update recommendations be handled (should it also be possible to use pm update <localPath>, as this is automatically suggested if the plugin is already installed)

Detect if it's local path, think Explorer plugin already has code to detect if it's local/network path. We can reuse it but move it to the SharedCommands folder in the Plugin project.

After the installation the zip is always deleted, which may not be desired, how to avoid this?

Cleaning up the zip file is by design when downloaded from URL. If local/network path is detected, skip this step.

jjw24 avatar Feb 04 '24 02:02 jjw24

Use a custom icon, or can we load the zip icon?

The problem with the icon is that the path to the png would be correct, but it has to be unzipped before it can be displayed. For this it would have to be temporary stored. I think the easiest way is to simply display a custom icon

Detect if it's local path, think Explorer plugin already has code to detect if it's local/network path. We can reuse it but move it to the SharedCommands folder in the Plugin project.

Unfortunately I have not found a method in Explorer to detect if it is a local path (currently I use File.Exsits and sometimes Path.GetTempPath() to check if its a local file) But there is a lot of redundant code in the update, because especially the prompts are always the same for update from a local file, a single update and update all.

Cleaning up the zip file is by design when downloaded from URL. If local/network path is detected, skip this step.

Thanks

flooxo avatar Feb 04 '24 16:02 flooxo

@check-spelling-bot Report

:red_circle: Please review

See the :open_file_folder: files view, the :scroll:action log, or :memo: job summary for details.

Unrecognized words (25)
alreadyexists
Appwrite
Caculator
CETYU
cxfksword
duckduckgo
errormetadatafile
facebook
findicon
gmail
hotkeys
Ioannis
localappdata
Newtonsoft
noresult
pluginsmanager
Prioritise
qianlifeng
Sekan
Softpedia
stackoverflow
winget
wolframalpha
youtube
zipfolder
To accept these unrecognized words as correct, you could run the following commands

... in a clone of the [email protected]:flooxo/Flow.Launcher.git repository on the local_install branch (:information_source: how do I use this?):

curl -s -S -L 'https://raw.githubusercontent.com/check-spelling/check-spelling/prerelease/apply.pl' |
perl - 'https://github.com/Flow-Launcher/Flow.Launcher/actions/runs/7775420189/attempts/1'
Warnings (1)

See the :open_file_folder: files view, the :scroll:action log, or :memo: job summary for details.

:information_source: Warnings Count
:information_source: non-alpha-in-dictionary 10

See :information_source: Event descriptions for more information.

If the flagged items are :exploding_head: false positives

If items relate to a ...

  • binary file (or some other file you wouldn't want to check at all).

    Please add a file path to the excludes.txt file matching the containing file.

    File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

    ^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

  • well-formed pattern.

    If you can write a pattern that would match it, try adding it to the patterns.txt file.

    Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

    Note that patterns can't match multiline strings.

github-actions[bot] avatar Feb 04 '24 16:02 github-actions[bot]

The problem with the icon is that the path to the png would be correct, but it has to be unzipped before it can be displayed. For this it would have to be temporary stored. I think the easiest way is to simply display a custom icon

Yeah that's what I mean, custom icon or just load the icon of the zip file?

jjw24 avatar Feb 05 '24 02:02 jjw24

Yes, thanks, I have done that

flooxo avatar Feb 05 '24 19:02 flooxo

Where are the other icons from? Maybe I need to either add attribution (but I don't know where) or use a different icon since this icon uses the "flaticon license" which is free for commercial use but requires attribution

flooxo avatar Feb 06 '24 17:02 flooxo

@onesounds could you please lend a hand with icons?

Garulf avatar Feb 06 '24 19:02 Garulf

Unfortunately I have not found a method in Explorer to detect if it is a local path (currently I use File.Exsits and sometimes Path.GetTempPath() to check if its a local file) But there is a lot of redundant code in the update, because especially the prompts are always the same for update from a local file, a single update and update all.

@flooxo this is what you need: https://github.com/Flow-Launcher/Flow.Launcher/blob/73f2c3b5038fb67dd547254352a6926f9e533aea/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs#L207

jjw24 avatar Feb 06 '24 21:02 jjw24

The new method uses plugin.UrlDownload to store the local path of the zip file. First, the corresponding values are read from the plugin.json file. Then it is installed like any other plugin, except that the zip file is not downloaded.

Could you explain why we need a local path in the plugin's manifest? Shouldn't allowing pm install <local path> be enough?

Garulf avatar Feb 11 '24 07:02 Garulf

The local path is required because when calling InstallOrUpdateAsync it is no longer possible to access the local path as this is not passed anywhere. However, the local path determines whether the plugin must be installed or downloaded first. And also in the case of updating the existing plugin, the local path must be reused to suggest pm update <local path>. If that makes sense :)

flooxo avatar Feb 20 '24 13:02 flooxo

@flooxo this is what you need: https://github.com/Flow-Launcher/Flow.Launcher/blob/73f2c3b5038fb67dd547254352a6926f9e533aea/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs#L207

Thanks! But this function does not check whether the location exists, which is crucial.

flooxo avatar Feb 20 '24 13:02 flooxo

Would it be best to use pm install at the new zip file for updates?

Garulf avatar Feb 20 '24 15:02 Garulf

What would be the advantage of this? The difference is that once PluginManager.UpdatePlugin and otherwise PluginManager.InstallPlugin is used. And update ensures that the old version is deleted first. So I would say pm update is fitting here

flooxo avatar Feb 20 '24 21:02 flooxo

@flooxo this is what you need: https://github.com/Flow-Launcher/Flow.Launcher/blob/73f2c3b5038fb67dd547254352a6926f9e533aea/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs#L207

Thanks! But this function does not check whether the location exists, which is crucial.

This method is best used to check if the query string is a location path, if not then proceed to download, if it is then you do a separate call to check if the file actually exists. This is so you don't end up checking file exists on disk per every query string.

So call that function on the passed in query string, if is location path then call this https://github.com/Flow-Launcher/Flow.Launcher/blob/73f2c3b5038fb67dd547254352a6926f9e533aea/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs#L141

jjw24 avatar Feb 21 '24 10:02 jjw24

What would be the advantage of this? The difference is that once PluginManager.UpdatePlugin and otherwise PluginManager.InstallPlugin is used. And update ensures that the old version is deleted first. So I would say pm update is fitting here

Not sure if I am understanding correctly, but I would say the expected user experience would be to use pm install <file_path> to install and pm update <file_path> to update.

jjw24 avatar Feb 21 '24 10:02 jjw24

Just a thought, whether pm update is a necessity here? If you need to constantly update your plugin from local file path, it would be when you are developing a plugin? Wouldn't be better to just dump/install the plugin into the plugins folder and open up the project from there anyway? Just a question more or less.

jjw24 avatar Feb 21 '24 10:02 jjw24

Yes, sure. I've already thought about this point, but I think if you can install a plugin locally, then it should also be possible to update it for the sake of completeness. Of course, it would be easier to simply drag it into the folder.

flooxo avatar Feb 24 '24 09:02 flooxo

Hey @flooxo I would like to make a couple changes and refactor the code on this PR, do you like me to commit them here directly or show you via a new PR?

jjw24 avatar May 11 '24 04:05 jjw24

Hey @flooxo I would like to make a couple changes and refactor the code on this PR, do you like me to commit them here directly or show you via a new PR?

Feel free to commit them directly here to keep things simple :)

flooxo avatar May 11 '24 19:05 flooxo

@flooxo hey I pushed my changes, they include:

  • the zip file no longer gets deleted. Added an extra property to UserPlugin class to hold and determine a local install.
  • moved the zip file read method into utilities class so no need to write the code in with the install/update methods
  • created a new method to determine zip file path

Let me know if you see any issues with them.

jjw24 avatar May 16 '24 12:05 jjw24

Nice, LGTM :)

flooxo avatar May 19 '24 08:05 flooxo