#129 Make web search suggestion optional and add baidu suggeestion source.

This commit is contained in:
qianlifeng 2014-07-21 22:27:57 +08:00
parent 4e87211d39
commit 83e199a0de
10 changed files with 203 additions and 59 deletions

View file

@ -11,21 +11,11 @@ using System.Text;
//From:http://blog.csdn.net/zhoufoxcn/article/details/6404236 //From:http://blog.csdn.net/zhoufoxcn/article/details/6404236
namespace Wox.Infrastructure namespace Wox.Infrastructure
{ {
/// <summary>
/// 有关HTTP请求的辅助类
/// </summary>
public class HttpRequest public class HttpRequest
{ {
private static readonly string DefaultUserAgent = "Wox/" + Assembly.GetEntryAssembly().GetName().Version.ToString() + " (+https://github.com/qianlifeng/Wox)"; private static readonly string DefaultUserAgent = "Wox/" + Assembly.GetEntryAssembly().GetName().Version.ToString() + " (+https://github.com/qianlifeng/Wox)";
/// <summary>
/// 创建GET方式的HTTP请求
/// </summary>
/// <param name="url">请求的URL</param>
/// <param name="timeout">请求的超时时间</param>
/// <param name="userAgent">请求的客户端浏览器信息,可以为空</param>
/// <param name="cookies">随同HTTP请求发送的Cookie信息如果不需要身份验证可以为空</param>
/// <returns></returns>
public static HttpWebResponse CreateGetHttpResponse(string url, int? timeout, string userAgent, CookieCollection cookies) public static HttpWebResponse CreateGetHttpResponse(string url, int? timeout, string userAgent, CookieCollection cookies)
{ {
if (string.IsNullOrEmpty(url)) if (string.IsNullOrEmpty(url))
@ -50,16 +40,7 @@ namespace Wox.Infrastructure
} }
return request.GetResponse() as HttpWebResponse; return request.GetResponse() as HttpWebResponse;
} }
/// <summary>
/// 创建POST方式的HTTP请求
/// </summary>
/// <param name="url">请求的URL</param>
/// <param name="parameters">随同请求POST的参数名称及参数值字典</param>
/// <param name="timeout">请求的超时时间</param>
/// <param name="userAgent">请求的客户端浏览器信息,可以为空</param>
/// <param name="requestEncoding">发送HTTP请求时所用的编码</param>
/// <param name="cookies">随同HTTP请求发送的Cookie信息如果不需要身份验证可以为空</param>
/// <returns></returns>
public static HttpWebResponse CreatePostHttpResponse(string url, IDictionary<string, string> parameters, int? timeout, string userAgent, Encoding requestEncoding, CookieCollection cookies) public static HttpWebResponse CreatePostHttpResponse(string url, IDictionary<string, string> parameters, int? timeout, string userAgent, Encoding requestEncoding, CookieCollection cookies)
{ {
if (string.IsNullOrEmpty(url)) if (string.IsNullOrEmpty(url))
@ -71,7 +52,6 @@ namespace Wox.Infrastructure
throw new ArgumentNullException("requestEncoding"); throw new ArgumentNullException("requestEncoding");
} }
HttpWebRequest request = null; HttpWebRequest request = null;
//如果是发送HTTPS请求
if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase)) if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
{ {
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult); ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
@ -103,7 +83,6 @@ namespace Wox.Infrastructure
request.CookieContainer = new CookieContainer(); request.CookieContainer = new CookieContainer();
request.CookieContainer.Add(cookies); request.CookieContainer.Add(cookies);
} }
//如果需要POST数据
if (!(parameters == null || parameters.Count == 0)) if (!(parameters == null || parameters.Count == 0))
{ {
StringBuilder buffer = new StringBuilder(); StringBuilder buffer = new StringBuilder();
@ -131,7 +110,7 @@ namespace Wox.Infrastructure
private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{ {
return true; //总是接受 return true;
} }
} }
} }

View file

@ -70,6 +70,12 @@ namespace Wox.Infrastructure.Storage.UserSettings
[JsonProperty] [JsonProperty]
public OpacityMode OpacityMode { get; set; } public OpacityMode OpacityMode { get; set; }
[JsonProperty]
public bool EnableWebSearchSuggestion { get; set; }
[JsonProperty]
public string WebSearchSuggestionSource { get; set; }
[JsonProperty] [JsonProperty]
public bool LeaveCmdOpen { get; set; } public bool LeaveCmdOpen { get; set; }

View file

@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using Wox.Infrastructure;
using YAMP.Numerics;
namespace Wox.Plugin.SystemPlugins.SuggestionSources
{
public class Baidu : AbstractSuggestionSource
{
Regex reg = new Regex("window.baidu.sug\\((.*)\\)");
public override List<string> GetSuggestions(string query)
{
try
{
var response =
HttpRequest.CreateGetHttpResponse(
"http://suggestion.baidu.com/su?json=1&wd=" + Uri.EscapeUriString(query), null,
null, null);
var stream = response.GetResponseStream();
if (stream != null)
{
var body = new StreamReader(stream, Encoding.GetEncoding("GB2312")).ReadToEnd();
Match m = reg.Match(body);
if (m.Success)
{
var json = JsonConvert.DeserializeObject(m.Groups[1].Value) as JContainer;
if (json != null)
{
var results = json["s"] as JArray;
if (results != null)
{
return results.OfType<JValue>().Select(o => o.Value).OfType<string>().ToList();
}
}
}
}
}
catch
{ }
return null;
}
}
}

View file

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Wox.Plugin.SystemPlugins.SuggestionSources
{
public class SuggestionSourceFactory
{
public static ISuggestionSource GetSuggestionSource(string name)
{
switch (name.ToLower())
{
case "google":
return new Google();
case "baidu":
return new Baidu();
default:
return null;
}
}
}
}

View file

@ -32,7 +32,7 @@ namespace Wox.Plugin.SystemPlugins
title = subtitle; title = subtitle;
subtitle = null; subtitle = null;
} }
context.API.PushResults(query,context.CurrentPluginMetadata, new List<Result>() context.API.PushResults(query, context.CurrentPluginMetadata, new List<Result>()
{ {
new Result() new Result()
{ {
@ -48,24 +48,29 @@ namespace Wox.Plugin.SystemPlugins
} }
}); });
if (!string.IsNullOrEmpty(keyword)) if (UserSettingStorage.Instance.EnableWebSearchSuggestion && !string.IsNullOrEmpty(keyword))
{ {
ISuggestionSource sugg = new Google(); ISuggestionSource sugg = SuggestionSourceFactory.GetSuggestionSource(
var result = sugg.GetSuggestions(keyword); UserSettingStorage.Instance.WebSearchSuggestionSource);
if (result != null) if (sugg != null)
{ {
context.API.PushResults(query,context.CurrentPluginMetadata, result.Select(o => new Result() var result = sugg.GetSuggestions(keyword);
if (result != null)
{ {
Title = o, context.API.PushResults(query, context.CurrentPluginMetadata,
SubTitle = subtitle, result.Select(o => new Result()
Score = 5, {
IcoPath = webSearch.IconPath, Title = o,
Action = (c) => SubTitle = subtitle,
{ Score = 5,
Process.Start(webSearch.Url.Replace("{q}", o)); IcoPath = webSearch.IconPath,
return true; Action = (c) =>
} {
}).ToList()); Process.Start(webSearch.Url.Replace("{q}", o));
return true;
}
}).ToList());
}
} }
} }
} }

View file

@ -7,10 +7,16 @@
d:DesignHeight="300" d:DesignWidth="300"> d:DesignHeight="300" d:DesignWidth="300">
<Grid Margin="10"> <Grid Margin="10">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="*"/> <RowDefinition Height="42"/>
<RowDefinition/>
<RowDefinition Height="50"/> <RowDefinition Height="50"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<ListView x:Name="webSearchView" Grid.Row="0"> <StackPanel Orientation="Horizontal" Grid.Row="0">
<CheckBox x:Name="cbEnableWebSearchSuggestion" Unchecked="CbEnableWebSearchSuggestion_OnUnchecked" Checked="CbEnableWebSearchSuggestion_OnChecked" Margin="0 10 10 10">Enable search suggestions</CheckBox>
<ComboBox x:Name="comboBoxSuggestionSource" SelectionChanged="ComboBoxSuggestionSource_OnSelectionChanged" Margin="10">
</ComboBox>
</StackPanel>
<ListView x:Name="webSearchView" Grid.Row="1">
<ListView.View> <ListView.View>
<GridView> <GridView>
<GridViewColumn Header="ActionWord" Width="180"> <GridViewColumn Header="ActionWord" Width="180">
@ -30,7 +36,7 @@
</GridView> </GridView>
</ListView.View> </ListView.View>
</ListView> </ListView>
<StackPanel Grid.Row="1" HorizontalAlignment="Right" Orientation="Horizontal"> <StackPanel Grid.Row="2" HorizontalAlignment="Right" Orientation="Horizontal">
<Button x:Name="btnDeleteWebSearch" Click="btnDeleteWebSearch_OnClick" Width="100" Margin="10" Content="Delete"/> <Button x:Name="btnDeleteWebSearch" Click="btnDeleteWebSearch_OnClick" Width="100" Margin="10" Content="Delete"/>
<Button x:Name="btnEditWebSearch" Click="btnEditWebSearch_OnClick" Width="100" Margin="10" Content="Edit"/> <Button x:Name="btnEditWebSearch" Click="btnEditWebSearch_OnClick" Width="100" Margin="10" Content="Edit"/>
<Button x:Name="btnAddWebSearch" Click="btnAddWebSearch_OnClick" Width="100" Margin="10" Content="Add"/> <Button x:Name="btnAddWebSearch" Click="btnAddWebSearch_OnClick" Width="100" Margin="10" Content="Add"/>

View file

@ -1,4 +1,6 @@
using System.Windows; using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using Wox.Infrastructure.Storage.UserSettings; using Wox.Infrastructure.Storage.UserSettings;
@ -19,6 +21,24 @@ namespace Wox.Plugin.SystemPlugins
private void Setting_Loaded(object sender, RoutedEventArgs e) private void Setting_Loaded(object sender, RoutedEventArgs e)
{ {
webSearchView.ItemsSource = UserSettingStorage.Instance.WebSearches; webSearchView.ItemsSource = UserSettingStorage.Instance.WebSearches;
cbEnableWebSearchSuggestion.IsChecked = UserSettingStorage.Instance.EnableWebSearchSuggestion;
comboBoxSuggestionSource.Visibility = UserSettingStorage.Instance.EnableWebSearchSuggestion
? Visibility.Visible
: Visibility.Collapsed;
List<ComboBoxItem> items = new List<ComboBoxItem>()
{
new ComboBoxItem() {Content = "Google"},
new ComboBoxItem() {Content = "Bing" },
new ComboBoxItem() {Content = "Baidu"},
};
ComboBoxItem selected = items.FirstOrDefault(o => o.Content.ToString() == UserSettingStorage.Instance.WebSearchSuggestionSource);
if (selected == null)
{
selected = items[0];
}
comboBoxSuggestionSource.ItemsSource = items;
comboBoxSuggestionSource.SelectedItem = selected;
} }
public void ReloadWebSearchView() public void ReloadWebSearchView()
@ -66,5 +86,24 @@ namespace Wox.Plugin.SystemPlugins
} }
} }
private void CbEnableWebSearchSuggestion_OnChecked(object sender, RoutedEventArgs e)
{
comboBoxSuggestionSource.Visibility = Visibility.Visible;
UserSettingStorage.Instance.EnableWebSearchSuggestion = true;
UserSettingStorage.Instance.Save();
}
private void CbEnableWebSearchSuggestion_OnUnchecked(object sender, RoutedEventArgs e)
{
comboBoxSuggestionSource.Visibility = Visibility.Collapsed;
UserSettingStorage.Instance.EnableWebSearchSuggestion = false;
UserSettingStorage.Instance.Save();
}
private void ComboBoxSuggestionSource_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
UserSettingStorage.Instance.WebSearchSuggestionSource = ((ComboBoxItem)e.AddedItems[0]).Content.ToString();
UserSettingStorage.Instance.Save();
}
} }
} }

View file

@ -79,6 +79,8 @@
<Compile Include="Calculator.cs" /> <Compile Include="Calculator.cs" />
<Compile Include="Program\ProgramSources\FileSystemProgramSource.cs" /> <Compile Include="Program\ProgramSources\FileSystemProgramSource.cs" />
<Compile Include="Program\ProgramSources\UserStartMenuProgramSource.cs" /> <Compile Include="Program\ProgramSources\UserStartMenuProgramSource.cs" />
<Compile Include="SuggestionSources\Baidu.cs" />
<Compile Include="SuggestionSources\SuggestionSourceFactory.cs" />
<Compile Include="UrlPlugin.cs" /> <Compile Include="UrlPlugin.cs" />
<Compile Include="WebSearch\WebSearchesSetting.xaml.cs"> <Compile Include="WebSearch\WebSearchesSetting.xaml.cs">
<DependentUpon>WebSearchesSetting.xaml</DependentUpon> <DependentUpon>WebSearchesSetting.xaml</DependentUpon>

View file

@ -55,7 +55,6 @@ namespace Wox
private string lastQuery; private string lastQuery;
private ToolTip toolTip = new ToolTip(); private ToolTip toolTip = new ToolTip();
private bool isCMDMode = false;
private bool ignoreTextChange = false; private bool ignoreTextChange = false;
#endregion #endregion
@ -98,7 +97,7 @@ namespace Wox
{ {
Dispatcher.Invoke(new Action(() => Dispatcher.Invoke(new Action(() =>
{ {
var m = new Msg {Owner = GetWindow(this)}; var m = new Msg { Owner = GetWindow(this) };
m.Show(title, subTitle, iconPath); m.Show(title, subTitle, iconPath);
})); }));
} }
@ -324,8 +323,37 @@ namespace Wox
} }
}, TimeSpan.FromSeconds(0), lastQuery); }, TimeSpan.FromSeconds(0), lastQuery);
} }
}, TimeSpan.FromMilliseconds((isCMDMode = tbQuery.Text.StartsWith(">")) ? 0 : 150)); }, TimeSpan.FromMilliseconds(ShouldNotDelayQuery ? 0 : 150));
} }
private bool ShouldNotDelayQuery
{
get
{
return (bool)Dispatcher.Invoke(new Func<bool>(() =>
{
return IsCMDMode || IsWebSearchMode;
}));
}
}
private bool IsCMDMode
{
get
{
return tbQuery.Text.StartsWith(">");
}
}
private bool IsWebSearchMode
{
get
{
Query q = new Query(tbQuery.Text);
return !UserSettingStorage.Instance.EnableWebSearchSuggestion &&
UserSettingStorage.Instance.WebSearches.Exists(o => o.ActionWord == q.ActionName && o.Enabled);
}
}
private void Border_OnMouseDown(object sender, MouseButtonEventArgs e) private void Border_OnMouseDown(object sender, MouseButtonEventArgs e)
{ {
@ -446,11 +474,11 @@ namespace Wox
private void updateCmdMode() private void updateCmdMode()
{ {
var selected = resultCtrl.AcceptSelect(); var currentSelectedItem = resultCtrl.GetActiveResult();
if (selected != null) if (currentSelectedItem != null)
{ {
ignoreTextChange = true; ignoreTextChange = true;
tbQuery.Text = ">" + selected.Title; tbQuery.Text = ">" + currentSelectedItem.Title;
tbQuery.CaretIndex = tbQuery.Text.Length; tbQuery.CaretIndex = tbQuery.Text.Length;
} }
} }
@ -468,41 +496,41 @@ namespace Wox
case Key.Down: case Key.Down:
resultCtrl.SelectNext(); resultCtrl.SelectNext();
if (isCMDMode) updateCmdMode(); if (IsCMDMode) updateCmdMode();
toolTip.IsOpen = false; toolTip.IsOpen = false;
e.Handled = true; e.Handled = true;
break; break;
case Key.Up: case Key.Up:
resultCtrl.SelectPrev(); resultCtrl.SelectPrev();
if (isCMDMode) updateCmdMode(); if (IsCMDMode) updateCmdMode();
toolTip.IsOpen = false; toolTip.IsOpen = false;
e.Handled = true; e.Handled = true;
break; break;
case Key.PageDown: case Key.PageDown:
resultCtrl.SelectNextPage(); resultCtrl.SelectNextPage();
if (isCMDMode) updateCmdMode(); if (IsCMDMode) updateCmdMode();
toolTip.IsOpen = false; toolTip.IsOpen = false;
e.Handled = true; e.Handled = true;
break; break;
case Key.PageUp: case Key.PageUp:
resultCtrl.SelectPrevPage(); resultCtrl.SelectPrevPage();
if (isCMDMode) updateCmdMode(); if (IsCMDMode) updateCmdMode();
toolTip.IsOpen = false; toolTip.IsOpen = false;
e.Handled = true; e.Handled = true;
break; break;
case Key.Enter: case Key.Enter:
AcceptSelect(resultCtrl.AcceptSelect()); AcceptSelect(resultCtrl.GetActiveResult());
e.Handled = true; e.Handled = true;
break; break;
case Key.Back: case Key.Back:
if (BackKeyDownEvent != null) if (BackKeyDownEvent != null)
{ {
BackKeyDownEvent(tbQuery,new WoxKeyDownEventArgs() BackKeyDownEvent(tbQuery, new WoxKeyDownEventArgs()
{ {
Query = tbQuery.Text, Query = tbQuery.Text,
keyEventArgs = e keyEventArgs = e
@ -511,7 +539,7 @@ namespace Wox
break; break;
case Key.Tab: case Key.Tab:
AcceptSelect(resultCtrl.AcceptSelect()); AcceptSelect(resultCtrl.GetActiveResult());
e.Handled = true; e.Handled = true;
break; break;
} }
@ -559,7 +587,7 @@ namespace Wox
List<Result> l = waitShowResultList.Where(o => o.OriginQuery != null && o.OriginQuery.RawQuery == lastQuery).ToList(); List<Result> l = waitShowResultList.Where(o => o.OriginQuery != null && o.OriginQuery.RawQuery == lastQuery).ToList();
waitShowResultList.Clear(); waitShowResultList.Clear();
resultCtrl.AddResults(l); resultCtrl.AddResults(l);
})), TimeSpan.FromMilliseconds(isCMDMode ? 0 : 50)); })), TimeSpan.FromMilliseconds(ShouldNotDelayQuery ? 0 : 50));
} }
} }

View file

@ -126,7 +126,7 @@ namespace Wox
} }
} }
public Result AcceptSelect() public Result GetActiveResult()
{ {
int index = lbResults.SelectedIndex; int index = lbResults.SelectedIndex;
if (index < 0) return null; if (index < 0) return null;