Skip to content

Commit

Permalink
Provide a strategy for host integrator's to set the python template a…
Browse files Browse the repository at this point in the history
…t startup (DynamoDS#9533)

* provide a strategy for host integrators to set Python node template at startup programmatically

* use 'is' as opposed to 'try/catch'

* Fix several bugs around previously existing logging statements

* add unit tests verifying valid and invalid  API usage
  • Loading branch information
alfarok committed Mar 8, 2019
1 parent ed24b08 commit 71aa22e
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 21 deletions.
65 changes: 56 additions & 9 deletions src/DynamoCore/Models/DynamoModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,7 @@ public struct DefaultStartConfiguration : IStartConfiguration
public IEnumerable<IExtension> Extensions { get; set; }
public TaskProcessMode ProcessMode { get; set; }
public bool IsHeadless { get; set; }
public string PythonTemplatePath { get; set; }
}

/// <summary>
Expand Down Expand Up @@ -636,21 +637,50 @@ protected DynamoModel(IStartConfiguration config)
var userDataFolder = pathManager.GetUserDataFolder(); // Get the default user data path
AddPackagePath(userDataFolder);

// Check if the Python template file specified in the settings file exists & it's not empty
// If not, check the default filepath for the Python template (userDataFolder\PythonTemplate.py).
// If that doesn't exist either or is empty, Dynamo falls back to the hard-coded Python script template.
// We log the behaviour to make it easy for users to troubleshoot this.
// Load Python Template
// The loading pattern is conducted in the following order
// 1) Set from DynamoSettings.XML
// 2) Set from API via the configuration file
// 3) Set from PythonTemplate.py located in 'C:\Users\USERNAME\AppData\Roaming\Dynamo\Dynamo Core\2.X'
// 4) Set from OOTB hard-coded default template

// If a custom python template path doesn't already exists in the DynamoSettings.xml
if (string.IsNullOrEmpty(PreferenceSettings.PythonTemplateFilePath) || !File.Exists(PreferenceSettings.PythonTemplateFilePath))
{
if (string.IsNullOrEmpty(pathManager.PythonTemplateFilePath) || !File.Exists(pathManager.PythonTemplateFilePath))
Logger.Log(Resources.PythonTemplateInvalid);
// To supply a custom python template host integrators should supply a 'DefaultStartConfiguration' config file
// or create a new struct that inherits from 'DefaultStartConfiguration' making sure to set the 'PythonTemplatePath'
// while passing the config to the 'DynamoModel' constructor.
if (config is DefaultStartConfiguration)
{
var configurationSettings = (DefaultStartConfiguration)config;
var templatePath = configurationSettings.PythonTemplatePath;

// If a custom python template path was set in the config apply that template
if (!string.IsNullOrEmpty(templatePath) && File.Exists(templatePath))
{
PreferenceSettings.PythonTemplateFilePath = templatePath;
Logger.Log(Resources.PythonTemplateDefinedByHost + " : " + PreferenceSettings.PythonTemplateFilePath);
}

// Otherwise fallback to the default
else
{
SetDefaultPythonTemplate();
}
}

else
{
PreferenceSettings.PythonTemplateFilePath = pathManager.PythonTemplateFilePath;
Logger.Log(Resources.PythonTemplateDefaultFile + " : " + pathManager.PythonTemplateFilePath);
// Fallback to the default
SetDefaultPythonTemplate();
}
}
else Logger.Log(Resources.PythonTemplateUserFile + " : " + pathManager.PythonTemplateFilePath);

else
{
// A custom python template path already exists in the DynamoSettings.xml
Logger.Log(Resources.PythonTemplateUserFile + " : " + PreferenceSettings.PythonTemplateFilePath);
}

pathManager.Preferences = PreferenceSettings;

Expand Down Expand Up @@ -779,6 +809,23 @@ protected DynamoModel(IStartConfiguration config)
DynamoReady(new ReadyParams(this));
}

private void SetDefaultPythonTemplate()
{
// First check if the default python template is overridden by a PythonTemplate.py file in AppData
// This file is always named accordingly and located in 'C:\Users\USERNAME\AppData\Roaming\Dynamo\Dynamo Core\2.X'
if (!string.IsNullOrEmpty(pathManager.PythonTemplateFilePath) && File.Exists(pathManager.PythonTemplateFilePath))
{
PreferenceSettings.PythonTemplateFilePath = pathManager.PythonTemplateFilePath;
Logger.Log(Resources.PythonTemplateAppData + " : " + PreferenceSettings.PythonTemplateFilePath);
}

// Otherwise the OOTB hard-coded template is applied
else
{
Logger.Log(Resources.PythonTemplateDefaultFile);
}
}

private void DynamoReadyExtensionHandler(ReadyParams readyParams, IEnumerable<IExtension> extensions) {

foreach (var ext in extensions)
Expand Down
19 changes: 14 additions & 5 deletions src/DynamoCore/Properties/Resources.Designer.cs

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

12 changes: 12 additions & 0 deletions src/DynamoCore/Properties/Resources.en-US.resx
Original file line number Diff line number Diff line change
Expand Up @@ -688,4 +688,16 @@ The input name should be a valid variable name, without spaces. An input type an
<data name="InvalidInputSymbolWarningTitle" xml:space="preserve">
<value>Custom Node Contains Invalid Inputs and Cannot Be Saved.</value>
</data>
<data name="PythonTemplateAppData" xml:space="preserve">
<value>Python template loaded from AppData</value>
</data>
<data name="PythonTemplateDefaultFile" xml:space="preserve">
<value>Python template set to default.</value>
</data>
<data name="PythonTemplateDefinedByHost" xml:space="preserve">
<value>Python template set by host integrator</value>
</data>
<data name="PythonTemplateUserFile" xml:space="preserve">
<value>Python template loaded from DynamoSettings.xml path</value>
</data>
</root>
11 changes: 7 additions & 4 deletions src/DynamoCore/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -649,14 +649,14 @@ value : bool = false</value>
<data name="NoneString" xml:space="preserve">
<value>none</value>
</data>
<data name="PythonTemplateInvalid" xml:space="preserve">
<value>Python template : no valid template found.</value>
<data name="PythonTemplateAppData" xml:space="preserve">
<value>Python template loaded from AppData</value>
</data>
<data name="PythonTemplateDefaultFile" xml:space="preserve">
<value>Python template set to default file</value>
<value>Python template set to default.</value>
</data>
<data name="PythonTemplateUserFile" xml:space="preserve">
<value>Python template set to user file</value>
<value>Python template loaded from DynamoSettings.xml path</value>
</data>
<data name="DefaultHomeWorkspaceName" xml:space="preserve">
<value>Home</value>
Expand Down Expand Up @@ -697,4 +697,7 @@ The input name should be a valid variable name, without spaces. An input type an
<data name="InvalidInputSymbolWarningTitle" xml:space="preserve">
<value>Custom Node Contains Invalid Inputs and Cannot Be Saved.</value>
</data>
<data name="PythonTemplateDefinedByHost" xml:space="preserve">
<value>Python template set by host integrator</value>
</data>
</root>
35 changes: 32 additions & 3 deletions test/DynamoCoreTests/Settings.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Dynamo.Configuration;
using Dynamo.Models;
using NUnit.Framework;

namespace Dynamo.Tests
Expand Down Expand Up @@ -55,6 +54,36 @@ public void LoadInvalidPythonTemplateFromSetting()
Assert.AreEqual(settings.PythonTemplateFilePath, pyFile);
}

[Test]
public void SetPythonTemplateFromConfigWithValidPath()
{
var templatePath = Path.Combine(SettingDirectory, "PythonTemplate-initial.py");

var config = new DynamoModel.DefaultStartConfiguration()
{
PythonTemplatePath = templatePath
};

var model = DynamoModel.Start(config);

Assert.AreEqual(model.PreferenceSettings.PythonTemplateFilePath, templatePath);
}

[Test]
public void SetPythonTemplateFromConfigWithInvalidPath()
{
var templatePath = Path.Combine(@"C:\Users\SomeDynamoUser\Desktop", "PythonTemplate-initial.py");

var config = new DynamoModel.DefaultStartConfiguration()
{
PythonTemplatePath = templatePath
};

var model = DynamoModel.Start(config);

Assert.AreEqual(model.PreferenceSettings.PythonTemplateFilePath, string.Empty);
}

}

}

0 comments on commit 71aa22e

Please sign in to comment.