diff --git a/Wox.Infrastructure/HttpRequest.cs b/Wox.Infrastructure/HttpRequest.cs
new file mode 100644
index 0000000000..1e53db6d0b
--- /dev/null
+++ b/Wox.Infrastructure/HttpRequest.cs
@@ -0,0 +1,137 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Security;
+using System.Reflection;
+using System.Security.Cryptography.X509Certificates;
+using System.Text;
+
+//From:http://blog.csdn.net/zhoufoxcn/article/details/6404236
+namespace Wox.Infrastructure
+{
+ ///
+ /// 有关HTTP请求的辅助类
+ ///
+ public class HttpRequest
+ {
+ private static readonly string DefaultUserAgent = "Wox/" + Assembly.GetEntryAssembly().GetName().Version.ToString() + " (+https://github.com/qianlifeng/Wox)";
+
+ ///
+ /// 创建GET方式的HTTP请求
+ ///
+ /// 请求的URL
+ /// 请求的超时时间
+ /// 请求的客户端浏览器信息,可以为空
+ /// 随同HTTP请求发送的Cookie信息,如果不需要身份验证可以为空
+ ///
+ public static HttpWebResponse CreateGetHttpResponse(string url, int? timeout, string userAgent, CookieCollection cookies)
+ {
+ if (string.IsNullOrEmpty(url))
+ {
+ throw new ArgumentNullException("url");
+ }
+ HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
+ request.Method = "GET";
+ request.UserAgent = DefaultUserAgent;
+ if (!string.IsNullOrEmpty(userAgent))
+ {
+ request.UserAgent = userAgent;
+ }
+ if (timeout.HasValue)
+ {
+ request.Timeout = timeout.Value;
+ }
+ if (cookies != null)
+ {
+ request.CookieContainer = new CookieContainer();
+ request.CookieContainer.Add(cookies);
+ }
+ return request.GetResponse() as HttpWebResponse;
+ }
+ ///
+ /// 创建POST方式的HTTP请求
+ ///
+ /// 请求的URL
+ /// 随同请求POST的参数名称及参数值字典
+ /// 请求的超时时间
+ /// 请求的客户端浏览器信息,可以为空
+ /// 发送HTTP请求时所用的编码
+ /// 随同HTTP请求发送的Cookie信息,如果不需要身份验证可以为空
+ ///
+ public static HttpWebResponse CreatePostHttpResponse(string url, IDictionary parameters, int? timeout, string userAgent, Encoding requestEncoding, CookieCollection cookies)
+ {
+ if (string.IsNullOrEmpty(url))
+ {
+ throw new ArgumentNullException("url");
+ }
+ if (requestEncoding == null)
+ {
+ throw new ArgumentNullException("requestEncoding");
+ }
+ HttpWebRequest request = null;
+ //如果是发送HTTPS请求
+ if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
+ {
+ ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
+ request = WebRequest.Create(url) as HttpWebRequest;
+ request.ProtocolVersion = HttpVersion.Version10;
+ }
+ else
+ {
+ request = WebRequest.Create(url) as HttpWebRequest;
+ }
+ request.Method = "POST";
+ request.ContentType = "application/x-www-form-urlencoded";
+
+ if (!string.IsNullOrEmpty(userAgent))
+ {
+ request.UserAgent = userAgent;
+ }
+ else
+ {
+ request.UserAgent = DefaultUserAgent;
+ }
+
+ if (timeout.HasValue)
+ {
+ request.Timeout = timeout.Value;
+ }
+ if (cookies != null)
+ {
+ request.CookieContainer = new CookieContainer();
+ request.CookieContainer.Add(cookies);
+ }
+ //如果需要POST数据
+ if (!(parameters == null || parameters.Count == 0))
+ {
+ StringBuilder buffer = new StringBuilder();
+ int i = 0;
+ foreach (string key in parameters.Keys)
+ {
+ if (i > 0)
+ {
+ buffer.AppendFormat("&{0}={1}", key, parameters[key]);
+ }
+ else
+ {
+ buffer.AppendFormat("{0}={1}", key, parameters[key]);
+ }
+ i++;
+ }
+ byte[] data = requestEncoding.GetBytes(buffer.ToString());
+ using (Stream stream = request.GetRequestStream())
+ {
+ stream.Write(data, 0, data.Length);
+ }
+ }
+ return request.GetResponse() as HttpWebResponse;
+ }
+
+ private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
+ {
+ return true; //总是接受
+ }
+ }
+}
diff --git a/Wox.Infrastructure/Wox.Infrastructure.csproj b/Wox.Infrastructure/Wox.Infrastructure.csproj
index e3c8ae0600..c1dc32ec1c 100644
--- a/Wox.Infrastructure/Wox.Infrastructure.csproj
+++ b/Wox.Infrastructure/Wox.Infrastructure.csproj
@@ -49,6 +49,7 @@
+
diff --git a/Wox.Plugin.System/CMD/CMD.cs b/Wox.Plugin.System/CMD/CMD.cs
index f2d5b1dd35..279e012881 100644
--- a/Wox.Plugin.System/CMD/CMD.cs
+++ b/Wox.Plugin.System/CMD/CMD.cs
@@ -57,7 +57,7 @@ namespace Wox.Plugin.System.CMD
}
catch (Exception) { }
- context.PushResults(new List() { result });
+ context.PushResults(query, new List() { result });
IEnumerable history = CMDStorage.Instance.CMDHistory.Where(o => o.Key.Contains(cmd))
.OrderByDescending(o => o.Value)
@@ -92,7 +92,7 @@ namespace Wox.Plugin.System.CMD
return ret;
}).Where(o => o != null).Take(4);
- context.PushResults(history.ToList());
+ context.PushResults(query, history.ToList());
try
{
diff --git a/Wox.Plugin.System/SuggestionSources/Google.cs b/Wox.Plugin.System/SuggestionSources/Google.cs
new file mode 100644
index 0000000000..4ae376a8b4
--- /dev/null
+++ b/Wox.Plugin.System/SuggestionSources/Google.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Xml;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json.Serialization;
+using Wox.Infrastructure;
+using YAMP.Numerics;
+
+namespace Wox.Plugin.System.SuggestionSources
+{
+ public class Google : AbstractSuggestionSource
+ {
+ public override List GetSuggestions(string query)
+ {
+ var response =
+ HttpRequest.CreateGetHttpResponse("https://www.google.com/complete/search?output=chrome&q=" + Uri.EscapeUriString(query), null,
+ null, null);
+ var stream = response.GetResponseStream();
+
+ if (stream != null)
+ {
+ var body = new StreamReader(stream).ReadToEnd();
+ var json = JsonConvert.DeserializeObject(body) as JContainer;
+ if (json != null)
+ {
+ var results = json[1] as JContainer;
+ if (results != null)
+ {
+ var j = results.OfType().Select(o => o.Value);
+ return results.OfType().Select(o => o.Value).OfType().ToList();
+ }
+ }
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/Wox.Plugin.System/SuggestionSources/ISuggestionSource.cs b/Wox.Plugin.System/SuggestionSources/ISuggestionSource.cs
new file mode 100644
index 0000000000..4683f3cab2
--- /dev/null
+++ b/Wox.Plugin.System/SuggestionSources/ISuggestionSource.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Cryptography.X509Certificates;
+using System.Text;
+
+namespace Wox.Plugin.System.SuggestionSources
+{
+ public interface ISuggestionSource
+ {
+ List GetSuggestions(string query);
+ }
+
+ public abstract class AbstractSuggestionSource : ISuggestionSource
+ {
+ public abstract List GetSuggestions(string query);
+ }
+}
diff --git a/Wox.Plugin.System/WebSearchPlugin.cs b/Wox.Plugin.System/WebSearchPlugin.cs
index ca35b46f6a..07f62f2057 100644
--- a/Wox.Plugin.System/WebSearchPlugin.cs
+++ b/Wox.Plugin.System/WebSearchPlugin.cs
@@ -7,11 +7,14 @@ using Newtonsoft.Json;
using Wox.Infrastructure;
using Wox.Infrastructure.Storage;
using Wox.Infrastructure.Storage.UserSettings;
+using Wox.Plugin.System.SuggestionSources;
namespace Wox.Plugin.System
{
public class WebSearchPlugin : BaseSystemPlugin
{
+ private PluginInitContext context;
+
protected override List QueryInternal(Query query)
{
List results = new List();
@@ -23,22 +26,49 @@ namespace Wox.Plugin.System
if (webSearch != null)
{
string keyword = query.ActionParameters.Count > 0 ? query.GetAllRemainingParameter() : "";
- string title = string.Format("Search {0} for \"{1}\"", webSearch.Title, keyword);
+ string title = keyword;
+ string subtitle = "Search " + webSearch.Title;
if (string.IsNullOrEmpty(keyword))
{
- title = "Search " + webSearch.Title;
+ title = subtitle;
+ subtitle = null;
}
- results.Add(new Result()
+ context.PushResults(query, new List()
{
- Title = title,
- Score = 6,
- IcoPath = webSearch.IconPath,
- Action = (c) =>
+ new Result()
{
- Process.Start(webSearch.Url.Replace("{q}", keyword));
- return true;
+ Title = title,
+ SubTitle = subtitle,
+ Score = 6,
+ IcoPath = webSearch.IconPath,
+ Action = (c) =>
+ {
+ Process.Start(webSearch.Url.Replace("{q}", keyword));
+ return true;
+ }
}
});
+
+ if (!string.IsNullOrEmpty(keyword))
+ {
+ ISuggestionSource sugg = new Google();
+ var result = sugg.GetSuggestions(keyword);
+ if (result != null)
+ {
+ context.PushResults(query, result.Select(o => new Result()
+ {
+ Title = o,
+ SubTitle = subtitle,
+ Score = 5,
+ IcoPath = webSearch.IconPath,
+ Action = (c) =>
+ {
+ Process.Start(webSearch.Url.Replace("{q}", o));
+ return true;
+ }
+ }).ToList());
+ }
+ }
}
return results;
@@ -46,6 +76,7 @@ namespace Wox.Plugin.System
protected override void InitInternal(PluginInitContext context)
{
+ this.context = context;
}
}
}
diff --git a/Wox.Plugin.System/Wox.Plugin.System.csproj b/Wox.Plugin.System/Wox.Plugin.System.csproj
index d44cae02a4..685d2ca9e0 100644
--- a/Wox.Plugin.System/Wox.Plugin.System.csproj
+++ b/Wox.Plugin.System/Wox.Plugin.System.csproj
@@ -70,6 +70,8 @@
+
+
diff --git a/Wox.Plugin/PluginInitContext.cs b/Wox.Plugin/PluginInitContext.cs
index 7169132dee..68be7a58f1 100644
--- a/Wox.Plugin/PluginInitContext.cs
+++ b/Wox.Plugin/PluginInitContext.cs
@@ -32,6 +32,6 @@ namespace Wox.Plugin
public Func ShellRun { get; set; }
- public Action> PushResults { get; set; }
+ public Action> PushResults { get; set; }
}
}
diff --git a/Wox/Commands/PluginCommand.cs b/Wox/Commands/PluginCommand.cs
index 8a29e4a7e8..5770188ad4 100644
--- a/Wox/Commands/PluginCommand.cs
+++ b/Wox/Commands/PluginCommand.cs
@@ -27,17 +27,17 @@ namespace Wox.Commands
{
try
{
- thirdPlugin.InitContext.PushResults = r =>
+ thirdPlugin.InitContext.PushResults = (qu, r) =>
{
r.ForEach(o =>
{
o.PluginDirectory = thirdPlugin.Metadata.PluginDirecotry;
- o.OriginQuery = q;
+ o.OriginQuery = qu;
});
UpdateResultView(r);
};
List results = thirdPlugin.Plugin.Query(q) ?? new List();
- thirdPlugin.InitContext.PushResults(results);
+ thirdPlugin.InitContext.PushResults(q, results);
}
catch (Exception queryException)
{
diff --git a/Wox/Commands/SystemCommand.cs b/Wox/Commands/SystemCommand.cs
index 0d90c0a90c..30816701bf 100644
--- a/Wox/Commands/SystemCommand.cs
+++ b/Wox/Commands/SystemCommand.cs
@@ -17,20 +17,20 @@ namespace Wox.Commands
PluginPair pair1 = pair;
ThreadPool.QueueUserWorkItem(state =>
{
- pair1.InitContext.PushResults = r =>
+ pair1.InitContext.PushResults = (q, r) =>
{
if (r == null || r.Count == 0) return;
foreach (Result result in r)
{
result.PluginDirectory = pair1.Metadata.PluginDirecotry;
- result.OriginQuery = query;
+ result.OriginQuery = q;
result.AutoAjustScore = true;
}
UpdateResultView(r);
};
List results = pair1.Plugin.Query(query);
- pair1.InitContext.PushResults(results);
+ pair1.InitContext.PushResults(query, results);
});
}
}