[PTRun][OneNote]Add query caching and delayedExecution (#18919)

* Adding OneNote plugin for PowerToys Run

* Updating to 3.0.1 dependency, updating md, spellcheck, ready for PR

* Updating spelling and using localized string

* Adding OneNote link to readme

* Adding OneNote requirement to description

* removing 'open' from description

* Updating interop version, PR feedback

* Adding query caching and delayedExecution to PT Run OneNote plugin

* Adding binaries to signing, and updating doc

* Adding dependency nuget package binaries to installer

* PR feedback and .editorconfig fix to ignore IDE rules that conflict with repo styling

* Fixing spelling
This commit is contained in:
Union Palenshus 2022-06-29 06:56:55 -07:00 коммит произвёл GitHub
Родитель 19bf2e3614
Коммит 28eb4c80f6
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
8 изменённых файлов: 156 добавлений и 19 удалений

1
.github/actions/spell-check/expect.txt поставляемый
Просмотреть файл

@ -929,6 +929,7 @@ IObservable
IOle
iolewindowcontextsensitivehelp
iomanip
IOne
iostream
IPackage
IPath

Просмотреть файл

@ -188,6 +188,7 @@
"modules\\FileExplorerPreview\\Microsoft.Web.WebView2.Wpf.dll",
"modules\\FileExplorerPreview\\WebView2Loader.dll",
"modules\\launcher\\e_sqlite3.dll",
"modules\\launcher\\LazyCache.dll",
"modules\\launcher\\SQLitePCLRaw.batteries_v2.dll",
"modules\\launcher\\SQLitePCLRaw.core.dll",
"modules\\launcher\\SQLitePCLRaw.provider.e_sqlite3.dll",

Просмотреть файл

@ -9,6 +9,8 @@ The code itself is very simple, basically just a call into OneNote interop via t
var pages = OneNoteProvider.FindPages(query.Search);
```
The query results will be cached for 1 day, and if cached results are found they'll be returned in the initial `Query()` call, otherwise OneNote itself will be queried in the `delayedExecution:true` overload.
If the user actions on a result, it'll open it in the OneNote app, and restore and/or focus the app as well if necessary.
```csharp
@ -33,4 +35,4 @@ catch (COMException)
// OneNote isn't installed, plugin won't do anything.
_oneNoteInstalled = false;
}
```
```

Просмотреть файл

@ -1697,7 +1697,7 @@
<!-- !Warning! Make sure to change Component Guid if you update the file list -->
<Component Id="launcherInstallComponent" Guid="ab0d0567-1e41-4da4-9934-dcb74b7048a4" Directory="LauncherInstallFolder" >
<File Source="$(var.BinDir)modules\Launcher\PowerToys.Launcher.dll" />
<?foreach File in e_sqlite3.dll;JetBrains.Annotations.dll;Mages.Core.dll;Mono.Cecil.dll;Mono.Cecil.Mdb.dll;Mono.Cecil.Pdb.dll;Mono.Cecil.Rocks.dll;NLog.dll;NLog.Extensions.Logging.dll;PowerToys.PowerLauncher.deps.json;PowerToys.PowerLauncher.dll;PowerToys.PowerLauncher.exe;Microsoft.Xaml.Behaviors.dll;PowerToys.PowerLauncher.runtimeconfig.json;System.Data.OleDb.dll;UnitsNet.dll;vcamp140_app.dll;Wox.Infrastructure.dll;Wox.Plugin.dll;PowerToys.Interop.dll;PowerToys.ManagedTelemetry.dll;PowerToys.PowerLauncher.Telemetry.dll;Microsoft.Data.Sqlite.dll;SQLitePCLRaw.batteries_v2.dll;SQLitePCLRaw.core.dll;SQLitePCLRaw.provider.e_sqlite3.dll;Microsoft.Extensions.Configuration.Abstractions.dll;Microsoft.Extensions.DependencyInjection.Abstractions.dll;Microsoft.Extensions.DependencyInjection.dll;Microsoft.Extensions.Logging.Abstractions.dll;Microsoft.Extensions.Logging.dll;Microsoft.Extensions.Options.dll;Microsoft.Extensions.Primitives.dll;ControlzEx.dll;PowerToys.ManagedCommon.dll;System.IO.Abstractions.dll;PowerToys.Common.UI.dll;System.ServiceProcess.ServiceController.dll;Microsoft.Toolkit.Uwp.Notifications.dll;ModernWpf.Controls.dll;ModernWpf.dll;WinRT.Runtime.dll;Microsoft.Windows.SDK.NET.dll;System.Reactive.dll;System.Text.Json.dll;Ijwhost.dll;ScipBe.Common.Office.OneNote.dll;Interop.Microsoft.Office.Interop.OneNote.dll?>
<?foreach File in e_sqlite3.dll;JetBrains.Annotations.dll;Mages.Core.dll;Mono.Cecil.dll;Mono.Cecil.Mdb.dll;Mono.Cecil.Pdb.dll;Mono.Cecil.Rocks.dll;NLog.dll;NLog.Extensions.Logging.dll;PowerToys.PowerLauncher.deps.json;PowerToys.PowerLauncher.dll;PowerToys.PowerLauncher.exe;Microsoft.Xaml.Behaviors.dll;PowerToys.PowerLauncher.runtimeconfig.json;System.Data.OleDb.dll;UnitsNet.dll;vcamp140_app.dll;Wox.Infrastructure.dll;Wox.Plugin.dll;PowerToys.Interop.dll;PowerToys.ManagedTelemetry.dll;PowerToys.PowerLauncher.Telemetry.dll;Microsoft.Data.Sqlite.dll;SQLitePCLRaw.batteries_v2.dll;SQLitePCLRaw.core.dll;SQLitePCLRaw.provider.e_sqlite3.dll;Microsoft.Extensions.Configuration.Abstractions.dll;Microsoft.Extensions.DependencyInjection.Abstractions.dll;Microsoft.Extensions.DependencyInjection.dll;Microsoft.Extensions.Logging.Abstractions.dll;Microsoft.Extensions.Logging.dll;Microsoft.Extensions.Options.dll;Microsoft.Extensions.Primitives.dll;ControlzEx.dll;PowerToys.ManagedCommon.dll;System.IO.Abstractions.dll;PowerToys.Common.UI.dll;System.ServiceProcess.ServiceController.dll;Microsoft.Toolkit.Uwp.Notifications.dll;ModernWpf.Controls.dll;ModernWpf.dll;WinRT.Runtime.dll;Microsoft.Windows.SDK.NET.dll;System.Reactive.dll;System.Text.Json.dll;Ijwhost.dll;ScipBe.Common.Office.OneNote.dll;Interop.Microsoft.Office.Interop.OneNote.dll;LazyCache.dll;Microsoft.Extensions.Caching.Abstractions.dll;Microsoft.Extensions.Caching.Memory.dll?>
<File Id="File_$(var.File)" Source="$(var.BinDir)modules\launcher\$(var.File)" />
<?endforeach?>
<File Source="$(var.BinDir)Settings\PowerToys.Settings.UI.Lib.dll" />

Просмотреть файл

@ -7,4 +7,92 @@ dotnet_diagnostic.SA1201.severity = none
dotnet_diagnostic.CA1303.severity = suggestion
# CA1051: Do not declare visible instance fields
dotnet_code_quality.ca1051.exclude_structs = true
dotnet_code_quality.ca1051.exclude_structs = true
csharp_using_directive_placement = inside_namespace:warning
csharp_prefer_simple_using_statement = true:suggestion
csharp_prefer_braces = true:silent
csharp_style_namespace_declarations = block_scoped:silent
csharp_style_prefer_method_group_conversion = true:silent
csharp_style_expression_bodied_methods = false:silent
csharp_style_expression_bodied_constructors = false:silent
csharp_style_expression_bodied_operators = false:silent
csharp_style_expression_bodied_properties = when_on_single_line:suggestion
csharp_style_expression_bodied_indexers = true:silent
csharp_style_expression_bodied_accessors = true:silent
csharp_style_expression_bodied_lambdas = true:silent
csharp_style_expression_bodied_local_functions = false:silent
csharp_style_throw_expression = true:suggestion
csharp_indent_labels = one_less_than_current
csharp_style_prefer_null_check_over_type_check = true:suggestion
[*.{cs,vb}]
#### Naming styles ####
# Naming rules
dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
# Symbol specifications
dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.interface.required_modifiers =
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.types.required_modifiers =
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.non_field_members.required_modifiers =
# Naming styles
dotnet_naming_style.begins_with_i.required_prefix = I
dotnet_naming_style.begins_with_i.required_suffix =
dotnet_naming_style.begins_with_i.word_separator =
dotnet_naming_style.begins_with_i.capitalization = pascal_case
dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case
dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_auto_properties = true:silent
dotnet_style_object_initializer = false:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
dotnet_style_prefer_conditional_expression_over_return = true:suggestion
dotnet_style_explicit_tuple_names = true:suggestion
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_compound_assignment = true:suggestion
dotnet_style_prefer_simplified_interpolation = true:suggestion
dotnet_style_namespace_match_folder = true:suggestion
dotnet_style_operator_placement_when_wrapping = beginning_of_line
tab_width = 4
indent_size = 4
end_of_line = crlf
# IDE0065: using directive placement
dotnet_diagnostic.IDE0065.severity = none
# IDE0009: Add this or Me qualification
dotnet_diagnostic.IDE0009.severity = none

Просмотреть файл

@ -5,6 +5,7 @@
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using LazyCache;
using ManagedCommon;
using Microsoft.PowerToys.Run.Plugin.OneNote.Properties;
using ScipBe.Common.Office.OneNote;
@ -18,13 +19,18 @@ namespace Microsoft.PowerToys.Run.Plugin.OneNote
/// <summary>
/// A power launcher plugin to search across time zones.
/// </summary>
public class Main : IPlugin, IPluginI18n
public class Main : IPlugin, IDelayedExecutionPlugin, IPluginI18n
{
/// <summary>
/// A value indicating if the OneNote interop library was able to successfully initialize.
/// </summary>
private bool _oneNoteInstalled;
/// <summary>
/// LazyCache CachingService instance to speed up repeated queries.
/// </summary>
private CachingService? _cache;
/// <summary>
/// The initial context for this plugin (contains API and meta-data)
/// </summary>
@ -65,6 +71,9 @@ namespace Microsoft.PowerToys.Run.Plugin.OneNote
{
_ = OneNoteProvider.PageItems.Any();
_oneNoteInstalled = true;
_cache = new CachingService();
_cache.DefaultCachePolicy.DefaultCacheDurationSeconds = (int)TimeSpan.FromDays(1).TotalSeconds;
}
catch (COMException)
{
@ -83,28 +92,47 @@ namespace Microsoft.PowerToys.Run.Plugin.OneNote
/// <returns>A filtered list, can be empty when nothing was found</returns>
public List<Result> Query(Query query)
{
if (!_oneNoteInstalled || query is null || string.IsNullOrWhiteSpace(query.Search))
if (!_oneNoteInstalled || query is null || string.IsNullOrWhiteSpace(query.Search) || _cache is null)
{
return new List<Result>(0);
}
var pages = OneNoteProvider.FindPages(query.Search);
// If there's cached results for this query, return immediately, otherwise wait for delayedExecution.
var results = _cache.Get<List<Result>>(query.Search);
return results ?? Query(query, false);
}
return pages.Select(p => new Result
/// <summary>
/// Return a filtered list, based on the given query
/// </summary>
/// <param name="query">The query to filter the list</param>
/// <param name="delayedExecution">False if this is the first pass through plugins, true otherwise. Slow plugins should run delayed.</param>
/// <returns>A filtered list, can be empty when nothing was found</returns>
public List<Result> Query(Query query, bool delayedExecution)
{
if (!delayedExecution || !_oneNoteInstalled || query is null || string.IsNullOrWhiteSpace(query.Search) || _cache is null)
{
IcoPath = _iconPath,
Title = p.Name,
QueryTextDisplay = p.Name,
SubTitle = @$"{p.Notebook.Name}\{p.Section.Name}",
Action = (_) =>
return new List<Result>(0);
}
// Get results from cache if they already exist for this query, otherwise query OneNote. Results will be cached for 1 day.
var results = _cache.GetOrAdd(query.Search, () =>
{
var pages = OneNoteProvider.FindPages(query.Search);
return pages.Select(p => new Result
{
p.OpenInOneNote();
ShowOneNote();
return true;
},
ContextData = p,
ToolTipData = new ToolTipData(Name, @$"{p.Notebook.Name}\{p.Section.Name}\{p.Name}"),
}).ToList();
IcoPath = _iconPath,
Title = p.Name,
QueryTextDisplay = p.Name,
SubTitle = @$"{p.Notebook.Name}\{p.Section.Name}",
Action = (_) => OpenPageInOneNote(p),
ContextData = p,
ToolTipData = new ToolTipData(Name, @$"{p.Notebook.Name}\{p.Section.Name}\{p.Name}"),
}).ToList();
});
return results;
}
/// <summary>
@ -130,6 +158,21 @@ namespace Microsoft.PowerToys.Run.Plugin.OneNote
_iconPath = theme == Theme.Light || theme == Theme.HighContrastWhite ? "Images/oneNote.light.png" : "Images/oneNote.dark.png";
}
private bool OpenPageInOneNote(IOneNoteExtPage page)
{
try
{
page.OpenInOneNote();
ShowOneNote();
return true;
}
catch (COMException)
{
// The page, section or even notebook may no longer exist, ignore and do nothing.
return false;
}
}
/// <summary>
/// Brings OneNote to the foreground and restores it if minimized.
/// </summary>

Просмотреть файл

@ -52,6 +52,7 @@
<ItemGroup>
<PackageReference Include="Interop.Microsoft.Office.Interop.OneNote" Version="1.1.0.2" />
<PackageReference Include="LazyCache" Version="2.4.0" />
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.1.691-beta">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

Просмотреть файл

@ -81,6 +81,7 @@
<PackageReference Include="Interop.Microsoft.Office.Interop.OneNote" Version="1.1.0.2" />
<PackageReference Include="JetBrains.Annotations" Version="2021.3.0" />
<PackageReference Include="Mages" Version="2.0.1" />
<PackageReference Include="LazyCache" Version="2.4.0" />
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>