14
14
using System . Threading ;
15
15
using System . Threading . Tasks ;
16
16
using System . Windows ;
17
+ using System . IO . Compression ;
18
+ using Newtonsoft . Json ;
17
19
18
20
namespace Flow . Launcher . Plugin . PluginsManager
19
21
{
@@ -138,6 +140,12 @@ internal async Task InstallOrUpdateAsync(UserPlugin plugin)
138
140
MessageBoxButton . YesNo ) == MessageBoxResult . No )
139
141
return ;
140
142
143
+ if ( File . Exists ( plugin . UrlDownload ) )
144
+ {
145
+ Install ( plugin , plugin . UrlDownload ) ;
146
+ return ;
147
+ }
148
+
141
149
// at minimum should provide a name, but handle plugin that is not downloaded from plugins manifest and is a url download
142
150
var downloadFilename = string . IsNullOrEmpty ( plugin . Version )
143
151
? $ "{ plugin . Name } -{ Guid . NewGuid ( ) } .zip"
@@ -470,6 +478,54 @@ internal List<Result> InstallFromWeb(string url)
470
478
return new List < Result > { result } ;
471
479
}
472
480
481
+ internal List < Result > InstallFromLocal ( string path )
482
+ {
483
+ if ( string . IsNullOrEmpty ( path ) || ! File . Exists ( path ) )
484
+ {
485
+ return new List < Result > ( ) ;
486
+ }
487
+
488
+ var plugin = null as UserPlugin ;
489
+
490
+ using ( ZipArchive archive = ZipFile . OpenRead ( path ) )
491
+ {
492
+ var pluginJsonPath = archive . Entries . FirstOrDefault ( x => x . Name == "plugin.json" ) . ToString ( ) ;
493
+ ZipArchiveEntry pluginJsonEntry = archive . GetEntry ( pluginJsonPath ) ;
494
+
495
+ if ( pluginJsonEntry != null )
496
+ {
497
+ using ( StreamReader reader = new StreamReader ( pluginJsonEntry . Open ( ) ) )
498
+ {
499
+ string pluginJsonContent = reader . ReadToEnd ( ) ;
500
+ plugin = JsonConvert . DeserializeObject < UserPlugin > ( pluginJsonContent ) ;
501
+ plugin . IcoPath = Path . Combine ( path , pluginJsonEntry . FullName . Split ( '/' ) [ 0 ] , plugin . IcoPath ) ;
502
+ }
503
+ }
504
+ }
505
+
506
+ if ( plugin == null )
507
+ {
508
+ return new List < Result > ( ) ;
509
+ }
510
+
511
+ plugin . UrlDownload = path ;
512
+
513
+ var result = new Result
514
+ {
515
+ Title = plugin . Name ,
516
+ SubTitle = plugin . UrlDownload ,
517
+ IcoPath = plugin . IcoPath ,
518
+ Action = e =>
519
+ {
520
+ Application . Current . MainWindow . Hide ( ) ;
521
+ _ = InstallOrUpdateAsync ( plugin ) ;
522
+
523
+ return ShouldHideWindow ;
524
+ }
525
+ } ;
526
+ return new List < Result > { result } ;
527
+ }
528
+
473
529
private bool InstallSourceKnown ( string url )
474
530
{
475
531
var author = url . Split ( '/' ) [ 3 ] ;
@@ -489,6 +545,9 @@ internal async ValueTask<List<Result>> RequestInstallOrUpdate(string search, Can
489
545
&& search . Split ( '.' ) . Last ( ) == zip )
490
546
return InstallFromWeb ( search ) ;
491
547
548
+ if ( File . Exists ( search ) && search . Split ( '.' ) . Last ( ) == zip )
549
+ return InstallFromLocal ( search ) ;
550
+
492
551
var results =
493
552
PluginsManifest
494
553
. UserPlugins
0 commit comments