public override async Task <StreamState> ReceiveStream(StreamState state, ProgressViewModel progress) { var pd = new ConcurrentDictionary <string, int>(); pd["A1"] = 1; pd["A2"] = 1; progress.Max = 100; progress.Update(pd); for (int i = 1; i < 100; i += 10) { if (progress.CancellationTokenSource.IsCancellationRequested) { return(state); } await Task.Delay(TimeSpan.FromMilliseconds(rnd.Next(200, 1000))); pd["A1"] = i; pd["A2"] = i + 2; try { if (i % 7 == 0) { throw new Exception($"Something happened."); } } catch (Exception e) { //TODO //state.Errors.Add(e); } progress.Update(pd); } // Mock some errors for (int i = 0; i < 10; i++) { try { throw new Exception($"Number {i} fail"); } catch (Exception e) { //TODO //state.Errors.Add(e); } } return(state); }
private List <ApplicationPlaceholderObject> ConvertAndBakeReceivedObjects(List <Base> objects, ISpeckleConverter converter, StreamState state, ProgressViewModel progress) { var placeholders = new List <ApplicationPlaceholderObject>(); var conversionProgressDict = new ConcurrentDictionary <string, int>(); conversionProgressDict["Conversion"] = 0; Execute.PostToUIThread(() => progress.Max = state.SelectedObjectIds.Count()); Action updateProgressAction = () => { conversionProgressDict["Conversion"]++; progress.Update(conversionProgressDict); }; foreach (var @base in objects) { if (progress.CancellationTokenSource.Token.IsCancellationRequested) { placeholders = null; break; } try { var convRes = converter.ConvertToNative(@base); if (convRes is ApplicationPlaceholderObject placeholder) { placeholders.Add(placeholder); } else if (convRes is List <ApplicationPlaceholderObject> placeholderList) { placeholders.AddRange(placeholderList); } // creating new elements, not updating existing! var convertedElement = convRes as Element; if (convertedElement != null) { var status = convertedElement.AddToModel(); if (status == StatusInt.Error) { converter.Report.LogConversionError(new Exception($"Failed to bake object {@base.id} of type {@base.speckle_type}.")); } } else { converter.Report.LogConversionError(new Exception($"Failed to convert object {@base.id} of type {@base.speckle_type}.")); } } catch (Exception e) { converter.Report.LogConversionError(e); } } return(placeholders); }
public override async Task SendStream(StreamState state, ProgressViewModel progress) { // Let's fake some progress barsssss progress.Report.Log("Starting fake sending"); var pd = new ConcurrentDictionary <string, int>(); pd["A1"] = 1; pd["A2"] = 1; progress.Max = 100; progress.Update(pd); for (int i = 1; i < 100; i += 10) { if (progress.CancellationTokenSource.Token.IsCancellationRequested) { progress.Report.Log("Fake sending was cancelled"); return; } progress.Report.Log("Done fake task " + i); await Task.Delay(TimeSpan.FromMilliseconds(rnd.Next(200, 1000))); pd["A1"] = i; pd["A2"] = i + 2; progress.Update(pd); } // Mock "some" errors for (int i = 0; i < 10; i++) { try { throw new Exception($"Number {i} failed"); } catch (Exception e) { progress.Report.LogOperationError(e); //TODO //state.Errors.Add(e); } } }
private List <ApplicationPlaceholderObject> ConvertReceivedObjects(List <Base> objects, ISpeckleConverter converter, StreamState state, ProgressViewModel progress) { var placeholders = new List <ApplicationPlaceholderObject>(); var conversionProgressDict = new ConcurrentDictionary <string, int>(); conversionProgressDict["Conversion"] = 1; foreach (var @base in objects) { if (progress.CancellationTokenSource.Token.IsCancellationRequested) { placeholders = null; break; } try { conversionProgressDict["Conversion"]++; // wrapped in a dispatcher not to block the ui progress.Update(conversionProgressDict); var convRes = converter.ConvertToNative(@base); if (convRes is ApplicationPlaceholderObject placeholder) { placeholders.Add(placeholder); } else if (convRes is List <ApplicationPlaceholderObject> placeholderList) { placeholders.AddRange(placeholderList); } } catch (Exception e) { progress.Report.LogConversionError(e); } } return(placeholders); }
public override async Task SendStream(StreamState state, ProgressViewModel progress) { //throw new NotImplementedException(); var kit = KitManager.GetDefaultKit(); //var converter = new ConverterETABS(); var converter = kit.LoadConverter(ConnectorETABSUtils.ETABSAppName); converter.SetContextDocument(Model); Exceptions.Clear(); var commitObj = new Base(); int objCount = 0; if (state.Filter != null) { state.SelectedObjectIds = GetSelectionFilterObjects(state.Filter); } var totalObjectCount = state.SelectedObjectIds.Count(); if (totalObjectCount == 0) { progress.Report.LogOperationError(new SpeckleException("Zero objects selected; send stopped. Please select some objects, or check that your filter can actually select something.", false)); return; } var conversionProgressDict = new ConcurrentDictionary <string, int>(); conversionProgressDict["Conversion"] = 0; progress.Update(conversionProgressDict); //if( commitObj["@Stories"] == null) //{ // commitObj["@Stories"] = converter.ConvertToSpeckle(("Stories", "ETABS")); //} foreach (var applicationId in state.SelectedObjectIds) { if (progress.CancellationTokenSource.Token.IsCancellationRequested) { return; } Base converted = null; string containerName = string.Empty; var selectedObjectType = ConnectorETABSUtils.ObjectIDsTypesAndNames .Where(pair => pair.Key == applicationId) .Select(pair => pair.Value.Item1).FirstOrDefault(); if (!converter.CanConvertToSpeckle(selectedObjectType)) { progress.Report.Log($"Skipped not supported type: ${selectedObjectType} are not supported"); continue; } Tracker.TrackPageview(Tracker.CONVERT_TOSPECKLE); var typeAndName = ConnectorETABSUtils.ObjectIDsTypesAndNames .Where(pair => pair.Key == applicationId) .Select(pair => pair.Value).FirstOrDefault(); converted = converter.ConvertToSpeckle(typeAndName); if (converted == null) { var exception = new Exception($"Failed to convert object ${applicationId} of type ${selectedObjectType}."); progress.Report.LogConversionError(exception); continue; } //if (converted != null) //{ // if (commitObj[selectedObjectType] == null) // { // commitObj[selectedObjectType] = new List<Base>(); // } // ((List<Base>)commitObj[selectedObjectType]).Add(converted); //} //objCount++; conversionProgressDict["Conversion"]++; progress.Update(conversionProgressDict); } Base ElementCount = converter.ConvertToSpeckle(("ElementsCount", "ETABS")); if (ElementCount.applicationId != null) { objCount = Convert.ToInt32(ElementCount.applicationId); } else { objCount = 0; } if (commitObj["@Model"] == null) { commitObj["@Model"] = converter.ConvertToSpeckle(("Model", "ETABS")); } if (commitObj["AnalysisResults"] == null) { commitObj["AnalysisResults"] = converter.ConvertToSpeckle(("AnalysisResults", "ETABS")); } progress.Report.Merge(converter.Report); if (objCount == 0) { progress.Report.LogOperationError(new SpeckleException("Zero objects converted successfully. Send stopped.", false)); return; } if (progress.CancellationTokenSource.Token.IsCancellationRequested) { return; } var streamId = state.StreamId; var client = state.Client; var transports = new List <SCT.ITransport>() { new SCT.ServerTransport(client.Account, streamId) }; var objectId = await Operations.Send( @object : commitObj, cancellationToken : progress.CancellationTokenSource.Token, transports : transports, onProgressAction : dict => progress.Update(dict), onErrorAction : (Action <string, Exception>)((s, e) => { progress.Report.LogOperationError(e); progress.CancellationTokenSource.Cancel(); }), disposeTransports : true ); if (progress.Report.OperationErrorsCount != 0) { //RaiseNotification($"Failed to send: \n {Exceptions.Last().Message}"); return; } var actualCommit = new CommitCreateInput { streamId = streamId, objectId = objectId, branchName = state.BranchName, message = state.CommitMessage != null ? state.CommitMessage : $"Pushed {objCount} elements from ETABS.", sourceApplication = ConnectorETABSUtils.ETABSAppName }; if (state.PreviousCommitId != null) { actualCommit.parents = new List <string>() { state.PreviousCommitId }; } try { var commitId = await client.CommitCreate(actualCommit); //await state.RefreshStream(); state.PreviousCommitId = commitId; //PersistAndUpdateStreamInFile(state); //RaiseNotification($"{objCount} objects sent to {state.Stream.name}. 🚀"); } catch (Exception e) { //Globals.Notify($"Failed to create commit.\n{e.Message}"); progress.Report.LogOperationError(e); } //return state; }
/// <summary> /// Converts the Revit elements that have been added to the stream by the user, sends them to /// the Server and the local DB, and creates a commit with the objects. /// </summary> /// <param name="state">StreamState passed by the UI</param> public override async Task SendStream(StreamState state, ProgressViewModel progress) { var kit = KitManager.GetDefaultKit(); var converter = kit.LoadConverter(ConnectorRevitUtils.RevitAppName); converter.SetContextDocument(CurrentDoc.Document); var streamId = state.StreamId; var client = state.Client; var selectedObjects = GetSelectionFilterObjects(state.Filter); state.SelectedObjectIds = selectedObjects.Select(x => x.UniqueId).ToList(); if (!selectedObjects.Any()) { progress.Report.LogOperationError(new Exception("There are zero objects to send. Please use a filter, or set some via selection.")); return; } converter.SetContextObjects(selectedObjects.Select(x => new ApplicationPlaceholderObject { applicationId = x.UniqueId }).ToList()); var commitObject = new Base(); var conversionProgressDict = new ConcurrentDictionary <string, int>(); conversionProgressDict["Conversion"] = 0; progress.Max = selectedObjects.Count(); var convertedCount = 0; var placeholders = new List <Base>(); foreach (var revitElement in selectedObjects) { try { if (revitElement == null) { continue; } if (!converter.CanConvertToSpeckle(revitElement)) { progress.Report.Log($"Skipped not supported type: {revitElement.GetType()}, name {revitElement.Name}"); continue; } if (progress.CancellationTokenSource.Token.IsCancellationRequested) { return; } var conversionResult = converter.ConvertToSpeckle(revitElement); conversionProgressDict["Conversion"]++; progress.Update(conversionProgressDict); placeholders.Add(new ApplicationPlaceholderObject { applicationId = revitElement.UniqueId, ApplicationGeneratedId = revitElement.UniqueId }); convertedCount++; //hosted elements will be returned as `null` by the ConvertToSpeckle method //since they are handled when converting their parents if (conversionResult != null) { var category = $"@{revitElement.Category.Name}"; if (commitObject[category] == null) { commitObject[category] = new List <Base>(); } ((List <Base>)commitObject[category]).Add(conversionResult); } } catch (Exception e) { progress.Report.LogConversionError(e); } } progress.Report.Merge(converter.Report); if (convertedCount == 0) { progress.Report.LogConversionError(new Exception("Zero objects converted successfully. Send stopped.")); return; } if (progress.CancellationTokenSource.Token.IsCancellationRequested) { return; } var transports = new List <ITransport>() { new ServerTransport(client.Account, streamId) }; var objectId = await Operations.Send( @object : commitObject, cancellationToken : progress.CancellationTokenSource.Token, transports : transports, onProgressAction : dict => progress.Update(dict), onErrorAction : (s, e) => { progress.Report.LogOperationError(e); progress.CancellationTokenSource.Cancel(); }, disposeTransports : true ); if (progress.Report.OperationErrorsCount != 0) { return; } if (progress.CancellationTokenSource.Token.IsCancellationRequested) { return; } var actualCommit = new CommitCreateInput() { streamId = streamId, objectId = objectId, branchName = state.BranchName, message = state.CommitMessage != null ? state.CommitMessage : $"Sent {convertedCount} objects from {ConnectorRevitUtils.RevitAppName}.", sourceApplication = ConnectorRevitUtils.RevitAppName, }; if (state.PreviousCommitId != null) { actualCommit.parents = new List <string>() { state.PreviousCommitId }; } try { var commitId = await client.CommitCreate(actualCommit); //await state.RefreshStream(); state.PreviousCommitId = commitId; } catch (Exception e) { progress.Report.LogOperationError(e); } //return state; }
public override async Task SendStream(StreamState state, ProgressViewModel progress) { var kit = KitManager.GetDefaultKit(); var converter = kit.LoadConverter(Utils.BentleyAppName); var streamId = state.StreamId; var client = state.Client; if (Control.InvokeRequired) { Control.Invoke(new SetContextDelegate(converter.SetContextDocument), new object[] { Session.Instance }); } else { converter.SetContextDocument(Session.Instance); } var selectedObjects = new List <Object>(); if (state.Filter != null) { if (Control.InvokeRequired) { state.SelectedObjectIds = (List <string>)Control.Invoke(new GetObjectsFromFilterDelegate(GetObjectsFromFilter), new object[] { state.Filter, converter, progress }); } else { state.SelectedObjectIds = GetObjectsFromFilter(state.Filter, converter, progress); } } if (state.SelectedObjectIds.Count == 0 && !ExportGridLines) { progress.Report.LogOperationError(new Exception("Zero objects selected; send stopped. Please select some objects, or check that your filter can actually select something.")); return; } var commitObj = new Base(); var units = Units.GetUnitsFromString(ModelUnits).ToLower(); commitObj["units"] = units; var conversionProgressDict = new ConcurrentDictionary <string, int>(); conversionProgressDict["Conversion"] = 0; Execute.PostToUIThread(() => progress.Max = state.SelectedObjectIds.Count()); int convertedCount = 0; // grab elements from active model var objs = new List <Element>(); #if (OPENROADS || OPENRAIL) bool convertCivilObject = false; var civObjs = new List <NamedModelEntity>(); if (civilElementKeys.Count(x => state.SelectedObjectIds.Contains(x)) > 0) { if (Control.InvokeRequired) { civObjs = (List <NamedModelEntity>)Control.Invoke(new GetCivilObjectsDelegate(GetCivilObjects), new object[] { state }); } else { civObjs = GetCivilObjects(state); } objs = civObjs.Select(x => x.Element).ToList(); convertCivilObject = true; } else { objs = state.SelectedObjectIds.Select(x => Model.FindElementById((ElementId)Convert.ToUInt64(x))).ToList(); } #else objs = state.SelectedObjectIds.Select(x => Model.FindElementById((ElementId)Convert.ToUInt64(x))).ToList(); #endif #if (OPENBUILDINGS) if (ExportGridLines) { var converted = ConvertGridLines(converter, progress); if (converted == null) { progress.Report.LogConversionError(new Exception($"Failed to convert Gridlines.")); } else { var containerName = "Grid Systems"; if (commitObj[$"@{containerName}"] == null) { commitObj[$"@{containerName}"] = new List <Base>(); } ((List <Base>)commitObj[$"@{containerName}"]).Add(converted); // not sure this makes much sense here conversionProgressDict["Conversion"]++; progress.Update(conversionProgressDict); convertedCount++; } } #endif foreach (var obj in objs) { if (progress.CancellationTokenSource.Token.IsCancellationRequested) { return; } if (obj == null) { progress.Report.Log($"Skipped not found object."); continue; } var objId = obj.ElementId.ToString(); var objType = obj.ElementType; if (!converter.CanConvertToSpeckle(obj)) { progress.Report.Log($"Skipped not supported type: ${objType}. Object ${objId} not sent."); continue; } // convert obj Base converted = null; string containerName = string.Empty; try { var levelCache = Model.GetFileLevelCache(); var objLevel = levelCache.GetLevel(obj.LevelId); var layerName = "Unknown"; if (objLevel != null) { layerName = objLevel.Name; } #if (OPENROADS || OPENRAIL) if (convertCivilObject) { var civilObj = civObjs[objs.IndexOf(obj)]; if (Control.InvokeRequired) { converted = (Base)Control.Invoke(new SpeckleConversionDelegate(converter.ConvertToSpeckle), new object[] { civilObj }); Control.Invoke((Action)(() => { containerName = civilObj.Name == "" ? "Unnamed" : civilObj.Name; })); } else { converted = converter.ConvertToSpeckle(civilObj); containerName = civilObj.Name == "" ? "Unnamed" : civilObj.Name; } } else { if (Control.InvokeRequired) { converted = (Base)Control.Invoke(new SpeckleConversionDelegate(converter.ConvertToSpeckle), new object[] { obj }); } else { converted = converter.ConvertToSpeckle(obj); } containerName = layerName; } #else if (Control.InvokeRequired) { converted = (Base)Control.Invoke(new SpeckleConversionDelegate(converter.ConvertToSpeckle), new object[] { obj }); } else { converted = converter.ConvertToSpeckle(obj); } containerName = layerName; #endif if (converted == null) { progress.Report.LogConversionError(new Exception($"Failed to convert object {objId} of type {objType}.")); continue; } } catch { progress.Report.LogConversionError(new Exception($"Failed to convert object {objId} of type {objType}.")); continue; } /* TODO: adding the feature data and properties per object * foreach (var key in obj.ExtensionDictionary) * { * converted[key] = obj.ExtensionDictionary.GetUserString(key); * } */ if (commitObj[$"@{containerName}"] == null) { commitObj[$"@{containerName}"] = new List <Base>(); } ((List <Base>)commitObj[$"@{containerName}"]).Add(converted); conversionProgressDict["Conversion"]++; progress.Update(conversionProgressDict); converted.applicationId = objId; convertedCount++; } progress.Report.Merge(converter.Report); if (progress.Report.OperationErrorsCount != 0) { return; } if (convertedCount == 0) { progress.Report.LogOperationError(new SpeckleException("Zero objects converted successfully. Send stopped.", false)); return; } if (progress.CancellationTokenSource.Token.IsCancellationRequested) { return; } Execute.PostToUIThread(() => progress.Max = convertedCount); var transports = new List <ITransport>() { new ServerTransport(client.Account, streamId) }; var commitObjId = await Operations.Send( commitObj, progress.CancellationTokenSource.Token, transports, onProgressAction : dict => progress.Update(dict), onErrorAction : (err, exception) => { progress.Report.LogOperationError(exception); progress.CancellationTokenSource.Cancel(); }, disposeTransports : true ); var actualCommit = new CommitCreateInput { streamId = streamId, objectId = commitObjId, branchName = state.BranchName, message = state.CommitMessage != null ? state.CommitMessage : $"Pushed {convertedCount} elements from {Utils.AppName}.", sourceApplication = Utils.BentleyAppName }; if (state.PreviousCommitId != null) { actualCommit.parents = new List <string>() { state.PreviousCommitId }; } try { var commitId = await client.CommitCreate(actualCommit); state.PreviousCommitId = commitId; } catch (Exception e) { progress.Report.LogOperationError(e); } }
public override async Task <StreamState> ReceiveStream(StreamState state, ProgressViewModel progress) { var kit = KitManager.GetDefaultKit(); var converter = kit.LoadConverter(Utils.BentleyAppName); var transport = new ServerTransport(state.Client.Account, state.StreamId); var stream = await state.Client.StreamGet(state.StreamId); var previouslyReceivedObjects = state.ReceivedObjects; if (converter == null) { throw new Exception("Could not find any Kit!"); } if (Control.InvokeRequired) { Control.Invoke(new SetContextDelegate(converter.SetContextDocument), new object[] { Session.Instance }); } else { converter.SetContextDocument(Session.Instance); } if (progress.CancellationTokenSource.Token.IsCancellationRequested) { return(null); } /* * if (Doc == null) * { * progress.Report.LogOperationError(new Exception($"No Document is open.")); * progress.CancellationTokenSource.Cancel(); * } */ //if "latest", always make sure we get the latest commit when the user clicks "receive" Commit commit = null; if (state.CommitId == "latest") { var res = await state.Client.BranchGet(progress.CancellationTokenSource.Token, state.StreamId, state.BranchName, 1); commit = res.commits.items.FirstOrDefault(); } else { commit = await state.Client.CommitGet(progress.CancellationTokenSource.Token, state.StreamId, state.CommitId); } string referencedObject = commit.referencedObject; var commitObject = await Operations.Receive( referencedObject, progress.CancellationTokenSource.Token, transport, onProgressAction : dict => progress.Update(dict), onTotalChildrenCountKnown : num => Execute.PostToUIThread(() => progress.Max = num), onErrorAction : (message, exception) => { progress.Report.LogOperationError(exception); progress.CancellationTokenSource.Cancel(); }, disposeTransports : true ); try { await state.Client.CommitReceived(new CommitReceivedInput { streamId = stream?.id, commitId = commit?.id, message = commit?.message, sourceApplication = Utils.BentleyAppName }); } catch { // Do nothing! } if (progress.Report.OperationErrorsCount != 0) { return(state); } // invoke conversions on the main thread via control var flattenedObjects = FlattenCommitObject(commitObject, converter); List <ApplicationPlaceholderObject> newPlaceholderObjects; if (Control.InvokeRequired) { newPlaceholderObjects = (List <ApplicationPlaceholderObject>)Control.Invoke(new NativeConversionAndBakeDelegate(ConvertAndBakeReceivedObjects), new object[] { flattenedObjects, converter, state, progress }); } else { newPlaceholderObjects = ConvertAndBakeReceivedObjects(flattenedObjects, converter, state, progress); } if (newPlaceholderObjects == null) { converter.Report.ConversionErrors.Add(new Exception("fatal error: receive cancelled by user")); return(null); } DeleteObjects(previouslyReceivedObjects, newPlaceholderObjects); state.ReceivedObjects = newPlaceholderObjects; progress.Report.Merge(converter.Report); if (progress.Report.OperationErrorsCount != 0) { return(null); // the commit is being rolled back } try { //await state.RefreshStream(); WriteStateToFile(); } catch (Exception e) { progress.Report.OperationErrors.Add(e); } return(state); }
/// <summary> /// Receives a stream and bakes into the existing revit file. /// </summary> /// <param name="state"></param> /// <returns></returns> public override async Task <StreamState> ReceiveStream(StreamState state, ProgressViewModel progress) { var kit = KitManager.GetDefaultKit(); var converter = kit.LoadConverter(ConnectorRevitUtils.RevitAppName); converter.SetContextDocument(CurrentDoc.Document); var previouslyReceiveObjects = state.ReceivedObjects; var transport = new ServerTransport(state.Client.Account, state.StreamId); var stream = await state.Client.StreamGet(state.StreamId); if (progress.CancellationTokenSource.Token.IsCancellationRequested) { return(null); } Commit myCommit = null; //if "latest", always make sure we get the latest commit when the user clicks "receive" if (state.CommitId == "latest") { var res = await state.Client.BranchGet(progress.CancellationTokenSource.Token, state.StreamId, state.BranchName, 1); myCommit = res.commits.items.FirstOrDefault(); } else { myCommit = await state.Client.CommitGet(progress.CancellationTokenSource.Token, state.StreamId, state.CommitId); } string referencedObject = myCommit.referencedObject; var commitObject = await Operations.Receive( referencedObject, progress.CancellationTokenSource.Token, transport, onProgressAction : dict => progress.Update(dict), onErrorAction : (s, e) => { progress.Report.LogOperationError(e); progress.CancellationTokenSource.Cancel(); }, onTotalChildrenCountKnown : count => { progress.Max = count; }, disposeTransports : true ); try { await state.Client.CommitReceived(new CommitReceivedInput { streamId = stream?.id, commitId = myCommit?.id, message = myCommit?.message, sourceApplication = ConnectorRevitUtils.RevitAppName }); } catch { // Do nothing! } if (progress.Report.OperationErrorsCount != 0) { return(state); } if (progress.CancellationTokenSource.Token.IsCancellationRequested) { return(null); } await RevitTask.RunAsync(app => { using (var t = new Transaction(CurrentDoc.Document, $"Baking stream {state.StreamId}")) { var failOpts = t.GetFailureHandlingOptions(); failOpts.SetFailuresPreprocessor(new ErrorEater(converter)); failOpts.SetClearAfterRollback(true); t.SetFailureHandlingOptions(failOpts); t.Start(); var flattenedObjects = FlattenCommitObject(commitObject, converter); // needs to be set for editing to work converter.SetPreviousContextObjects(previouslyReceiveObjects); // needs to be set for openings in floors and roofs to work converter.SetContextObjects(flattenedObjects.Select(x => new ApplicationPlaceholderObject { applicationId = x.applicationId, NativeObject = x }).ToList()); var newPlaceholderObjects = ConvertReceivedObjects(flattenedObjects, converter, state, progress); // receive was cancelled by user if (newPlaceholderObjects == null) { progress.Report.LogConversionError(new Exception("fatal error: receive cancelled by user")); t.RollBack(); return; } DeleteObjects(previouslyReceiveObjects, newPlaceholderObjects); state.ReceivedObjects = newPlaceholderObjects; t.Commit(); progress.Report.Merge(converter.Report); } }); if (converter.Report.ConversionErrors.Any(x => x.Message.Contains("fatal error"))) { // the commit is being rolled back return(null); } return(state); }
public override async Task SendStream(StreamState state, ProgressViewModel progress) { var kit = KitManager.GetDefaultKit(); var converter = kit.LoadConverter(Utils.AutocadAppName); var streamId = state.StreamId; var client = state.Client; if (state.Filter != null) { state.SelectedObjectIds = GetObjectsFromFilter(state.Filter, converter); } // remove deleted object ids var deletedElements = new List <string>(); foreach (var handle in state.SelectedObjectIds) { if (Doc.Database.TryGetObjectId(Utils.GetHandle(handle), out ObjectId id)) { if (id.IsErased || id.IsNull) { deletedElements.Add(handle); } } } state.SelectedObjectIds = state.SelectedObjectIds.Where(o => !deletedElements.Contains(o)).ToList(); if (state.SelectedObjectIds.Count == 0) { progress.Report.LogOperationError(new Exception("Zero objects selected; send stopped. Please select some objects, or check that your filter can actually select something.")); return; } var commitObj = new Base(); var units = Units.GetUnitsFromString(Doc.Database.Insunits.ToString()); commitObj["units"] = units; var conversionProgressDict = new ConcurrentDictionary <string, int>(); conversionProgressDict["Conversion"] = 0; Execute.PostToUIThread(() => progress.Max = state.SelectedObjectIds.Count()); int convertedCount = 0; bool renamedlayers = false; using (Transaction tr = Doc.Database.TransactionManager.StartTransaction()) { // set the context doc for conversion - this is set inside the transaction loop because the converter retrieves this transaction for all db editing when the context doc is set! converter.SetContextDocument(Doc); foreach (var autocadObjectHandle in state.SelectedObjectIds) { if (progress.CancellationTokenSource.Token.IsCancellationRequested) { return; } // get the db object from id Handle hn = Utils.GetHandle(autocadObjectHandle); DBObject obj = hn.GetObject(out string type, out string layer); if (obj == null) { progress.Report.Log($"Skipped not found object: ${autocadObjectHandle}."); continue; } if (!converter.CanConvertToSpeckle(obj)) { progress.Report.Log($"Skipped not supported type: ${type}. Object ${obj.Id} not sent."); continue; } // convert obj Base converted = null; string containerName = string.Empty; converted = converter.ConvertToSpeckle(obj); if (converted == null) { progress.Report.LogConversionError(new Exception($"Failed to convert object {autocadObjectHandle} of type {type}.")); continue; } /* TODO: adding the extension dictionary / xdata per object * foreach (var key in obj.ExtensionDictionary) * { * converted[key] = obj.ExtensionDictionary.GetUserString(key); * } */ if (obj is BlockReference) { containerName = "Blocks"; } else { // remove invalid chars from layer name string cleanLayerName = Utils.RemoveInvalidDynamicPropChars(layer); containerName = cleanLayerName; if (!cleanLayerName.Equals(layer)) { renamedlayers = true; } } if (commitObj[$"@{containerName}"] == null) { commitObj[$"@{containerName}"] = new List <Base>(); } ((List <Base>)commitObj[$"@{containerName}"]).Add(converted); conversionProgressDict["Conversion"]++; progress.Update(conversionProgressDict); converted.applicationId = autocadObjectHandle; convertedCount++; } tr.Commit(); } progress.Report.Merge(converter.Report); if (convertedCount == 0) { progress.Report.LogOperationError(new SpeckleException("Zero objects converted successfully. Send stopped.", false)); return; } if (renamedlayers) { progress.Report.Log("Replaced illegal chars ./ with - in one or more layer names."); } if (progress.CancellationTokenSource.Token.IsCancellationRequested) { return; } Execute.PostToUIThread(() => progress.Max = convertedCount); var transports = new List <ITransport>() { new ServerTransport(client.Account, streamId) }; var commitObjId = await Operations.Send( commitObj, progress.CancellationTokenSource.Token, transports, onProgressAction : dict => progress.Update(dict), onErrorAction : (err, exception) => { progress.Report.LogOperationError(exception); progress.CancellationTokenSource.Cancel(); }, disposeTransports : true ); if (progress.Report.OperationErrorsCount != 0) { return; } var actualCommit = new CommitCreateInput { streamId = streamId, objectId = commitObjId, branchName = state.BranchName, message = state.CommitMessage != null ? state.CommitMessage : $"Pushed {convertedCount} elements from {Utils.AppName}.", sourceApplication = Utils.AutocadAppName }; if (state.PreviousCommitId != null) { actualCommit.parents = new List <string>() { state.PreviousCommitId }; } try { var commitId = await client.CommitCreate(actualCommit); state.PreviousCommitId = commitId; } catch (Exception e) { progress.Report.LogOperationError(e); } }
private void ConvertCommit(Base commitObject, ISpeckleConverter converter, StreamState state, ProgressViewModel progress, Stream stream, string id) { using (DocumentLock l = Doc.LockDocument()) { using (Transaction tr = Doc.Database.TransactionManager.StartTransaction()) { // set the context doc for conversion - this is set inside the transaction loop because the converter retrieves this transaction for all db editing when the context doc is set! converter.SetContextDocument(Doc); // keep track of conversion progress here var conversionProgressDict = new ConcurrentDictionary <string, int>(); conversionProgressDict["Conversion"] = 0; Execute.PostToUIThread(() => progress.Max = state.SelectedObjectIds.Count()); Action updateProgressAction = () => { conversionProgressDict["Conversion"]++; progress.Update(conversionProgressDict); }; // keep track of any layer name changes for notification here bool changedLayerNames = false; // create a commit prefix: used for layers and block definition names var commitPrefix = DesktopUI.Utils.Formatting.CommitInfo(stream.name, state.BranchName, id); // give converter a way to access the commit info Doc.UserData.Add("commit", commitPrefix); // delete existing commit layers try { DeleteBlocksWithPrefix(commitPrefix, tr); DeleteLayersWithPrefix(commitPrefix, tr); } catch { converter.Report.LogOperationError(new Exception($"Failed to remove existing layers or blocks starting with {commitPrefix} before importing new geometry.")); } // flatten the commit object to retrieve children objs int count = 0; var commitObjs = FlattenCommitObject(commitObject, converter, commitPrefix, state, ref count); // open model space block table record for write BlockTableRecord btr = (BlockTableRecord)tr.GetObject(Doc.Database.CurrentSpaceId, OpenMode.ForWrite); // More efficient this way than doing this per object var lineTypeDictionary = new Dictionary <string, ObjectId>(); var lineTypeTable = (LinetypeTable)tr.GetObject(Doc.Database.LinetypeTableId, OpenMode.ForRead); foreach (ObjectId lineTypeId in lineTypeTable) { var linetype = (LinetypeTableRecord)tr.GetObject(lineTypeId, OpenMode.ForRead); lineTypeDictionary.Add(linetype.Name, lineTypeId); } foreach (var commitObj in commitObjs) { // create the object's bake layer if it doesn't already exist (Base obj, string layerName) = commitObj; var converted = converter.ConvertToNative(obj); var convertedEntity = converted as Entity; if (convertedEntity != null) { if (GetOrMakeLayer(layerName, tr, out string cleanName)) { // record if layer name has been modified if (!cleanName.Equals(layerName)) { changedLayerNames = true; } var res = convertedEntity.Append(cleanName); if (res.IsValid) { // handle display Base display = obj[@"displayStyle"] as Base; if (display != null) { var color = display["color"] as int?; var lineType = display["linetype"] as string; var lineWidth = display["lineweight"] as double?; if (color != null) { var systemColor = System.Drawing.Color.FromArgb((int)color); convertedEntity.Color = Color.FromRgb(systemColor.R, systemColor.G, systemColor.B); convertedEntity.Transparency = new Transparency(systemColor.A); } if (lineWidth != null) { convertedEntity.LineWeight = Utils.GetLineWeight((double)lineWidth); } if (lineType != null) { if (lineTypeDictionary.ContainsKey(lineType)) { convertedEntity.LinetypeId = lineTypeDictionary[lineType]; } } } tr.TransactionManager.QueueForGraphicsFlush(); } else { progress.Report.LogConversionError(new Exception($"Failed to add converted object {obj.id} of type {obj.speckle_type} to the document.")); } } else { progress.Report.LogOperationError(new Exception($"Failed to create layer {layerName} to bake objects into.")); } } else if (converted == null) { progress.Report.LogConversionError(new Exception($"Failed to convert object {obj.id} of type {obj.speckle_type}.")); } } progress.Report.Merge(converter.Report); if (changedLayerNames) { progress.Report.Log($"Layer names were modified: one or more layers contained invalid characters {Utils.invalidChars}"); } // remove commit info from doc userdata Doc.UserData.Remove("commit"); tr.Commit(); } } }
public override async Task <StreamState> ReceiveStream(StreamState state, ProgressViewModel progress) { var kit = KitManager.GetDefaultKit(); var converter = kit.LoadConverter(Utils.AutocadAppName); if (converter == null) { throw new Exception("Could not find any Kit!"); } var transport = new ServerTransport(state.Client.Account, state.StreamId); var stream = await state.Client.StreamGet(state.StreamId); if (progress.CancellationTokenSource.Token.IsCancellationRequested) { return(null); } if (Doc == null) { progress.Report.LogOperationError(new Exception($"No Document is open.")); progress.CancellationTokenSource.Cancel(); } //if "latest", always make sure we get the latest commit when the user clicks "receive" Commit commit = null; if (state.CommitId == "latest") { var res = await state.Client.BranchGet(progress.CancellationTokenSource.Token, state.StreamId, state.BranchName, 1); commit = res.commits.items.FirstOrDefault(); } else { commit = await state.Client.CommitGet(progress.CancellationTokenSource.Token, state.StreamId, state.CommitId); } string referencedObject = commit.referencedObject; var commitObject = await Operations.Receive( referencedObject, progress.CancellationTokenSource.Token, transport, onProgressAction : dict => progress.Update(dict), onTotalChildrenCountKnown : num => Execute.PostToUIThread(() => progress.Max = num), onErrorAction : (message, exception) => { progress.Report.LogOperationError(exception); progress.CancellationTokenSource.Cancel(); }, disposeTransports : true ); try { await state.Client.CommitReceived(new CommitReceivedInput { streamId = stream?.id, commitId = commit?.id, message = commit?.message, sourceApplication = Utils.AutocadAppName }); } catch { // Do nothing! } if (progress.Report.OperationErrorsCount != 0) { return(state); } // invoke conversions on the main thread via control if (Control.InvokeRequired) { Control.Invoke(new ConversionDelegate(ConvertCommit), new object[] { commitObject, converter, state, progress, stream, commit.id }); } else { ConvertCommit(commitObject, converter, state, progress, stream, commit.id); } return(state); }
public override async Task <StreamState> ReceiveStream(StreamState state, ProgressViewModel progress) { Tracker.TrackPageview(Tracker.RECEIVE); Exceptions.Clear(); var kit = KitManager.GetDefaultKit(); var converter = kit.LoadConverter(ConnectorETABSUtils.ETABSAppName); converter.SetContextDocument(Model); //var previouslyRecieveObjects = state.ReceivedObjects; if (converter == null) { throw new Exception("Could not find any Kit!"); //RaiseNotification($"Could not find any Kit!"); progress.CancellationTokenSource.Cancel(); //return null; } Tracker.TrackPageview(Tracker.STREAM_GET); var stream = await state.Client.StreamGet(state.StreamId); if (progress.CancellationTokenSource.Token.IsCancellationRequested) { return(null); } var transport = new ServerTransport(state.Client.Account, state.StreamId); Exceptions.Clear(); Commit commit = null; if (state.CommitId == "latest") { var res = await state.Client.BranchGet(progress.CancellationTokenSource.Token, state.StreamId, state.BranchName, 1); commit = res.commits.items.FirstOrDefault(); } else { commit = await state.Client.CommitGet(progress.CancellationTokenSource.Token, state.StreamId, state.CommitId); } string referencedObject = commit.referencedObject; var commitObject = await Operations.Receive( referencedObject, progress.CancellationTokenSource.Token, transport, onProgressAction : dict => progress.Update(dict), onErrorAction : (Action <string, Exception>)((s, e) => { progress.Report.LogOperationError(e); progress.CancellationTokenSource.Cancel(); }), //onTotalChildrenCountKnown: count => Execute.PostToUIThread(() => state.Progress.Maximum = count), disposeTransports : true ); if (progress.Report.OperationErrorsCount != 0) { return(state); } try { await state.Client.CommitReceived(new CommitReceivedInput { streamId = stream?.id, commitId = commit?.id, message = commit?.message, sourceApplication = ConnectorETABSUtils.ETABSAppName }); } catch { // Do nothing! } if (progress.Report.OperationErrorsCount != 0) { return(state); } if (progress.CancellationTokenSource.Token.IsCancellationRequested) { return(null); } var conversionProgressDict = new ConcurrentDictionary <string, int>(); conversionProgressDict["Conversion"] = 0; //Execute.PostToUIThread(() => state.Progress.Maximum = state.SelectedObjectIds.Count()); Action updateProgressAction = () => { conversionProgressDict["Conversion"]++; progress.Update(conversionProgressDict); }; var commitObjs = FlattenCommitObject(commitObject, converter); foreach (var commitObj in commitObjs) { BakeObject(commitObj, state, converter); updateProgressAction?.Invoke(); } try { //await state.RefreshStream(); WriteStateToFile(); } catch (Exception e) { progress.Report.LogOperationError(e); WriteStateToFile(); //state.Errors.Add(e); //Globals.Notify($"Receiving done, but failed to update stream from server.\n{e.Message}"); } progress.Report.Merge(converter.Report); return(state); }