Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/distrib/xml/en-US/DSCoreNodes.xml

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

1 change: 1 addition & 0 deletions src/DynamoCore/Configuration/ExecutionSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public ExecutionSession(Scheduler.UpdateGraphAsyncTask updateTask, DynamoModel m
parameters[ParameterKeys.LastExecutionDuration] = new TimeSpan(updateTask.ExecutionEndTime.TickCount - updateTask.ExecutionStartTime.TickCount);
parameters[ParameterKeys.PackagePaths] = pathManager.PackagesDirectories;
parameters[ParameterKeys.Logger] = model.Logger;
parameters[ParameterKeys.NoNetworkMode] = model.NoNetworkMode;
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion src/DynamoCore/Models/DynamoModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ public static string Version
internal bool IsServiceMode { get; set; }

/// <summary>
/// True if Dynamo starts up in offline mode.
/// True if Dynamo is used in offline mode.
/// </summary>
internal bool NoNetworkMode { get; }

Expand Down
4 changes: 2 additions & 2 deletions src/DynamoCoreWpf/ViewModels/Core/DynamoViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2810,12 +2810,12 @@ internal void ShowPackageManager(object parameters)

internal bool CanShowPackageManagerSearch(object parameters)
{
return !model.IsServiceMode;
return !model.IsServiceMode && !model.NoNetworkMode;
}

internal bool CanShowPackageManager(object parameters)
{
return !model.IsServiceMode;
return !model.IsServiceMode && !model.NoNetworkMode;
}

/// <summary>
Expand Down
20 changes: 20 additions & 0 deletions src/DynamoCoreWpf/ViewModels/Menu/PreferencesViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1346,6 +1346,24 @@ private void AddPythonEnginesOptions()
/// </summary>
public TrustedPathViewModel TrustedPathsViewModel { get; set; }

private bool noNetworkMode;

/// <summary>
/// True if Dynamo is used in offline mode.
/// </summary>
public bool NoNetworkMode
{
get => noNetworkMode;
private set
{
if (noNetworkMode != value)
{
noNetworkMode = value;
RaisePropertyChanged(nameof(NoNetworkMode));
}
}
}

/// <summary>
/// Returns a boolean value indicating if the Settings importing was successful or not
/// </summary>
Expand Down Expand Up @@ -1469,6 +1487,8 @@ public PreferencesViewModel(DynamoViewModel dynamoViewModel)
this.pythonScriptEditorTextOptions = dynamoViewModel.PythonScriptEditorTextOptions;
this.dynamoViewModel = dynamoViewModel;

NoNetworkMode = dynamoViewModel.Model.NoNetworkMode;

if (dynamoViewModel.PackageManagerClientViewModel != null)
{
installedPackagesViewModel = new InstalledPackagesViewModel(dynamoViewModel, dynamoViewModel.PackageManagerClientViewModel.PackageManagerExtension.PackageLoader);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ public void PublishCurrentWorkspace(object m)

public bool CanPublishCurrentWorkspace(object m)
{
return DynamoViewModel.Model.CurrentWorkspace is CustomNodeWorkspaceModel && AuthenticationManager.HasAuthProvider;
return DynamoViewModel.Model.CurrentWorkspace is CustomNodeWorkspaceModel && AuthenticationManager.HasAuthProvider && !Model.NoNetworkMode;
}

public void PublishNewPackage(object m)
Expand All @@ -363,7 +363,7 @@ public void PublishNewPackage(object m)

public bool CanPublishNewPackage(object m)
{
return AuthenticationManager.HasAuthProvider;
return AuthenticationManager.HasAuthProvider && !Model.NoNetworkMode;
}

public void PublishCustomNode(Function m)
Expand Down Expand Up @@ -393,7 +393,7 @@ public void PublishCustomNode(Function m)

public bool CanPublishCustomNode(Function m)
{
return AuthenticationManager.HasAuthProvider && m != null;
return AuthenticationManager.HasAuthProvider && m != null && !Model.NoNetworkMode;
}

public void PublishSelectedNodes(object m)
Expand Down Expand Up @@ -453,7 +453,7 @@ public void PublishSelectedNodes(object m)
public bool CanPublishSelectedNodes(object m)
{
return DynamoSelection.Instance.Selection.Count > 0 &&
DynamoSelection.Instance.Selection.All(x => x is Function) && AuthenticationManager.HasAuthProvider; ;
DynamoSelection.Instance.Selection.All(x => x is Function) && AuthenticationManager.HasAuthProvider && !Model.NoNetworkMode;
}

private void ShowNodePublishInfo()
Expand Down
15 changes: 14 additions & 1 deletion src/DynamoCoreWpf/Views/Menu/PreferencesView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
xmlns:fa="clr-namespace:FontAwesome5;assembly=FontAwesome5.Net"
xmlns:packagemanager="clr-namespace:Dynamo.Wpf.Views.PackageManager"
xmlns:trustedpaths="clr-namespace:Dynamo.Wpf.Views"
xmlns:converters="clr-namespace:Dynamo.Controls;assembly=DynamoCoreWpf"
xmlns:wpfControls="clr-namespace:Dynamo.Wpf.Controls"
d:DataContext="{d:DesignInstance Type=viewModels:PreferencesViewModel}"
WindowStartupLocation="CenterOwner"
Expand Down Expand Up @@ -1949,7 +1950,19 @@
<Hyperlink Click="OnInstalledPackagesHyperlinkClicked"
Foreground="{StaticResource TextBlockLinkForegroundColor}">
<TextBlock Name="PackageManagerLink"
Text="{x:Static p:Resources.InstalledPackagePartialHyperlinkMessage}" />
Text="{x:Static p:Resources.InstalledPackagePartialHyperlinkMessage}"
IsHitTestVisible="{Binding NoNetworkMode, Converter={StaticResource InverseBooleanConverter}}">
<TextBlock.Style>
<Style TargetType="TextBlock">
<!--<Setter Property="Foreground" Value="Black" />-->
<Style.Triggers>
<DataTrigger Binding="{Binding NoNetworkMode}" Value="True">
<Setter Property="Foreground" Value="Gray" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Hyperlink>
<Run>.</Run>
</TextBlock>
Expand Down
42 changes: 38 additions & 4 deletions src/DynamoPackages/PackageManagerClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,24 @@ public string BaseUrl
get { return this.client.BaseUrl; }
}

internal readonly bool NoNetworkMode;

#endregion

internal PackageManagerClient(IGregClient client, IPackageUploadBuilder builder, string packageUploadDirectory)
internal PackageManagerClient(IGregClient client, IPackageUploadBuilder builder, string packageUploadDirectory,
bool noNetworkMode = false)
{
this.packageUploadDirectory = packageUploadDirectory;
this.uploadBuilder = builder;
this.client = client;
this.packageMaintainers = new Dictionary<string, bool>();
this.NoNetworkMode = noNetworkMode;
}

internal bool Upvote(string packageId)
{
if (NoNetworkMode) return false;

return FailFunc.TryExecute(() =>
{
var pkgResponse = this.client.ExecuteAndDeserialize(new Upvote(packageId));
Expand All @@ -70,6 +76,8 @@ internal bool Upvote(string packageId)

internal List<string> UserVotes()
{
if (NoNetworkMode) return null;
Copy link

Copilot AI May 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning null for a list can lead to NullReferenceExceptions. Prefer returning an empty list (new List<string>()) to maintain API consistency.

Suggested change
if (NoNetworkMode) return null;
if (NoNetworkMode) return new List<string>();

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This?


var votes = FailFunc.TryExecute(() =>
{
var nv = new GetUserVotes();
Expand All @@ -82,6 +90,8 @@ internal List<string> UserVotes()

internal List<JObject> CompatibilityMap()
{
if (NoNetworkMode) return null;

var compatibilityMap = FailFunc.TryExecute(() =>
{
var cm = new GetCompatibilityMap();
Expand All @@ -99,6 +109,8 @@ internal PackageManagerResult DownloadPackage(string packageId, string version,
{
try
{
if (NoNetworkMode) throw new Exception(DynamoPackages.Properties.Resources.DownloadPackageDisabled);
Comment thread
aparajit-pratap marked this conversation as resolved.
Copy link

Copilot AI May 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] This method throws an exception on offline mode, but other methods return null or defaults. Consider unifying the error-handling strategy across package manager methods.

Suggested change
if (NoNetworkMode) throw new Exception(DynamoPackages.Properties.Resources.DownloadPackageDisabled);
if (NoNetworkMode)
{
pathToPackage = null;
return PackageManagerResult.Failed(DynamoPackages.Properties.Resources.DownloadPackageDisabled);
}

Copilot uses AI. Check for mistakes.

var response = this.client.Execute(new PackageDownload(packageId, version));
pathToPackage = PackageDownload.GetFileFromResponse(response);
return PackageManagerResult.Succeeded();
Expand All @@ -112,6 +124,8 @@ internal PackageManagerResult DownloadPackage(string packageId, string version,

internal IEnumerable<PackageHeader> ListAll()
{
if (NoNetworkMode) return new List<PackageHeader>();

return FailFunc.TryExecute(() => {
var nv = HeaderCollectionDownload.ByEngine("dynamo");
var pkgResponse = this.client.ExecuteAndDeserializeWithContent<List<PackageHeader>>(nv);
Expand Down Expand Up @@ -146,6 +160,8 @@ void CleanPackagesWithWrongVersions(List<PackageHeader> packages)
/// <returns></returns>
internal PackageHeader GetPackageMaintainers(IPackageInfo packageInfo)
{
if (NoNetworkMode) return null;

var header = FailFunc.TryExecute(() =>
{
var nv = new GetMaintainers("dynamo", packageInfo.Name);
Expand All @@ -162,6 +178,8 @@ internal PackageHeader GetPackageMaintainers(IPackageInfo packageInfo)
/// <returns></returns>
internal UserPackages GetUsersLatestPackages()
{
if (NoNetworkMode) return null;

var packages = FailFunc.TryExecute(() =>
{
var nv = new GetMyPackages();
Expand All @@ -179,6 +197,8 @@ internal UserPackages GetUsersLatestPackages()
/// <returns>Package version metadata</returns>
internal PackageVersion GetPackageVersionHeader(IPackageInfo packageInfo)
{
if (NoNetworkMode) return null;

var req = new HeaderVersionDownload("dynamo", packageInfo.Name, packageInfo.Version.ToString());
var pkgResponse = this.client.ExecuteAndDeserializeWithContent<PackageVersion>(req);
if (!pkgResponse.success)
Expand All @@ -196,6 +216,8 @@ internal PackageVersion GetPackageVersionHeader(IPackageInfo packageInfo)
/// <returns>Package version metadata</returns>
internal virtual PackageVersion GetPackageVersionHeader(string id, string version)
{
if (NoNetworkMode) return null;

var req = new HeaderVersionDownload(id, version);
var pkgResponse = this.client.ExecuteAndDeserializeWithContent<PackageVersion>(req);
if (!pkgResponse.success)
Expand All @@ -211,6 +233,8 @@ internal virtual PackageVersion GetPackageVersionHeader(string id, string versio
/// </summary>
internal virtual IEnumerable<string> GetKnownHosts()
{
if (NoNetworkMode) return null;

if (cachedHosts == null)
{
cachedHosts = FailFunc.TryExecute(() =>
Expand All @@ -235,6 +259,8 @@ public bool SetTermsOfUseAcceptanceStatus()

private bool ExecuteTermsOfUseCall(bool queryAcceptanceStatus)
{
if (NoNetworkMode) return false;

return FailFunc.TryExecute(() =>
{
var request = new TermsOfUse(queryAcceptanceStatus);
Expand All @@ -258,6 +284,8 @@ private bool ExecuteTermsOfUseCall(bool queryAcceptanceStatus)
/// <returns>A <see cref="PackageUploadHandle"/> Used to track the upload status.</returns>
internal PackageUploadHandle PublishAsync(Package package, object files, IEnumerable<string> markdownFiles, bool isNewVersion, IEnumerable<string> roots, bool retainFolderStructure)
{
if (NoNetworkMode) return null;

var packageUploadHandle = new PackageUploadHandle(PackageUploadBuilder.NewRequestBody(package));

Task.Factory.StartNew(() =>
Expand Down Expand Up @@ -321,6 +349,8 @@ internal void Publish(Package package, object files, IEnumerable<string> markdow

internal PackageManagerResult Deprecate(string name)
{
if (NoNetworkMode) return null;

return FailFunc.TryExecute(() =>
{
var pkgResponse = this.client.ExecuteAndDeserialize(new Deprecate(name, PackageEngineName));
Expand All @@ -330,6 +360,8 @@ internal PackageManagerResult Deprecate(string name)

internal PackageManagerResult Undeprecate(string name)
{
if (NoNetworkMode) return null;

return FailFunc.TryExecute(() =>
{
var pkgResponse = this.client.ExecuteAndDeserialize(new Undeprecate(name, PackageEngineName));
Expand All @@ -339,14 +371,16 @@ internal PackageManagerResult Undeprecate(string name)

internal bool DoesCurrentUserOwnPackage(Package package,string username)
{
if (NoNetworkMode) return false;

bool value;
if (this.packageMaintainers.Count > 0 && this.packageMaintainers.TryGetValue(package.Name, out value)) {
if (packageMaintainers.Count > 0 && packageMaintainers.TryGetValue(package.Name, out value)) {
return value;
}
var pkg = new PackageInfo(package.Name, new Version(package.VersionName));
var mnt = GetPackageMaintainers(pkg);
value = (mnt != null) && (mnt.maintainers.Any(maintainer => maintainer.username.Equals(username)));
this.packageMaintainers[package.Name] = value;
packageMaintainers[package.Name] = value;
return value;
}

Expand Down Expand Up @@ -386,7 +420,7 @@ internal void LoadCompatibilityMap()
{
compatibilityMap = new Dictionary<string, Dictionary<string, string>>();

var compatibilityMapList = this.CompatibilityMap();
var compatibilityMapList = CompatibilityMap();
PackageManagerClient.compatibilityMapList = compatibilityMapList; // Loads the full CompatibilityMap as a side-effect

foreach (var host in compatibilityMapList)
Expand Down
5 changes: 3 additions & 2 deletions src/DynamoPackages/PackageManagerExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,12 @@ public void Startup(StartupParams startupParams)

var packageUploadDirectory = startupParams.PathManager.DefaultPackagesDirectory;

noNetworkMode = startupParams.NoNetworkMode;

PackageManagerClient = new PackageManagerClient(
new GregClient(startupParams.AuthProvider, url),
uploadBuilder, packageUploadDirectory);
uploadBuilder, packageUploadDirectory, noNetworkMode);

noNetworkMode = startupParams.NoNetworkMode;

//we don't ask dpm for the compatibility map in offline mode.
if (!noNetworkMode)
Expand Down
9 changes: 9 additions & 0 deletions src/DynamoPackages/Properties/Resources.Designer.cs

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

5 changes: 4 additions & 1 deletion src/DynamoPackages/Properties/Resources.en-US.resx
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@
<data name="CannotRemovePackageAssemblyTitle" xml:space="preserve">
<value>Cannot update assembly</value>
</data>
<data name="DownloadPackageDisabled" xml:space="preserve">
<value>Package download is disabled in no-network mode.</value>
</data>
<data name="InvalidPackageFolderWarning" xml:space="preserve">
<value>The folder '{0}' does not exist</value>
<comment>This warning message is shown (during start up) when user specifies additional folders in DynamoSettings.xml file but the folders do not exist.</comment>
Expand All @@ -140,4 +143,4 @@
<value>{0} was not scanned for packages because a preference setting disabled loading from that location."</value>
<comment>This warning message is shown when a package directory is skipped due to a preference setting disabling loads from that location type.</comment>
</data>
</root>
</root>
5 changes: 4 additions & 1 deletion src/DynamoPackages/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@
<data name="CannotRemovePackageAssemblyTitle" xml:space="preserve">
<value>Cannot update assembly</value>
</data>
<data name="DownloadPackageDisabled" xml:space="preserve">
<value>Package download is disabled in no-network mode.</value>
</data>
<data name="InvalidPackageFolderWarning" xml:space="preserve">
<value>The folder '{0}' does not exist</value>
<comment>This warning message is shown (during start up) when user specifies additional folders in DynamoSettings.xml file but the folders do not exist.</comment>
Expand All @@ -140,4 +143,4 @@
<value>{0} was not scanned for packages because a preference setting disabled loading from that location."</value>
<comment>This warning message is shown when a package directory is skipped due to a preference setting disabling loads from that location type.</comment>
</data>
</root>
</root>
6 changes: 4 additions & 2 deletions src/Libraries/CoreNodeModels/WebRequest.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
using System;
using System;
using System.Collections.Generic;
using CoreNodeModels.Properties;
using DSCore;
using Dynamo.Events;
using Dynamo.Graph.Nodes;
using Dynamo.Session;
using Newtonsoft.Json;
using ProtoCore.AST.AssociativeAST;

namespace CoreNodeModels
{
[NodeName("Web Request")]
[NodeDescription("WebRequestDescription", typeof(Resources))]
[NodeDescription(nameof(Resources.WebRequestDescription), typeof(Resources))]
[NodeCategory(BuiltinNodeCategories.CORE_WEB)]
[IsDesignScriptCompatible]
[OutPortTypes("var[]..[]")]
Expand Down
Loading
Loading