Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Python scripting capability #860

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 13 additions & 0 deletions .idea/.idea.SuperPutty/.idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions .idea/.idea.SuperPutty/.idea/.name

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions .idea/.idea.SuperPutty/.idea/encodings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/.idea.SuperPutty/.idea/indexLayout.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/.idea.SuperPutty/.idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions SuperPutty.sln.DotSettings.user
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Int64 x:Key="/Default/Environment/Hierarchy/Build/BuildTool/MsbuildVersion/@EntryValue">1114112</s:Int64>
<s:String x:Key="/Default/Environment/Hierarchy/Build/BuildTool/CustomBuildToolPath/@EntryValue">C:\Users\reggi\AppData\Local\JetBrains\BuildTools\MSBuild\Current\Bin\MSBuild.exe</s:String></wpf:ResourceDictionary>
52 changes: 52 additions & 0 deletions SuperPutty/Scripting/Spsl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
using log4net;
using SuperPutty;
using SuperPutty.Utils;
using SuperPutty.Data;
using IronPython.Hosting;
using Microsoft.Scripting.Hosting;

namespace SuperPuTTY.Scripting
{
Expand Down Expand Up @@ -105,6 +108,55 @@ public static void BeginExecuteScript(ExecuteScriptEventArgs scriptArgs)
}
}

/// <summary>Create an Action for a given command (keyword) executed in the Python script</summary>
/// <param name="keyword">The keyword for the command (i.e. SENDLINE)</param>
/// <param name="scriptArgs">A <seealso cref="ExecuteScriptEventArgs"/> object containing the script to execute
/// and parameters</param>
public static Action<object> CreatePythonCommandAction(string keyword, ExecuteScriptEventArgs scriptArgs)
{
void CommandAction(object line)
{
CommandData command;
TryParseScriptLine(keyword + " " + line, out command);

if (command != null)
{
command.SendToTerminal(scriptArgs.Handle.ToInt32());
}
}

return (CommandAction);
}

/// <summary>Execute a SPSL script Async</summary>
/// <param name="scriptArgs">A <seealso cref="ExecuteScriptEventArgs"/> object containing the script to execute
/// and parameters</param>
/// <param name="session">The SessionData in which to execute in Python script</param>
public static void BeginExecutePythonScript(ExecuteScriptEventArgs scriptArgs, SessionData session)
{
new System.Threading.Thread(delegate()
{
ScriptEngine engine = Python.CreateEngine();

// Create a ScriptSource to encapsulate our program and a scope in which it runs
ScriptSource source = engine.CreateScriptSourceFromString(scriptArgs.Script);
ScriptScope scope = engine.CreateScope();
foreach (SPSLFunction spslFunction in keywords)
{
scope.SetVariable(spslFunction.command,
CreatePythonCommandAction(spslFunction.command, scriptArgs));
}

if (session != null)
{
scope.SetVariable("Session", session);
}

// Execute the script in 'scope'
source.Execute(scope);
}).Start();
}

/// <summary>Find Valid spsl script commands from lookup table and retrieve the Function to execute</summary>
/// <param name="command">the SPSL command to lookup</param>
/// <returns>The Function associated with the command or null of the command is invalid</returns>
Expand Down
11 changes: 9 additions & 2 deletions SuperPutty/SuperPuTTY.cs
Original file line number Diff line number Diff line change
Expand Up @@ -529,8 +529,15 @@ public static ctlPuttyPanel OpenProtoSession(SessionData session)
if (!String.IsNullOrEmpty(script))
{
ExecuteScriptEventArgs scriptArgs = new ExecuteScriptEventArgs() { Script = script, Handle = panel.AppPanel.AppWindowHandle };
SPSL.BeginExecuteScript(scriptArgs);
}

if (scriptArgs.IsPython)
{
SPSL.BeginExecutePythonScript(scriptArgs, session);
}
else
{
SPSL.BeginExecuteScript(scriptArgs);
} }
}
} catch (InvalidOperationException ex)
{
Expand Down
31 changes: 30 additions & 1 deletion SuperPutty/SuperPutty.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>SuperPutty</RootNamespace>
<AssemblyName>SuperPutty</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<FileUpgradeFlags>
</FileUpgradeFlags>
Expand All @@ -33,6 +33,7 @@
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<LangVersion>9</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
Expand Down Expand Up @@ -65,9 +66,37 @@
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<ItemGroup>
<Reference Include="IronPython, Version=2.7.11.0, Culture=neutral, PublicKeyToken=7f709c5b713576e1">
<HintPath>..\packages\IronPython.2.7.11\lib\net45\IronPython.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="IronPython.Modules, Version=2.7.11.0, Culture=neutral, PublicKeyToken=7f709c5b713576e1">
<HintPath>..\packages\IronPython.2.7.11\lib\net45\IronPython.Modules.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="IronPython.SQLite, Version=2.7.11.0, Culture=neutral, PublicKeyToken=7f709c5b713576e1">
<HintPath>..\packages\IronPython.2.7.11\lib\net45\IronPython.SQLite.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="IronPython.Wpf, Version=2.7.11.0, Culture=neutral, PublicKeyToken=7f709c5b713576e1">
<HintPath>..\packages\IronPython.2.7.11\lib\net45\IronPython.Wpf.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="log4net, Version=2.0.13.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\packages\log4net.2.0.13\lib\net45\log4net.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Dynamic, Version=1.3.0.0, Culture=neutral, PublicKeyToken=7f709c5b713576e1">
<HintPath>..\packages\DynamicLanguageRuntime.1.3.0\lib\net45\Microsoft.Dynamic.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Scripting, Version=1.3.0.0, Culture=neutral, PublicKeyToken=7f709c5b713576e1">
<HintPath>..\packages\DynamicLanguageRuntime.1.3.0\lib\net45\Microsoft.Scripting.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Scripting.Metadata, Version=1.3.0.0, Culture=neutral, PublicKeyToken=7f709c5b713576e1">
<HintPath>..\packages\DynamicLanguageRuntime.1.3.0\lib\net45\Microsoft.Scripting.Metadata.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.VisualBasic" />
<Reference Include="Renci.SshNet, Version=2020.0.1.0, Culture=neutral, PublicKeyToken=1cee9f8bde3db106, processorArchitecture=MSIL">
<HintPath>..\packages\SSH.NET.2020.0.1\lib\net40\Renci.SshNet.dll</HintPath>
Expand Down
14 changes: 13 additions & 1 deletion SuperPutty/dlgScriptEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public class ExecuteScriptEventArgs : EventArgs
{
/// <summary>A string containing a list of commands to be sent to open terminal sessions</summary>
public string Script { get; set; }
/// <summary>True if the script should be handled by script parser</summary>
/// <summary>True if the script should be handled by SPSL script parser</summary>
public bool IsSPSL {
get
{
Expand All @@ -92,6 +92,18 @@ public class ExecuteScriptEventArgs : EventArgs
}
}

/// <summary>True if the script should be handled by Python script parser</summary>
public bool IsPython {
get
{
if (!string.IsNullOrEmpty(this.Script)
&& this.Script.StartsWith("#!/bin/python"))
return true;
else
return false;
}
}

/// <summary>If set to the handle of a window, script will be restricted to the specified session only.</summary>
public IntPtr Handle { get; set; }
}
Expand Down
22 changes: 18 additions & 4 deletions SuperPutty/frmSuperPutty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1209,8 +1209,9 @@ private int TrySendCommandsFromToolbar(bool saveHistory)
/// <summary>Send commands to open sessions</summary>
/// <param name="command">The <seealso cref="CommandData"/> object containing text and or keyboard commands</param>
/// <param name="saveHistory">If True, save the history in the command toolbar combobox</param>
/// <param name="isPythonScript">If True, send the command to the Python scripting engine</param>
/// <returns>The number terminals commands have been sent to</returns>
private int TrySendCommandsFromToolbar(CommandData command, bool saveHistory)
private int TrySendCommandsFromToolbar(CommandData command, bool saveHistory, bool isPythonScript = false)
{
int sent = 0;

Expand All @@ -1231,8 +1232,17 @@ private int TrySendCommandsFromToolbar(CommandData command, bool saveHistory)
int handle = hPtr.ToInt32();
//Log.InfoFormat("SendCommand: session={0}, command=[{1}], handle={2}", panel.Session.SessionId, command, handle);

command.SendToTerminal(handle);

if (isPythonScript)
{
SPSL.BeginExecutePythonScript(
new ExecuteScriptEventArgs() { Script = command.Command, Handle = hPtr },
panel.Session);
}
else
{
command.SendToTerminal(handle);
}

sent++;
}
}
Expand Down Expand Up @@ -1904,7 +1914,11 @@ private void Editor_ScriptReady(object sender, ExecuteScriptEventArgs e)
}
}).Start();
}
else // Not a spsl script
else if (e.IsPython)
{
TrySendCommandsFromToolbar(new CommandData(e.Script), false, true);
}
else // Not a spsl or Python script
{
foreach (string line in scriptlines)
{
Expand Down
2 changes: 2 additions & 0 deletions SuperPutty/packages.config
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
<packages>
<package id="DockPanelSuite" version="3.1.0" targetFramework="net45" />
<package id="DockPanelSuite.ThemeVS2005" version="3.1.0" targetFramework="net45" />
<package id="DynamicLanguageRuntime" version="1.3.0" targetFramework="net452" />
<package id="IronPython" version="2.7.11" targetFramework="net452" />
<package id="log4net" version="2.0.13" targetFramework="net45" />
<package id="Microsoft.VisualBasic" version="10.3.0" targetFramework="net45" />
<package id="SSH.NET" version="2020.0.1" targetFramework="net45" />
Expand Down
2 changes: 1 addition & 1 deletion SuperPuttyUnitTests/SuperPuttyUnitTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>SuperPuttyUnitTests</RootNamespace>
<AssemblyName>SuperPuttyUnitTests</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<FileAlignment>512</FileAlignment>
Expand Down