Web search suggestion is loaded async

1. suggestion is async
2. if ping time of domain less than 300ms, then suggestion is still sync
3. #578 #539
This commit is contained in:
bao-qian
2016-05-05 16:08:44 +01:00
parent c41847c0d7
commit ba1e22955e
11 changed files with 293 additions and 217 deletions

View File

@@ -8,8 +8,10 @@ using Wox.Infrastructure.Http;
namespace Wox.Plugin.WebSearch.SuggestionSources
{
public class Baidu : AbstractSuggestionSource
public class Baidu : SuggestionSource
{
public override string Domain { get; set; } = "www.baidu.com";
Regex reg = new Regex("window.baidu.sug\\((.*)\\)");
public override List<string> GetSuggestions(string query)

View File

@@ -7,8 +7,9 @@ using Wox.Infrastructure.Http;
namespace Wox.Plugin.WebSearch.SuggestionSources
{
public class Google : AbstractSuggestionSource
public class Google : SuggestionSource
{
public override string Domain { get; set; } = "www.google.com";
public override List<string> GetSuggestions(string query)
{
var result = HttpRequest.Get("https://www.google.com/complete/search?output=chrome&q=" + Uri.EscapeUriString(query), Proxy);

View File

@@ -2,20 +2,31 @@
namespace Wox.Plugin.WebSearch.SuggestionSources
{
public interface ISuggestionSource
{
List<string> GetSuggestions(string query);
}
public abstract class AbstractSuggestionSource : ISuggestionSource
public abstract class SuggestionSource
{
public virtual string Domain { get; set; }
public IHttpProxy Proxy { get; set; }
public AbstractSuggestionSource(IHttpProxy httpProxy)
public SuggestionSource(IHttpProxy httpProxy)
{
Proxy = httpProxy;
}
public abstract List<string> GetSuggestions(string query);
public static SuggestionSource GetSuggestionSource(string name, PluginInitContext context)
{
switch (name.ToLower())
{
case "google":
return new Google(context.Proxy);
case "baidu":
return new Baidu(context.Proxy);
default:
return null;
}
}
}
}

View File

@@ -1,20 +0,0 @@
namespace Wox.Plugin.WebSearch.SuggestionSources
{
public class SuggestionSourceFactory
{
public static ISuggestionSource GetSuggestionSource(string name,PluginInitContext context)
{
switch (name.ToLower())
{
case "google":
return new Google(context.Proxy);
case "baidu":
return new Baidu(context.Proxy);
default:
return null;
}
}
}
}

View File

@@ -3,19 +3,26 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.NetworkInformation;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Documents;
using JetBrains.Annotations;
using Wox.Infrastructure.Storage;
using Wox.Plugin.WebSearch.SuggestionSources;
namespace Wox.Plugin.WebSearch
{
public class WebSearchPlugin : IPlugin, ISettingProvider, IPluginI18n, IMultipleActionKeywords, ISavable
public class WebSearchPlugin : IPlugin, ISettingProvider, IPluginI18n, IMultipleActionKeywords, ISavable, IResultUpdated
{
public PluginInitContext Context { get; private set; }
private PluginJsonStorage<Settings> _storage;
private Settings _settings;
private CancellationTokenSource _updateSource;
private CancellationToken _updateToken;
public const string ImageDirectory = "Images";
public static string PluginDirectory;
@@ -26,7 +33,10 @@ namespace Wox.Plugin.WebSearch
public List<Result> Query(Query query)
{
List<Result> results = new List<Result>();
_updateSource?.Cancel();
_updateSource = new CancellationTokenSource();
_updateToken = _updateSource.Token;
WebSearch webSearch =
_settings.WebSearches.FirstOrDefault(o => o.ActionKeyword == query.ActionKeyword && o.Enabled);
@@ -37,36 +47,74 @@ namespace Wox.Plugin.WebSearch
string subtitle = Context.API.GetTranslation("wox_plugin_websearch_search") + " " + webSearch.Title;
if (string.IsNullOrEmpty(keyword))
{
title = subtitle;
subtitle = string.Empty;
}
var result = new Result
{
Title = title,
SubTitle = subtitle,
Score = 6,
IcoPath = webSearch.IconPath,
Action = c =>
var result = new Result
{
Process.Start(webSearch.Url.Replace("{q}", Uri.EscapeDataString(keyword ?? string.Empty)));
return true;
}
};
results.Add(result);
if (_settings.EnableWebSearchSuggestion && !string.IsNullOrEmpty(keyword))
Title = subtitle,
SubTitle = string.Empty,
IcoPath = webSearch.IconPath
};
return new List<Result> { result };
}
else
{
// todo use Task.Wait when .net upgraded
results.AddRange(ResultsFromSuggestions(keyword, subtitle, webSearch));
var results = new List<Result>();
var result = new Result
{
Title = title,
SubTitle = subtitle,
Score = 6,
IcoPath = webSearch.IconPath,
Action = c =>
{
Process.Start(webSearch.Url.Replace("{q}", Uri.EscapeDataString(keyword)));
return true;
}
};
results.Add(result);
UpdateResultsFromSuggestion(results, keyword, subtitle, webSearch, query);
return results;
}
}
else
{
return new List<Result>();
}
}
private void UpdateResultsFromSuggestion(List<Result> results, string keyword, string subtitle, WebSearch webSearch, Query query)
{
if (_settings.EnableWebSearchSuggestion)
{
var waittime = 300;
var fastDomain = Task.Factory.StartNew(() =>
{
var ping = new Ping();
var source = SuggestionSource.GetSuggestionSource(_settings.WebSearchSuggestionSource, Context);
ping.Send(source.Domain);
}, _updateToken).Wait(waittime);
if (fastDomain)
{
results.AddRange(ResultsFromSuggestions(keyword, subtitle, webSearch));
}
else
{
Task.Factory.StartNew(() =>
{
results.AddRange(ResultsFromSuggestions(keyword, subtitle, webSearch));
ResultsUpdated?.Invoke(this, new ResultUpdatedEventHandlerArgs
{
Results = results,
Query = query
});
}, _updateToken);
}
}
return results;
}
private IEnumerable<Result> ResultsFromSuggestions(string keyword, string subtitle, WebSearch webSearch)
{
ISuggestionSource sugg = SuggestionSourceFactory.GetSuggestionSource(_settings.WebSearchSuggestionSource, Context);
var suggestions = sugg?.GetSuggestions(keyword);
var source = SuggestionSource.GetSuggestionSource(_settings.WebSearchSuggestionSource, Context);
var suggestions = source?.GetSuggestions(keyword);
if (suggestions != null)
{
var resultsFromSuggestion = suggestions.Select(o => new Result
@@ -135,5 +183,6 @@ namespace Wox.Plugin.WebSearch
}
public event ActionKeywordsChangedEventHandler ActionKeywordsChanged;
public event ResultUpdatedEventHandler ResultsUpdated;
}
}

View File

@@ -61,7 +61,6 @@
<Compile Include="SuggestionSources\Baidu.cs" />
<Compile Include="SuggestionSources\Google.cs" />
<Compile Include="SuggestionSources\ISuggestionSource.cs" />
<Compile Include="SuggestionSources\SuggestionSourceFactory.cs" />
<Compile Include="WebSearch.cs" />
<Compile Include="WebSearchesSetting.xaml.cs">
<DependentUpon>WebSearchesSetting.xaml</DependentUpon>