diff --git a/Converters/ArcGIS/Speckle.Converters.ArcGIS3/ArcGISConversionSettingsFactory.cs b/Converters/ArcGIS/Speckle.Converters.ArcGIS3/ArcGISConversionSettingsFactory.cs index a26000363..5ae9ae250 100644 --- a/Converters/ArcGIS/Speckle.Converters.ArcGIS3/ArcGISConversionSettingsFactory.cs +++ b/Converters/ArcGIS/Speckle.Converters.ArcGIS3/ArcGISConversionSettingsFactory.cs @@ -6,6 +6,7 @@ using Speckle.Converters.ArcGIS3.Utils; using Speckle.Converters.Common; using Speckle.InterfaceGenerator; +using Speckle.Sdk.Logging; namespace Speckle.Converters.ArcGIS3; @@ -39,7 +40,10 @@ public Uri GetDatabasePath() throw new ArgumentException($"Project directory {Project.Current.URI} not found"); } var fGdbPath = new Uri(parentDirectory.FullName); - return new Uri($"{fGdbPath}/{FGDB_NAME}"); + Uri firstDatabasePath = new Uri($"{fGdbPath}/{FGDB_NAME}"); + + Uri databasePath = ValidateDatabasePath(firstDatabasePath); + return databasePath; } catch (Exception ex) when (ex @@ -54,8 +58,63 @@ or System.Security.SecurityException } } - public Uri AddDatabaseToProject(Uri databasePath) + public Uri ValidateDatabasePath(Uri originalGatabasePath) { + var fGdbName = originalGatabasePath.Segments[^1]; + var parentFolder = Path.GetDirectoryName(originalGatabasePath.AbsolutePath); + if (parentFolder == null) + { + // POC: customize the exception type + throw new ArgumentException($"Invalid path: {originalGatabasePath}"); + } + + Uri databasePath = originalGatabasePath; + Item folderToAdd = ItemFactory.Instance.Create(parentFolder); + if (folderToAdd is null) + { + // ArcGIS API doesn't show it as nullable, but it is + // Likely the project location is inaccessible with not enough permissions + // Store inside Speckle folder + + string speckleFolder = SpecklePathProvider.UserSpeckleFolderPath; //Path.GetTempPath(); + // create folder in Speckle repo + string speckleArcgisFolder = Path.Join(speckleFolder, $"ArcGIS_gdb"); + bool existsArcgisFolder = Directory.Exists(speckleArcgisFolder); + if (!existsArcgisFolder) + { + Directory.CreateDirectory(speckleArcgisFolder); + } + + // create a project-specific folder + string projectFolderName; + string? folderContainingProject = Path.GetDirectoryName(parentFolder); + if (folderContainingProject == null) + { + projectFolderName = "default"; + } + else + { + projectFolderName = Path.GetRelativePath(folderContainingProject, parentFolder); + } + + string tempParentFolder = Path.Join(speckleArcgisFolder, $"{projectFolderName}"); + bool exists = Directory.Exists(tempParentFolder); + if (!exists) + { + Directory.CreateDirectory(tempParentFolder); + } + + // repeat: try adding a folder item again + folderToAdd = ItemFactory.Instance.Create(tempParentFolder); + if (folderToAdd is null) + { + throw new ArgumentException( + $"Project path: '{parentFolder}' and Temp folder: '{tempParentFolder}' likely don't have write permissions." + ); + } + databasePath = new Uri(Path.Join(tempParentFolder, fGdbName), UriKind.Absolute); + } + // Create a FileGeodatabaseConnectionPath with the name of the file geodatabase you wish to create FileGeodatabaseConnectionPath fileGeodatabaseConnectionPath = new(databasePath); // Create actual database in the specified Path unless already exists @@ -69,13 +128,13 @@ public Uri AddDatabaseToProject(Uri databasePath) // geodatabase already exists, do nothing } + return databasePath; + } + + public Uri AddDatabaseToProject(Uri databasePath) + { // Add a folder connection to a project var parentFolder = Path.GetDirectoryName(databasePath.AbsolutePath); - if (parentFolder == null) - { - // POC: customize the exception type - throw new ArgumentException($"Invalid path: {databasePath}"); - } var fGdbName = databasePath.Segments[^1]; Item folderToAdd = ItemFactory.Instance.Create(parentFolder); // POC: QueuedTask