mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Move WebSearch to Async model
This commit is contained in:
parent
d0d938b92a
commit
a4edbc2cb9
5 changed files with 52 additions and 52 deletions
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
|
|
@ -13,14 +14,12 @@ using Flow.Launcher.Plugin.SharedCommands;
|
|||
|
||||
namespace Flow.Launcher.Plugin.WebSearch
|
||||
{
|
||||
public class Main : IPlugin, ISettingProvider, IPluginI18n, ISavable, IResultUpdated
|
||||
public class Main : IAsyncPlugin, ISettingProvider, IPluginI18n, ISavable, IResultUpdated
|
||||
{
|
||||
private PluginInitContext _context;
|
||||
|
||||
private readonly Settings _settings;
|
||||
private readonly SettingsViewModel _viewModel;
|
||||
private CancellationTokenSource _updateSource;
|
||||
private CancellationToken _updateToken;
|
||||
|
||||
internal const string Images = "Images";
|
||||
internal static string DefaultImagesDirectory;
|
||||
|
|
@ -33,7 +32,7 @@ namespace Flow.Launcher.Plugin.WebSearch
|
|||
_viewModel.Save();
|
||||
}
|
||||
|
||||
public List<Result> Query(Query query)
|
||||
public async Task<List<Result>> QueryAsync(Query query, CancellationToken token)
|
||||
{
|
||||
if (FilesFolders.IsLocationPathString(query.Search))
|
||||
return new List<Result>();
|
||||
|
|
@ -41,11 +40,7 @@ namespace Flow.Launcher.Plugin.WebSearch
|
|||
var searchSourceList = new List<SearchSource>();
|
||||
var results = new List<Result>();
|
||||
|
||||
_updateSource?.Cancel();
|
||||
_updateSource = new CancellationTokenSource();
|
||||
_updateToken = _updateSource.Token;
|
||||
|
||||
_settings.SearchSources.Where(o => (o.ActionKeyword == query.ActionKeyword || o.ActionKeyword == SearchSourceGlobalPluginWildCardSign)
|
||||
_settings.SearchSources.Where(o => (o.ActionKeyword == query.ActionKeyword || o.ActionKeyword == SearchSourceGlobalPluginWildCardSign)
|
||||
&& o.Enabled)
|
||||
.ToList()
|
||||
.ForEach(x => searchSourceList.Add(x));
|
||||
|
|
@ -94,49 +89,45 @@ namespace Flow.Launcher.Plugin.WebSearch
|
|||
};
|
||||
|
||||
results.Add(result);
|
||||
ResultsUpdated?.Invoke(this, new ResultUpdatedEventArgs
|
||||
{
|
||||
Results = results,
|
||||
Query = query
|
||||
});
|
||||
|
||||
UpdateResultsFromSuggestion(results, keyword, subtitle, searchSource, query);
|
||||
}
|
||||
|
||||
ResultsUpdated?.Invoke(this, new ResultUpdatedEventArgs
|
||||
{
|
||||
Results = results,
|
||||
Query = query
|
||||
});
|
||||
|
||||
await UpdateResultsFromSuggestionAsync(results, keyword, subtitle, searchSource, query, token).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private void UpdateResultsFromSuggestion(List<Result> results, string keyword, string subtitle,
|
||||
SearchSource searchSource, Query query)
|
||||
private async Task UpdateResultsFromSuggestionAsync(List<Result> results, string keyword, string subtitle,
|
||||
SearchSource searchSource, Query query, CancellationToken token)
|
||||
{
|
||||
if (_settings.EnableSuggestion)
|
||||
{
|
||||
const int waittime = 300;
|
||||
var task = Task.Run(async () =>
|
||||
{
|
||||
var suggestions = await Suggestions(keyword, subtitle, searchSource);
|
||||
results.AddRange(suggestions);
|
||||
}, _updateToken);
|
||||
var suggestions = await SuggestionsAsync(keyword, subtitle, searchSource, token).ConfigureAwait(false);
|
||||
results.AddRange(suggestions);
|
||||
|
||||
if (!task.Wait(waittime))
|
||||
token.ThrowIfCancellationRequested();
|
||||
|
||||
ResultsUpdated?.Invoke(this, new ResultUpdatedEventArgs
|
||||
{
|
||||
task.ContinueWith(_ => ResultsUpdated?.Invoke(this, new ResultUpdatedEventArgs
|
||||
{
|
||||
Results = results,
|
||||
Query = query
|
||||
}), _updateToken);
|
||||
}
|
||||
Results = results,
|
||||
Query = query
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<Result>> Suggestions(string keyword, string subtitle, SearchSource searchSource)
|
||||
private async Task<IEnumerable<Result>> SuggestionsAsync(string keyword, string subtitle, SearchSource searchSource, CancellationToken token)
|
||||
{
|
||||
var source = _settings.SelectedSuggestion;
|
||||
if (source != null)
|
||||
{
|
||||
var suggestions = await source.Suggestions(keyword);
|
||||
var suggestions = await source.Suggestions(keyword, token);
|
||||
var resultsFromSuggestion = suggestions.Select(o => new Result
|
||||
{
|
||||
Title = o,
|
||||
|
|
@ -169,19 +160,24 @@ namespace Flow.Launcher.Plugin.WebSearch
|
|||
_settings = _viewModel.Settings;
|
||||
}
|
||||
|
||||
public void Init(PluginInitContext context)
|
||||
public Task InitAsync(PluginInitContext context)
|
||||
{
|
||||
_context = context;
|
||||
var pluginDirectory = _context.CurrentPluginMetadata.PluginDirectory;
|
||||
var bundledImagesDirectory = Path.Combine(pluginDirectory, Images);
|
||||
|
||||
// Default images directory is in the WebSearch's application folder
|
||||
DefaultImagesDirectory = Path.Combine(pluginDirectory, Images);
|
||||
Helper.ValidateDataDirectory(bundledImagesDirectory, DefaultImagesDirectory);
|
||||
return Task.Run(Init);
|
||||
|
||||
// Custom images directory is in the WebSearch's data location folder
|
||||
var name = Path.GetFileNameWithoutExtension(_context.CurrentPluginMetadata.ExecuteFileName);
|
||||
CustomImagesDirectory = Path.Combine(DataLocation.PluginSettingsDirectory, name, "CustomIcons");
|
||||
void Init()
|
||||
{
|
||||
_context = context;
|
||||
var pluginDirectory = _context.CurrentPluginMetadata.PluginDirectory;
|
||||
var bundledImagesDirectory = Path.Combine(pluginDirectory, Images);
|
||||
|
||||
// Default images directory is in the WebSearch's application folder
|
||||
DefaultImagesDirectory = Path.Combine(pluginDirectory, Images);
|
||||
Helper.ValidateDataDirectory(bundledImagesDirectory, DefaultImagesDirectory);
|
||||
|
||||
// Custom images directory is in the WebSearch's data location folder
|
||||
var name = Path.GetFileNameWithoutExtension(_context.CurrentPluginMetadata.ExecuteFileName);
|
||||
CustomImagesDirectory = Path.Combine(DataLocation.PluginSettingsDirectory, name, "CustomIcons");
|
||||
};
|
||||
}
|
||||
|
||||
#region ISettingProvider Members
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ using Newtonsoft.Json.Linq;
|
|||
using Flow.Launcher.Infrastructure.Http;
|
||||
using Flow.Launcher.Infrastructure.Logger;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
|
||||
namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources
|
||||
{
|
||||
|
|
@ -16,14 +17,14 @@ namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources
|
|||
{
|
||||
private readonly Regex _reg = new Regex("window.baidu.sug\\((.*)\\)");
|
||||
|
||||
public override async Task<List<string>> Suggestions(string query)
|
||||
public override async Task<List<string>> Suggestions(string query, CancellationToken token)
|
||||
{
|
||||
string result;
|
||||
|
||||
try
|
||||
{
|
||||
const string api = "http://suggestion.baidu.com/su?json=1&wd=";
|
||||
result = await Http.GetAsync(api + Uri.EscapeUriString(query)).ConfigureAwait(false);
|
||||
result = await Http.GetAsync(api + Uri.EscapeUriString(query), token).ConfigureAwait(false);
|
||||
}
|
||||
catch (HttpRequestException e)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -9,19 +9,20 @@ using System.Text.RegularExpressions;
|
|||
using System.Threading.Tasks;
|
||||
using System.Text.Json;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
|
||||
namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources
|
||||
{
|
||||
class Bing : SuggestionSource
|
||||
{
|
||||
public override async Task<List<string>> Suggestions(string query)
|
||||
public override async Task<List<string>> Suggestions(string query, CancellationToken token)
|
||||
{
|
||||
Stream resultStream;
|
||||
|
||||
try
|
||||
{
|
||||
const string api = "https://api.bing.com/qsonhs.aspx?q=";
|
||||
resultStream = await Http.GetStreamAsync(api + Uri.EscapeUriString(query)).ConfigureAwait(false);
|
||||
resultStream = await Http.GetStreamAsync(api + Uri.EscapeUriString(query), token).ConfigureAwait(false);
|
||||
}
|
||||
catch (HttpRequestException e)
|
||||
{
|
||||
|
|
@ -29,7 +30,7 @@ namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources
|
|||
return new List<string>();
|
||||
}
|
||||
|
||||
if (resultStream.Length == 0) return new List<string>();
|
||||
if (resultStream.Length == 0) return new List<string>(); // this handles the cancellation
|
||||
|
||||
JsonElement json;
|
||||
try
|
||||
|
|
|
|||
|
|
@ -8,18 +8,19 @@ using Newtonsoft.Json.Linq;
|
|||
using Flow.Launcher.Infrastructure.Http;
|
||||
using Flow.Launcher.Infrastructure.Logger;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
|
||||
namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources
|
||||
{
|
||||
public class Google : SuggestionSource
|
||||
{
|
||||
public override async Task<List<string>> Suggestions(string query)
|
||||
public override async Task<List<string>> Suggestions(string query, CancellationToken token)
|
||||
{
|
||||
string result;
|
||||
try
|
||||
{
|
||||
const string api = "https://www.google.com/complete/search?output=chrome&q=";
|
||||
result = await Http.GetAsync(api + Uri.EscapeUriString(query)).ConfigureAwait(false);
|
||||
result = await Http.GetAsync(api + Uri.EscapeUriString(query), token).ConfigureAwait(false);
|
||||
}
|
||||
catch (HttpRequestException e)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Flow.Launcher.Plugin.WebSearch.SuggestionSources
|
||||
{
|
||||
public abstract class SuggestionSource
|
||||
{
|
||||
public abstract Task<List<string>> Suggestions(string query);
|
||||
public abstract Task<List<string>> Suggestions(string query, CancellationToken token);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue