232 lines
7.9 KiB
C#
232 lines
7.9 KiB
C#
using System;
|
|
|
|
namespace umbraco.scripting
|
|
{
|
|
|
|
/// <summary>
|
|
/// Something like a proxy to IronPython. Does some initial settings and calls.
|
|
/// Maps IronPython's StandardOutput and StandardError to a simple string.
|
|
/// </summary>
|
|
public class python
|
|
{
|
|
protected internal static PythonEngine Engine;
|
|
protected static System.IO.MemoryStream ms;
|
|
protected static System.IO.StreamReader sr;
|
|
protected internal static System.Collections.Hashtable scripts;
|
|
|
|
static python()
|
|
{
|
|
Engine = new PythonEngine();
|
|
|
|
initEnv();
|
|
loadScripts();
|
|
|
|
ms = new System.IO.MemoryStream();
|
|
sr = new System.IO.StreamReader(ms);
|
|
Engine.SetStandardOutput(ms);
|
|
Engine.SetStandardError(ms);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// To be able to import umbraco dll's we have to append the umbraco path to python.
|
|
/// It should also be possible to import other python scripts from umbracos python folder.
|
|
/// And finally to run run some custom init stuff the script site.py in umbraco's
|
|
/// root folder will be executed.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private static void initEnv()
|
|
{
|
|
// Add umbracos bin folder to python's path
|
|
string path = System.Web.HttpContext.Current.Server.MapPath(GlobalSettings.Path + "\\..\\bin");
|
|
Engine.AddToPath(path);
|
|
|
|
// Add umbracos python folder to python's path
|
|
path = System.Web.HttpContext.Current.Server.MapPath(GlobalSettings.Path + "\\..\\python");
|
|
Engine.AddToPath(path);
|
|
|
|
// execute the site.py to do all the initial stuff
|
|
string initFile = System.Web.HttpContext.Current.Server.MapPath(GlobalSettings.Path + "\\..\\site.py");
|
|
Engine.ExecuteFile(initFile);
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
private static void loadScripts()
|
|
{
|
|
scripts = new System.Collections.Hashtable();
|
|
string path = System.Web.HttpContext.Current.Server.MapPath(GlobalSettings.Path + "\\..\\python");
|
|
System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(path);
|
|
foreach (System.IO.FileInfo f in dir.GetFiles("*.py"))
|
|
{
|
|
if (!f.Name.EndsWith("_temp.py"))
|
|
{
|
|
try
|
|
{
|
|
scripts[f.FullName] = Engine.CompileFile(f.FullName );
|
|
}
|
|
catch
|
|
{
|
|
scripts[f.FullName] = Engine.Compile("print 'error in file " + f.Name + "'");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Executes a python command like in console
|
|
/// </summary>
|
|
/// <param name="expression">command to execute</param>
|
|
/// <returns>returns standard out of executed command</returns>
|
|
public static string execute(string expression)
|
|
{
|
|
if (!(expression == null))
|
|
{
|
|
string ret;
|
|
ms.SetLength(0);
|
|
ms.Flush();
|
|
try
|
|
{
|
|
Engine.Execute(expression);
|
|
ms.Position = 0;
|
|
ret = sr.ReadToEnd();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ret = ex.Message;
|
|
}
|
|
return ret;
|
|
}
|
|
else
|
|
{
|
|
return string.Empty;
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Executes a python script like in console
|
|
/// </summary>
|
|
/// <param name="file">absolute path to script</param>
|
|
/// <returns>returns standard out of executed script</returns>
|
|
public static string executeFile(string file)
|
|
{
|
|
if (System.IO.File.Exists(file))
|
|
{
|
|
string ret;
|
|
ms.SetLength(0);
|
|
ms.Flush();
|
|
|
|
scripts[file].GetType().InvokeMember("Execute", System.Reflection.BindingFlags.InvokeMethod, null, scripts[file], null);
|
|
|
|
ms.Position = 0;
|
|
ret = sr.ReadToEnd();
|
|
return ret;
|
|
}
|
|
else
|
|
{
|
|
return "The File " + file + " could not be found.";
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Compiles a python script and add it to umbraco's script collection.
|
|
/// If compilation fails then an exception will be raised.
|
|
/// </summary>
|
|
/// <param name="file">absolute path to script</param>
|
|
/// <returns></returns>
|
|
public static void compileFile(string file)
|
|
{
|
|
loadScripts();
|
|
scripts[file] = Engine.CompileFile(file);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Compiles a python script.
|
|
/// If compilation fails then an exception will be raised.
|
|
/// </summary>
|
|
/// <param name="file">absolute path to script</param>
|
|
/// <returns></returns>
|
|
public static void tryCompile(string file)
|
|
{
|
|
Engine.CompileFile(file);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// The Class PythonEngine is just a wrapper for the real class IronPython.Hosting.PythonEngine
|
|
/// in IronPython. In this manner we does not need a hard reference to the IronPython assembly.
|
|
/// I've implemented only the methods i need for my purpose.
|
|
/// </summary>
|
|
public class PythonEngine
|
|
{
|
|
protected object Engine;
|
|
|
|
public PythonEngine()
|
|
{
|
|
string path = System.Web.HttpContext.Current.Server.MapPath(GlobalSettings.Path + "\\..\\bin\\IronPython.dll");
|
|
System.Reflection.Assembly asm = System.Reflection.Assembly.LoadFile(path);
|
|
System.Type EngineType = asm.GetType("IronPython.Hosting.PythonEngine");
|
|
Engine = System.Activator.CreateInstance(EngineType);
|
|
}
|
|
|
|
public void AddToPath(string path)
|
|
{
|
|
Engine.GetType().InvokeMember("AddToPath", System.Reflection.BindingFlags.InvokeMethod, null, Engine, new object[] { path });
|
|
}
|
|
|
|
public void SetStandardOutput(System.IO.Stream stream)
|
|
{
|
|
Engine.GetType().InvokeMember("SetStandardOutput", System.Reflection.BindingFlags.InvokeMethod, null, Engine, new object[] { stream });
|
|
}
|
|
|
|
public void SetStandardError(System.IO.Stream stream)
|
|
{
|
|
Engine.GetType().InvokeMember("SetStandardError", System.Reflection.BindingFlags.InvokeMethod, null, Engine, new object[] { stream });
|
|
}
|
|
|
|
public void ExecuteFile(string FileName)
|
|
{
|
|
Engine.GetType().InvokeMember("ExecuteFile", System.Reflection.BindingFlags.InvokeMethod, null, Engine, new object[] { FileName });
|
|
}
|
|
|
|
public void Execute(string ScriptCode)
|
|
{
|
|
Engine.GetType().InvokeMember("Execute", System.Reflection.BindingFlags.InvokeMethod, null, Engine, new object[] { ScriptCode });
|
|
}
|
|
|
|
public Object CompileFile(string FileName)
|
|
{
|
|
return Engine.GetType().InvokeMember("CompileFile", System.Reflection.BindingFlags.InvokeMethod, null, Engine, new object[] { FileName });
|
|
}
|
|
|
|
public Object Compile(string Expression)
|
|
{
|
|
return Engine.GetType().InvokeMember("Compile", System.Reflection.BindingFlags.InvokeMethod, null, Engine, new object[] { Expression });
|
|
}
|
|
|
|
public Object CreateModule(string Modulename, bool publish)
|
|
{
|
|
return Engine.GetType().InvokeMember("CreateModule", System.Reflection.BindingFlags.InvokeMethod, null, Engine, new object[] { Modulename, publish });
|
|
}
|
|
|
|
public System.Collections.IDictionary Globals
|
|
{
|
|
set
|
|
{
|
|
Engine.GetType().InvokeMember("Globals", System.Reflection.BindingFlags.SetProperty, null, Engine, new object[] { value });
|
|
}
|
|
get
|
|
{
|
|
return (System.Collections.IDictionary)Engine.GetType().InvokeMember("Globals", System.Reflection.BindingFlags.GetProperty, null, Engine, null);
|
|
}
|
|
}
|
|
}
|
|
} |