2020-08-18 01:00:56 +08:00
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System ;
using System.Collections.Generic ;
using System.Diagnostics ;
using System.Linq ;
using System.Threading.Tasks ;
using Microsoft.Plugin.Program.Programs ;
using Microsoft.Plugin.Program.Storage ;
using Wox.Infrastructure.Logger ;
using Wox.Infrastructure.Storage ;
using Wox.Plugin ;
using Stopwatch = Wox . Infrastructure . Stopwatch ;
namespace Microsoft.Plugin.Program
{
2020-07-10 04:14:53 +08:00
public class Main : IPlugin , IPluginI18n , IContextMenu , ISavable , IReloadable , IDisposable
2020-08-18 01:00:56 +08:00
{
internal static ProgramPluginSettings Settings { get ; set ; }
private static PluginInitContext _context ;
private readonly PluginJsonStorage < ProgramPluginSettings > _settingsStorage ;
2020-08-22 03:40:31 +08:00
private bool _disposed ;
2020-08-12 00:08:44 +08:00
private PackageRepository _packageRepository = new PackageRepository ( new PackageCatalogWrapper ( ) , new BinaryStorage < IList < UWPApplication > > ( "UWP" ) ) ;
2020-07-18 13:32:21 +08:00
private static Win32ProgramFileSystemWatchers _win32ProgramRepositoryHelper ;
2020-08-18 01:00:56 +08:00
private static Win32ProgramRepository _win32ProgramRepository ;
public Main ( )
{
_settingsStorage = new PluginJsonStorage < ProgramPluginSettings > ( ) ;
Settings = _settingsStorage . Load ( ) ;
// This helper class initializes the file system watchers based on the locations to watch
_win32ProgramRepositoryHelper = new Win32ProgramFileSystemWatchers ( ) ;
// Initialize the Win32ProgramRepository with the settings object
_win32ProgramRepository = new Win32ProgramRepository ( _win32ProgramRepositoryHelper . FileSystemWatchers . Cast < IFileSystemWatcherWrapper > ( ) . ToList ( ) , new BinaryStorage < IList < Programs . Win32Program > > ( "Win32" ) , Settings , _win32ProgramRepositoryHelper . PathsToWatch ) ;
var a = Task . Run ( ( ) = >
{
2020-08-25 01:50:54 +08:00
Stopwatch . Normal ( "|Microsoft.Plugin.Program.Main|Win32Program index cost" , _win32ProgramRepository . IndexPrograms ) ;
2020-08-18 01:00:56 +08:00
} ) ;
var b = Task . Run ( ( ) = >
{
2020-08-25 01:50:54 +08:00
Stopwatch . Normal ( "|Microsoft.Plugin.Program.Main|Win32Program index cost" , _packageRepository . IndexPrograms ) ;
2020-08-18 01:00:56 +08:00
} ) ;
Task . WaitAll ( a , b ) ;
Settings . LastIndexTime = DateTime . Today ;
}
public void Save ( )
{
_settingsStorage . Save ( ) ;
}
public List < Result > Query ( Query query )
{
var results1 = _win32ProgramRepository . AsParallel ( )
. Where ( p = > p . Enabled )
. Select ( p = > p . Result ( query . Search , _context . API ) ) ;
var results2 = _packageRepository . AsParallel ( )
. Where ( p = > p . Enabled )
. Select ( p = > p . Result ( query . Search , _context . API ) ) ;
var result = results1 . Concat ( results2 ) . Where ( r = > r ! = null & & r . Score > 0 ) ;
2020-08-20 07:16:45 +08:00
if ( result . Any ( ) )
{
var maxScore = result . Max ( x = > x . Score ) ;
result = result . Where ( x = > x . Score > Settings . MinScoreThreshold * maxScore ) ;
}
2020-08-18 01:00:56 +08:00
return result . ToList ( ) ;
}
public void Init ( PluginInitContext context )
{
_context = context ? ? throw new ArgumentNullException ( nameof ( context ) ) ;
_context . API . ThemeChanged + = OnThemeChanged ;
UpdateUWPIconPath ( _context . API . GetCurrentTheme ( ) ) ;
}
public void OnThemeChanged ( Theme currentTheme , Theme newTheme )
{
UpdateUWPIconPath ( newTheme ) ;
}
public void UpdateUWPIconPath ( Theme theme )
{
foreach ( UWPApplication app in _packageRepository )
{
app . UpdatePath ( theme ) ;
}
}
public void IndexPrograms ( )
{
var t1 = Task . Run ( ( ) = > _win32ProgramRepository . IndexPrograms ( ) ) ;
var t2 = Task . Run ( ( ) = > _packageRepository . IndexPrograms ( ) ) ;
Task . WaitAll ( t1 , t2 ) ;
Settings . LastIndexTime = DateTime . Today ;
}
public string GetTranslatedPluginTitle ( )
{
2020-09-03 06:24:59 +08:00
return Properties . Resources . wox_plugin_program_plugin_name ;
2020-08-18 01:00:56 +08:00
}
public string GetTranslatedPluginDescription ( )
{
2020-09-03 06:24:59 +08:00
return Properties . Resources . wox_plugin_program_plugin_description ;
2020-08-18 01:00:56 +08:00
}
public List < ContextMenuResult > LoadContextMenus ( Result selectedResult )
{
if ( selectedResult = = null )
{
throw new ArgumentNullException ( nameof ( selectedResult ) ) ;
}
var menuOptions = new List < ContextMenuResult > ( ) ;
if ( selectedResult . ContextData is Programs . IProgram program )
{
menuOptions = program . ContextMenus ( _context . API ) ;
}
return menuOptions ;
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "We want to keep the process alive and show the user a warning message")]
public static void StartProcess ( Func < ProcessStartInfo , Process > runProcess , ProcessStartInfo info )
{
try
{
if ( runProcess = = null )
{
throw new ArgumentNullException ( nameof ( runProcess ) ) ;
}
if ( info = = null )
{
throw new ArgumentNullException ( nameof ( info ) ) ;
}
runProcess ( info ) ;
}
catch ( Exception )
{
var name = "Plugin: Program" ;
2020-08-22 03:40:31 +08:00
var message = $"Unable to start: {info?.FileName}" ;
2020-08-18 01:00:56 +08:00
_context . API . ShowMsg ( name , message , string . Empty ) ;
}
}
public void ReloadData ( )
{
IndexPrograms ( ) ;
}
2020-06-27 08:42:06 +08:00
public void Dispose ( )
{
Dispose ( disposing : true ) ;
GC . SuppressFinalize ( this ) ;
}
protected virtual void Dispose ( bool disposing )
{
if ( ! _disposed )
{
if ( disposing )
{
_context . API . ThemeChanged - = OnThemeChanged ;
2020-07-18 13:32:21 +08:00
_win32ProgramRepositoryHelper . Dispose ( ) ;
2020-06-27 08:42:06 +08:00
_disposed = true ;
}
}
}
2020-08-18 01:00:56 +08:00
}
}