PowerToys/Wox/PluginLoader/PythonPluginWrapper.cs

143 lines
4.5 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
2014-01-15 22:45:02 +08:00
using System.Linq;
2013-12-23 23:53:38 +08:00
using Newtonsoft.Json;
2014-01-11 00:19:14 +08:00
using Python.Runtime;
2014-01-29 18:33:24 +08:00
using Wox.Helper;
using Wox.Plugin;
2014-01-29 18:33:24 +08:00
namespace Wox.PluginLoader
{
public class PythonPluginWrapper : IPlugin
{
2013-12-23 19:21:51 +08:00
private PluginMetadata metadata;
2014-01-15 22:45:02 +08:00
private string moduleName;
2013-12-23 19:21:51 +08:00
public PythonPluginWrapper(PluginMetadata metadata)
{
2013-12-23 19:21:51 +08:00
this.metadata = metadata;
2014-01-15 22:45:02 +08:00
moduleName = metadata.ExecuteFileName.Replace(".py", "");
}
public List<Result> Query(Query query)
{
2013-12-27 00:39:07 +08:00
try
2013-12-26 20:18:08 +08:00
{
2014-01-15 22:45:02 +08:00
string jsonResult = InvokeFunc("query", query.RawQuery);
if (string.IsNullOrEmpty(jsonResult))
2013-12-27 20:06:49 +08:00
{
return new List<Result>();
}
List<PythonResult> o = JsonConvert.DeserializeObject<List<PythonResult>>(jsonResult);
2013-12-27 00:39:07 +08:00
List<Result> r = new List<Result>();
foreach (PythonResult pythonResult in o)
{
PythonResult ps = pythonResult;
2013-12-27 20:06:49 +08:00
if (!string.IsNullOrEmpty(ps.ActionName))
{
2014-02-28 23:21:01 +08:00
ps.Action = (context) =>
{
InvokeFunc(ps.ActionName, GetPythonActionContext(context), new PyString(ps.ActionPara));
return true;
};
2013-12-27 20:06:49 +08:00
}
2013-12-27 00:39:07 +08:00
r.Add(ps);
}
return r;
2013-12-26 20:18:08 +08:00
}
2014-02-22 18:04:59 +08:00
catch (Exception e)
2013-12-27 00:39:07 +08:00
{
#if (DEBUG)
{
2014-02-23 10:36:37 +08:00
throw new WoxPythonException(e.Message);
}
#endif
2014-02-22 18:04:59 +08:00
Log.Error(string.Format("Python Plugin {0} query failed: {1}", metadata.Name, e.Message));
2013-12-27 00:39:07 +08:00
}
return new List<Result>();
}
private PyObject GetPythonActionContext(ActionContext context)
2014-01-11 00:19:14 +08:00
{
PyDict dict = new PyDict();
PyDict specialKeyStateDict = new PyDict();
specialKeyStateDict["CtrlPressed"] = new PyString(context.SpecialKeyState.CtrlPressed.ToString());
specialKeyStateDict["AltPressed"] = new PyString(context.SpecialKeyState.AltPressed.ToString());
specialKeyStateDict["WinPressed"] = new PyString(context.SpecialKeyState.WinPressed.ToString());
specialKeyStateDict["ShiftPressed"] = new PyString(context.SpecialKeyState.ShiftPressed.ToString());
2014-01-15 22:45:02 +08:00
dict["SpecialKeyState"] = specialKeyStateDict;
return dict;
}
private string InvokeFunc(string func, params PyObject[] paras)
{
2014-02-22 18:04:59 +08:00
string json = null;
2014-01-15 22:45:02 +08:00
2014-03-13 22:31:44 +08:00
//if pythobn plugin folder name is chinese, here will deadlock.
2014-01-11 00:19:14 +08:00
IntPtr gs = PythonEngine.AcquireLock();
PyObject module = PythonEngine.ImportModule(moduleName);
2014-02-22 18:04:59 +08:00
if (module == null)
{
string error = string.Format("Python Invoke failed: {0} doesn't has module {1}",
2014-02-23 10:36:37 +08:00
metadata.ExecuteFilePath, moduleName);
2014-02-22 18:04:59 +08:00
Log.Error(error);
return json;
}
2014-01-15 22:45:02 +08:00
if (module.HasAttr(func))
{
2014-02-23 10:36:37 +08:00
try
{
PyObject res = paras.Length > 0 ? module.InvokeMethod(func, paras) : module.InvokeMethod(func);
json = Runtime.GetManagedString(res.Handle);
}
catch (Exception e)
{
string error = string.Format("Python Invoke failed: {0}", e.Message);
Log.Error(error);
#if (DEBUG)
{
throw new WoxPythonException(error);
}
#endif
}
2014-01-15 22:45:02 +08:00
}
else
{
string error = string.Format("Python Invoke failed: {0} doesn't has function {1}",
metadata.ExecuteFilePath, func);
Log.Error(error);
#if (DEBUG)
{
2014-02-23 10:36:37 +08:00
throw new WoxPythonException(error);
2014-01-15 22:45:02 +08:00
}
#endif
}
2014-01-11 00:19:14 +08:00
PythonEngine.ReleaseLock(gs);
return json;
}
private string InvokeFunc(string func, params string[] para)
{
PyObject[] paras = { };
if (para != null && para.Length > 0)
{
paras = para.Select(o => new PyString(o)).ToArray();
}
return InvokeFunc(func, paras);
}
2014-01-03 23:52:36 +08:00
public void Init(PluginInitContext context)
{
}
}
}