diff --git a/Plugins/WinAlfred.Plugin.DouBan/Images/movies.png b/Plugins/WinAlfred.Plugin.DouBan/Images/movies.png new file mode 100644 index 0000000000..a8ec632c4f Binary files /dev/null and b/Plugins/WinAlfred.Plugin.DouBan/Images/movies.png differ diff --git a/Plugins/WinAlfred.Plugin.DouBan/main.py b/Plugins/WinAlfred.Plugin.DouBan/main.py index bb47feeda7..e74e852a82 100644 --- a/Plugins/WinAlfred.Plugin.DouBan/main.py +++ b/Plugins/WinAlfred.Plugin.DouBan/main.py @@ -2,7 +2,7 @@ import requests from bs4 import BeautifulSoup import json - +import webbrowser def query(key): k = key.split(" ")[1] @@ -15,15 +15,18 @@ def query(key): res = {} title = i.select("a")[0].text.replace("\n","").replace(" ","") score = i.select("span.rating_nums")[0].text if i.select("span.rating_nums") else "0" - res["Title"] = title - res["SubTitle"] = score + res["Title"] = title.split("/")[0] + year = i.select("p.pl")[0].text.split("-")[0] if i.select("p.pl")[0] else "Null" + alias = title.split("/")[1] if len(title.split("/")) >= 2 else "Null" + res["SubTitle"] = "Year: " + year + " Score: " + score + " Alias: " + alias res["ActionName"] = "openUrl" + res["IcoPath"] = "Images\\movies.png" res["ActionPara"] = i.select("a[href]")[0]["href"] results.append(res) return json.dumps(results) def openUrl(url): - pass + webbrowser.open(url) if __name__ == "__main__": print query("movie geo") diff --git a/WinAlfred/Commands/PluginCommand.cs b/WinAlfred/Commands/PluginCommand.cs index f30b667ac3..81f5e739d1 100644 --- a/WinAlfred/Commands/PluginCommand.cs +++ b/WinAlfred/Commands/PluginCommand.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading; +using Python.Runtime; using WinAlfred.Helper; using WinAlfred.Plugin; using WinAlfred.PluginLoader; @@ -9,6 +11,9 @@ namespace WinAlfred.Commands { public class PluginCommand : BaseCommand { + private string currentPythonModulePath = string.Empty; + private IntPtr GIL; + public PluginCommand(MainWindow mainWindow) : base(mainWindow) { @@ -17,36 +22,56 @@ namespace WinAlfred.Commands public override void Dispatch(Query q) { - - foreach (PluginPair pair in Plugins.AllPlugins) + PluginPair thirdPlugin = Plugins.AllPlugins.FirstOrDefault(o => o.Metadata.ActionKeyword == q.ActionName); + if (thirdPlugin != null && !string.IsNullOrEmpty(thirdPlugin.Metadata.ActionKeyword)) { - if (pair.Metadata.ActionKeyword == q.ActionName) + if (thirdPlugin.Metadata.Language == AllowedLanguage.Python) { - PluginPair pair1 = pair; - ThreadPool.QueueUserWorkItem(state => - { - try - { - List r = pair1.Plugin.Query(q); - r.ForEach(o => - { - o.PluginDirectory = pair1.Metadata.PluginDirecotry; - o.OriginQuery = q; - }); - UpdateResultView(r); - } - catch (Exception queryException) - { - Log.Error(string.Format("Plugin {0} query failed: {1}", pair1.Metadata.Name, - queryException.Message)); -#if (DEBUG) - { - throw; - } -#endif - } - }); + SwitchPythonEnv(thirdPlugin); } + ThreadPool.QueueUserWorkItem(t => + { + try + { + List r = thirdPlugin.Plugin.Query(q); + r.ForEach(o => + { + o.PluginDirectory = thirdPlugin.Metadata.PluginDirecotry; + o.OriginQuery = q; + }); + UpdateResultView(r); + } + catch (Exception queryException) + { + Log.Error(string.Format("Plugin {0} query failed: {1}", thirdPlugin.Metadata.Name, + queryException.Message)); +#if (DEBUG) + { + throw; + } +#endif + } + }); + } + } + + private void SwitchPythonEnv(PluginPair thirdPlugin) + { + if (currentPythonModulePath != thirdPlugin.Metadata.PluginDirecotry) + { + //this must initial in main thread + currentPythonModulePath = thirdPlugin.Metadata.PluginDirecotry; + + if (GIL != IntPtr.Zero) + { + Runtime.PyEval_RestoreThread(GIL); + PythonEngine.Shutdown(); + } + PythonEngine.Initialize(); + IntPtr pyStrPtr = Runtime.PyString_FromString(thirdPlugin.Metadata.PluginDirecotry); + IntPtr SysDotPath = Runtime.PySys_GetObject("path"); + Runtime.PyList_Append(SysDotPath, pyStrPtr); + GIL = PythonEngine.BeginAllowThreads(); } } } diff --git a/WinAlfred/MainWindow.xaml.cs b/WinAlfred/MainWindow.xaml.cs index 12af291774..acef9d0906 100644 --- a/WinAlfred/MainWindow.xaml.cs +++ b/WinAlfred/MainWindow.xaml.cs @@ -45,7 +45,7 @@ namespace WinAlfred void MainWindow_Closed(object sender, EventArgs e) { - PythonEngine.Shutdown(); + //PythonEngine.Shutdown(); } private void InitProgressbarAnimation() diff --git a/WinAlfred/PluginLoader/BasePluginLoader.cs b/WinAlfred/PluginLoader/BasePluginLoader.cs index 6a48e7aa0e..3acf56d129 100644 --- a/WinAlfred/PluginLoader/BasePluginLoader.cs +++ b/WinAlfred/PluginLoader/BasePluginLoader.cs @@ -117,5 +117,16 @@ namespace WinAlfred.PluginLoader return null; } } + + ///// + ///// Change python execute file name to unique file name using GUID + ///// this is because if two pythong plugin use the same + ///// + ///// + ///// + //private static PluginMetadata filterPythonMetadata(PluginMetadata metadata) + //{ + + //} } } diff --git a/WinAlfred/PluginLoader/PythonPluginLoader.cs b/WinAlfred/PluginLoader/PythonPluginLoader.cs index 52509f8aaa..a31fea21fd 100644 --- a/WinAlfred/PluginLoader/PythonPluginLoader.cs +++ b/WinAlfred/PluginLoader/PythonPluginLoader.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Threading; using Python.Runtime; @@ -11,8 +12,7 @@ namespace WinAlfred.PluginLoader static PythonPluginLoader() { - PythonEngine.Initialize(); - PythonEngine.BeginAllowThreads(); + } public override List LoadPlugin() diff --git a/WinAlfred/PluginLoader/PythonPluginWrapper.cs b/WinAlfred/PluginLoader/PythonPluginWrapper.cs index 4288b4eddd..1ecba68c8c 100644 --- a/WinAlfred/PluginLoader/PythonPluginWrapper.cs +++ b/WinAlfred/PluginLoader/PythonPluginWrapper.cs @@ -10,6 +10,7 @@ namespace WinAlfred.PluginLoader { public class PythonPluginWrapper : IPlugin { + private PluginMetadata metadata; public PythonPluginWrapper(PluginMetadata metadata) @@ -21,13 +22,13 @@ namespace WinAlfred.PluginLoader { try { - string s = InvokeFunc(metadata.PluginDirecotry, metadata.ExecuteFileName.Replace(".py", ""),"query",query.RawQuery); - if (string.IsNullOrEmpty(s)) + string jsonResult = InvokeFunc(metadata.PluginDirecotry, metadata.ExecuteFileName.Replace(".py", ""), "query", query.RawQuery); + if (string.IsNullOrEmpty(jsonResult)) { return new List(); } - List o = JsonConvert.DeserializeObject>(s); + List o = JsonConvert.DeserializeObject>(jsonResult); List r = new List(); foreach (PythonResult pythonResult in o) { @@ -42,22 +43,20 @@ namespace WinAlfred.PluginLoader } catch (Exception) { - - throw; +#if (DEBUG) + { + throw; + } +#endif } } - private string InvokeFunc(string path, string moduleName,string func, string para) + private string InvokeFunc(string path, string moduleName, string func, string para) { IntPtr gs = PythonEngine.AcquireLock(); - IntPtr pyStrPtr = Runtime.PyString_FromString(path); - IntPtr SysDotPath = Runtime.PySys_GetObject("path"); - Runtime.PyList_Append(SysDotPath, pyStrPtr); - PyObject module = PythonEngine.ImportModule(moduleName); - module = PythonEngine.ReloadModule(module); PyObject res = module.InvokeMethod(func, new PyString(para)); string json = Runtime.GetManagedString(res.Handle); @@ -68,7 +67,7 @@ namespace WinAlfred.PluginLoader public void Init(PluginInitContext context) { - + } } }