Esempio n. 1
0
        // (Konrad) We are not going to process warnings here.
#else
        /// <summary>
        /// Adds Warnings to a collection in database. If warnings exist it updates their status.
        /// </summary>
        public static void ProcessWarnings(ActionType action, Document doc, string centralPath)
        {
            var current = doc.GetWarnings().Select(x => new WarningItem(x, doc)).ToList();

            switch (action)
            {
            case ActionType.CheckIn:
                if (!ServerUtilities.Post(current, "warnings/add", out ResponseCreated unused1))
                {
                    Log.AppendLog(LogMessageType.ERROR, "Failed to publish Views Data.");
                }
                break;

            case ActionType.Synch:
                var newW = AppCommand.Warnings.Values
                           .Where(x => !string.IsNullOrEmpty(x.CreatedBy) && current.Any(y => y.UniqueId == x.UniqueId)).ToList();
                var existingW = current.Except(newW).Select(x => x.UniqueId);

                var payload = new WarningData(Environment.UserName, centralPath, newW, existingW);
                if (!ServerUtilities.Post(payload, "warnings/update", out ResponseCreated unused))
                {
                    Log.AppendLog(LogMessageType.ERROR, "Failed to publish Views Data.");
                }
                else
                {
                    CollectWarnings(doc);
                }
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(action), action, null);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Checks if Trigger Records collection exists and creates one if it doesn't. Since trigger
        /// records are published on demand by another tool (DTM) there is no need to publish them here.
        /// </summary>
        /// <param name="centralPath"></param>
        public static void ProcessTriggerRecords(string centralPath)
        {
            var project = MissionControlSetup.Projects[centralPath];

            if (!ServerUtilities.GetByCentralPath(centralPath, "triggerrecords/centralpath", out TriggerRecordData trData))
            {
                if (ServerUtilities.Post(new TriggerRecordData {
                    CentralPath = centralPath.ToLower()
                }, "triggerrecords", out trData))
                {
                    ServerUtilities.Put(new { id = trData.Id }, "projects/" + project.Id + "/addtriggerrecord");

                    if (MissionControlSetup.TriggerRecords.ContainsKey(centralPath))
                    {
                        MissionControlSetup.TriggerRecords.Remove(centralPath);
                    }
                    MissionControlSetup.TriggerRecords.Add(centralPath, trData.Id); // store TriggerRecords record
                }
            }
            if (trData != null)
            {
                if (MissionControlSetup.TriggerRecords.ContainsKey(centralPath))
                {
                    MissionControlSetup.TriggerRecords.Remove(centralPath);
                }
                MissionControlSetup.TriggerRecords.Add(centralPath, trData.Id); // store TriggerRecords record
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Publishes data about Model Opening duration.
        /// </summary>
        /// <param name="filePath">Revit Document central file path.</param>
        public void PublishOpenTime(string filePath)
        {
            try
            {
                var from = AppCommand.OpenTime["from"];
                var to   = DateTime.UtcNow;
                var span = to - from;
                var ms   = (int)span.TotalMilliseconds;

                var eventItem = new ModelEventData
                {
                    CentralPath = filePath.ToLower(),
                    Value       = ms,
                    User        = Environment.UserName.ToLower()
                };

                if (!ServerUtilities.Post(eventItem, "model/opentimes", out ModelEventData unused))
                {
                    Log.AppendLog(LogMessageType.ERROR, "Failed to publish Model Open Times Data.");
                }
            }
            catch (Exception ex)
            {
                Log.AppendLog(LogMessageType.EXCEPTION, ex.Message);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Adds Groups data to collection if such exists, otherwise creates a new one.
        /// </summary>
        private static void ProcessGroups(Document doc, string centralPath)
        {
            var project = MissionControlSetup.Projects[centralPath];
            var data    = new DataRangeRequest(centralPath.ToLower());

            if (!ServerUtilities.Post(data, "groups/groupstats", out GroupsData gData))
            {
                if (ServerUtilities.Post(new GroupsData {
                    CentralPath = centralPath.ToLower()
                }, "groups", out gData))
                {
                    ServerUtilities.Put(new { id = gData.Id }, "projects/" + project.Id + "/addgroup");
                }
            }

            if (gData != null)
            {
                if (MissionControlSetup.GroupsData.ContainsKey(centralPath))
                {
                    MissionControlSetup.GroupsData.Remove(centralPath);
                }
                MissionControlSetup.GroupsData.Add(centralPath, gData); // store groups record

                Messenger.Default.Send(new HealthReportSummaryAdded {
                    Data = gData, Type = SummaryType.Groups
                });

                new Thread(() => new GroupMonitor().PublishData(doc, gData.Id))
                {
                    Priority     = ThreadPriority.BelowNormal,
                    IsBackground = true
                }.Start();
            }
        }
Esempio n. 5
0
        /// <summary>
        /// If Family is marked as Completed it will post the data to MC.
        /// </summary>
        /// <param name="app"></param>
        public void SubmitFamily(UIApplication app)
        {
            var doc = app.ActiveUIDocument.Document;

            if (doc == null || doc.IsFamilyDocument)
            {
                return;
            }

            var centralPath   = FileInfoUtil.GetCentralFilePath(doc);
            var familyStatsId = MissionControlSetup.FamilyData[centralPath].Id;

            if (string.IsNullOrEmpty(familyStatsId))
            {
                return;
            }

            FamilyTask.CompletedOn = DateTime.UtcNow;
            FamilyTask.CompletedBy = Environment.UserName.ToLower();

            if (!ServerUtilities.Post(FamilyTask,
                                      "families/" + familyStatsId + "/family/" + FamilyItem.Name + "/updatetask/" + FamilyTask.Id, out FamilyData unused))
            {
                Log.AppendLog(LogMessageType.ERROR, "Failed to submit Family Task Completed update.");
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Adds Sheets data to collection if such exists, otherwise creates a new one.
        /// </summary>
        public static void ProcessSheets(ActionType action, Document doc, string centralPath)
        {
            var project = MissionControlSetup.Projects[centralPath];

            switch (action)
            {
            case ActionType.CheckIn:
                if (!ServerUtilities.GetByCentralPath(centralPath, "sheets/centralpath", out SheetData sData))
                {
                    if (ServerUtilities.Post(new SheetData {
                        CentralPath = centralPath.ToLower()
                    }, "sheets", out sData))
                    {
                        ServerUtilities.Put(new { id = sData.Id }, "projects/" + project.Id + "/addsheet");

                        if (MissionControlSetup.SheetsData.ContainsKey(centralPath))
                        {
                            MissionControlSetup.SheetsData.Remove(centralPath);
                        }
                        MissionControlSetup.SheetsData.Add(centralPath, sData);     // store sheets record
                    }
                }
                if (sData != null)
                {
                    if (MissionControlSetup.SheetsData.ContainsKey(centralPath))
                    {
                        MissionControlSetup.SheetsData.Remove(centralPath);
                    }
                    MissionControlSetup.SheetsData.Add(centralPath, sData);     // store sheets record

                    Messenger.Default.Send(new CommunicatorDataDownloaded
                    {
                        CentralPath = centralPath,
                        Type        = DataType.Sheets
                    });

                    new Thread(() => new SheetTracker.SheetTracker().SynchSheets(doc))
                    {
                        Priority     = ThreadPriority.BelowNormal,
                        IsBackground = true
                    }.Start();
                }
                break;

            case ActionType.Synch:
                if (MissionControlSetup.SheetsData.ContainsKey(centralPath))
                {
                    new Thread(() => new SheetTracker.SheetTracker().SynchSheets(doc))
                    {
                        Priority     = ThreadPriority.BelowNormal,
                        IsBackground = true
                    }.Start();
                }
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(action), action, null);
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Adds Models data to collection if such exists, otherwise creates a new one.
        /// </summary>
        public static void ProcessModels(ActionType action, Document doc, string centralPath)
        {
            var data = new DataRangeRequest(centralPath.ToLower())
            {
                From = null, To = null
            };

            switch (action)
            {
            case ActionType.CheckIn:
                if (!ServerUtilities.Post(data, "model/getmodelsdata", out List <ModelStats> mData) || mData == null)
                {
                    Log.AppendLog(LogMessageType.ERROR, "Failed to get Model Stats.");
                    return;
                }
                if (mData.Any())
                {
                    if (MissionControlSetup.ModelsData.ContainsKey(centralPath))
                    {
                        MissionControlSetup.ModelsData.Remove(centralPath);
                    }
                    MissionControlSetup.ModelsData.Add(centralPath, mData.First());     // store model record

                    Messenger.Default.Send(new HealthReportSummaryAdded {
                        Data = mData.First(), Type = SummaryType.Models
                    });

                    new Thread(() => new ModelMonitor().PublishModelSize(doc, centralPath, doc.Application.VersionNumber))
                    {
                        Priority     = ThreadPriority.BelowNormal,
                        IsBackground = true
                    }.Start();

                    if (AppCommand.OpenTime.ContainsKey("from"))
                    {
                        new Thread(() => new ModelMonitor().PublishOpenTime(centralPath))
                        {
                            Priority     = ThreadPriority.BelowNormal,
                            IsBackground = true
                        }.Start();
                    }
                }
                break;

            case ActionType.Synch:
                if (AppCommand.SynchTime.ContainsKey("from"))
                {
                    new Thread(() => new ModelMonitor().PublishSynchTime(centralPath))
                    {
                        Priority     = ThreadPriority.BelowNormal,
                        IsBackground = true
                    }.Start();
                }
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(action), action, null);
            }
        }
Esempio n. 8
0
        /// <summary>
        /// Adds Worksets data to collection if such exists, otherwise creates a new one.
        /// </summary>
        public static void ProcessWorksets(ActionType action, Document doc, string centralPath)
        {
            var data = new DataRangeRequest(centralPath.ToLower())
            {
                From = null, To = null
            };

            switch (action)
            {
            case ActionType.CheckIn:
                if (!ServerUtilities.Post(data, "worksets/getworksetsdata", out List <WorksetStats> wData))
                {
                    Log.AppendLog(LogMessageType.ERROR, "Failed to get Workset Stats.");
                    return;
                }
                if (wData != null && wData.Any())
                {
                    if (MissionControlSetup.WorksetsData.ContainsKey(centralPath))
                    {
                        MissionControlSetup.WorksetsData.Remove(centralPath);
                    }
                    MissionControlSetup.WorksetsData.Add(centralPath, wData.First());     // store workset record

                    Messenger.Default.Send(new HealthReportSummaryAdded {
                        Data = wData.First(), Type = SummaryType.Worksets
                    });

                    new Thread(() => new WorksetItemCount().PublishData(doc, centralPath))
                    {
                        Priority     = ThreadPriority.BelowNormal,
                        IsBackground = true
                    }.Start();

                    new Thread(() => new WorksetOpenSynch().PublishData(doc, centralPath, WorksetMonitorState.onopened))
                    {
                        Priority     = ThreadPriority.BelowNormal,
                        IsBackground = true
                    }.Start();
                }
                break;

            case ActionType.Synch:
                new Thread(() => new WorksetOpenSynch().PublishData(doc, centralPath, WorksetMonitorState.onsynched))
                {
                    Priority     = ThreadPriority.BelowNormal,
                    IsBackground = true
                }.Start();
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(action), action, null);
            }
        }
Esempio n. 9
0
        /// <summary>
        /// Publishes information about groups in the model.
        /// </summary>
        /// <param name="doc">Revit Document.</param>
        /// <param name="groupsId">Id of the Groups Document in MongoDB.</param>
        public void PublishData(Document doc, string groupsId)
        {
            try
            {
                var gTypes = new FilteredElementCollector(doc)
                             .OfClass(typeof(GroupType))
                             .Cast <GroupType>()
                             .ToDictionary(x => x.Id, x => new GroupItem
                {
                    Name = x.Name,

                    // (Konrad) If there is a Detail Group attached to Model Group
                    // it will have the same name as Model Group but different Category.
                    Type = x.Category.Name == "Attached Detail Groups"
                            ? "Attached Detail Group"
                            : x.FamilyName
                });

                foreach (var gi in new FilteredElementCollector(doc).OfClass(typeof(Group)).Cast <Group>())
                {
                    var gTypeId = gi.GroupType.Id;
                    if (!gTypes.ContainsKey(gTypeId))
                    {
                        continue;
                    }

                    var gType = gTypes[gTypeId];
                    gType.Instances.Add(new GroupInstanceItem(gi));
                    gType.MemberCount = gi.GetMemberIds().Count;
                }

                var groupStats = new GroupDataItem
                {
                    Groups = gTypes.Values.ToList()
                };

                if (!ServerUtilities.Post(groupStats, "groups/" + groupsId + "/groupstats",
                                          out GroupsData unused))
                {
                    Log.AppendLog(LogMessageType.ERROR, "Failed to publish Groups Data.");
                }
            }
            catch (Exception ex)
            {
                Log.AppendLog(LogMessageType.EXCEPTION, ex.Message);
            }
        }
Esempio n. 10
0
        /// <summary>
        /// Posts approved changes to MongoDB. Mongo will fire socket event when complete.
        /// </summary>
        /// <param name="wrapper">Sheet Task Wrapper containing approved task.</param>
        /// <param name="centralPath"></param>
        public void Approve(SheetTaskWrapper wrapper, string centralPath)
        {
            var sheetsDataId = string.Empty;

            if (MissionControlSetup.SheetsData.ContainsKey(centralPath))
            {
                sheetsDataId = MissionControlSetup.SheetsData[centralPath].Id;
            }
            if (string.IsNullOrEmpty(sheetsDataId))
            {
                return;
            }

            var t = (SheetTask)wrapper.Task;
            var e = (SheetItem)wrapper.Element;

            t.CompletedBy = Environment.UserName.ToLower();
            t.CompletedOn = DateTime.UtcNow;

            // body needs to be updated with a new identifier object or mongo side will fail.
            if (e.IsNewSheet)
            {
                // (Konrad) It's a create sheet task (element associated with task is null). Let's approve that.
                var newSheet = AppCommand.CommunicatorHandler.SheetItem;
                if (newSheet == null)
                {
                    return;
                }

                wrapper.Element = newSheet;
                if (!ServerUtilities.Post(wrapper, "sheets/" + sheetsDataId + "/approvenewsheet", out SheetData unused))
                {
                    Log.AppendLog(LogMessageType.ERROR, "Failed to approve creation of new Sheet.");
                }
            }
            else
            {
                t.SheetId = e.Id;
                if (!ServerUtilities.Post(t, "sheets/" + sheetsDataId + "/updatetasks", out SheetData unused))
                {
                    Log.AppendLog(LogMessageType.ERROR, "Failed to approve changes to Sheet.");
                }
            }
        }
Esempio n. 11
0
        /// <summary>
        /// Publishes Workset Item Count data when Document is closed.
        /// </summary>
        /// <param name="doc">Revit Document.</param>
        /// <param name="filePath">Revit Document central file path.</param>
        public void PublishData(Document doc, string filePath)
        {
            try
            {
                var worksets = new FilteredWorksetCollector(doc)
                               .OfKind(WorksetKind.UserWorkset)
                               .ToWorksets();

                var worksetInfo = new List <WorksetItem>();
                foreach (var w in worksets)
                {
                    // (Konrad) It turns out that for some reason Linked worksets
                    // contain things like CopyMonitor options and Sketch Planes.
                    var worksetFilter = new ElementWorksetFilter(w.Id, false);
                    var planeFilter   = new ElementClassFilter(typeof(SketchPlane), true);
                    var filter        = new LogicalAndFilter(worksetFilter, planeFilter);
                    var count         = new FilteredElementCollector(doc)
                                        .WherePasses(filter)
                                        .WhereElementIsNotElementType()
                                        .GetElementCount();

                    worksetInfo.Add(new WorksetItem
                    {
                        Name  = w.Name,
                        Count = count
                    });
                }

                var wItemData = new WorksetItemData
                {
                    CentralPath = filePath.ToLower(),
                    User        = Environment.UserName.ToLower(),
                    Worksets    = worksetInfo
                };
                if (!ServerUtilities.Post(wItemData, "worksets/itemcount", out WorksetItemData unused))
                {
                    Log.AppendLog(LogMessageType.ERROR, "Failed to publish Worksets Data.");
                }
            }
            catch (Exception ex)
            {
                Log.AppendLog(LogMessageType.EXCEPTION, ex.Message);
            }
        }
Esempio n. 12
0
        /// <summary>
        /// Publishes Workset Open Data to database for onOpened/onSynched events.
        /// </summary>
        /// <param name="doc">Revit Document.</param>
        /// <param name="filePath">Revit Document central file path.</param>
        /// <param name="state">State of the Revit model.</param>
        public void PublishData(Document doc, string filePath, WorksetMonitorState state)
        {
            try
            {
                var worksets = new FilteredWorksetCollector(doc)
                               .OfKind(WorksetKind.UserWorkset)
                               .ToWorksets();

                var opened = 0;
                var closed = 0;
                foreach (var w in worksets)
                {
                    if (w.IsOpen)
                    {
                        opened++;
                    }
                    else
                    {
                        closed++;
                    }
                }

                var worksetInfo = new WorksetEvent
                {
                    CentralPath = filePath.ToLower(),
                    User        = Environment.UserName.ToLower(),
                    Opened      = opened,
                    Closed      = closed
                };

                var route = state == WorksetMonitorState.onopened ? "onopened" : "onsynched";
                if (!ServerUtilities.Post(worksetInfo, "worksets/" + route, out WorksetEvent unused))
                {
                    Log.AppendLog(LogMessageType.ERROR, "Failed to publish Worksets Data: " + state + ".");
                }
            }
            catch (Exception ex)
            {
                Log.AppendLog(LogMessageType.EXCEPTION, ex.Message);
            }
        }
Esempio n. 13
0
        /// <summary>
        /// Checks if Families collection exists and creates one if it doesn't. Since families
        /// stats are published on demand by another tool there is no need to publish them here.
        /// </summary>
        private static void ProcessFamilies(string centralPath)
        {
            var project = MissionControlSetup.Projects[centralPath];

            // (Konrad) For families we only need to make sure that we have the collection id. It will be used
            // by the Tasks. The actual data gets posted by FamilyPublish Tool.
            if (!ServerUtilities.GetByCentralPath(centralPath, "families/centralpath", out FamilyData fData))
            {
                if (ServerUtilities.Post(new FamilyData {
                    CentralPath = centralPath.ToLower()
                }, "families", out fData))
                {
                    ServerUtilities.Put(new { id = fData.Id }, "projects/" + project.Id + "/addfamilies");

                    if (MissionControlSetup.FamilyData.ContainsKey(centralPath))
                    {
                        MissionControlSetup.FamilyData.Remove(centralPath);
                    }
                    MissionControlSetup.FamilyData.Add(centralPath, fData); // store families record
                }
            }
            else
            {
                if (MissionControlSetup.FamilyData.ContainsKey(centralPath))
                {
                    MissionControlSetup.FamilyData.Remove(centralPath);
                }
                MissionControlSetup.FamilyData.Add(centralPath, fData); // store families record

                Messenger.Default.Send(new HealthReportSummaryAdded {
                    Data = fData, Type = SummaryType.Families
                });
                Messenger.Default.Send(new CommunicatorDataDownloaded {
                    CentralPath = centralPath, Type = DataType.Families
                });
            }
        }
Esempio n. 14
0
        private void OnButtonEdit(Window window)
        {
            try
            {
                //update category trigger settings
                var settingsUpdated = false;
                var centralPath     = reportingInfo.CentralPath;
                if (MissionControlSetup.Configurations.ContainsKey(centralPath))
                {
                    var config       = MissionControlSetup.Configurations[centralPath];
                    var updaterFound = config.Updaters
                                       .FirstOrDefault(x => string.Equals(x.UpdaterId, reportingInfo.UpdaterId,
                                                                          StringComparison.OrdinalIgnoreCase));
                    if (updaterFound != null)
                    {
                        var updaterIndex = config.Updaters.IndexOf(updaterFound);
                        var triggerFound = updaterFound.CategoryTriggers
                                           .FirstOrDefault(x => x.CategoryName == reportingInfo.CategoryName);
                        if (triggerFound != null)
                        {
                            var triggerIndex = updaterFound.CategoryTriggers.IndexOf(triggerFound);
                            config.Updaters[updaterIndex].CategoryTriggers[triggerIndex].IsEnabled = false;

                            MissionControlSetup.Configurations.Remove(centralPath);
                            MissionControlSetup.Configurations.Add(centralPath, config);

                            //refresh category trigger
                            AppCommand.Instance.DtmUpdaterInstance.Unregister(Doc);
                            AppCommand.Instance.DtmUpdaterInstance.Register(Doc, config.Updaters[updaterIndex]);

                            settingsUpdated = true;
                        }
                    }
                }

                if (settingsUpdated)
                {
                    if (MissionControlSetup.TriggerRecords.ContainsKey(centralPath))
                    {
                        var trId   = MissionControlSetup.TriggerRecords[centralPath];
                        var record = new TriggerRecordItem
                        {
                            UpdaterId       = reportingInfo.UpdaterId,
                            CategoryName    = reportingInfo.CategoryName,
                            ElementUniqueId = reportingInfo.ReportingUniqueId,
                            CreatedOn       = DateTime.UtcNow,
                            User            = Environment.UserName
                        };

                        if (!ServerUtilities.Post(record, "triggerrecords/" + trId + "/add",
                                                  out TriggerRecordData unused))
                        {
                            Log.AppendLog(LogMessageType.ERROR, "Failed to post Trigger Record Data.");
                        }
                    }


                    window.DialogResult = false;
                }
                window.Close();
            }
            catch (Exception ex)
            {
                Log.AppendLog(LogMessageType.EXCEPTION, ex.Message);
            }
        }
Esempio n. 15
0
        /// <summary>
        /// Method to "check into" mission control. It posts all initial data, and stores all needed references.
        /// </summary>
        /// <param name="doc"></param>
        public void CheckIn(Document doc)
        {
            try
            {
                var centralPath = FileInfoUtil.GetCentralFilePath(doc);

                // (Konrad) We can publish a file path to the DB.
                // That will make it easier to create Configurations.
                // Valid file is:
                // - not detached
                // - not a family
                // - is workshared
                // - is saved on the network, revit server or bim 360 server
                if (!doc.IsDetached && !doc.IsFamilyDocument && doc.IsWorkshared && FilePathItem.IsValidFilePath(centralPath))
                {
                    if (!ServerUtilities.Post(new FilePathItem(centralPath, doc.Application.VersionNumber), "filepaths/add", out FilePathItem unused))
                    {
                        Log.AppendLog(LogMessageType.ERROR, "Failed to publish File Path: " + centralPath);
                    }
                }

                // (Konrad) Get Configuration/Project.
                if (!ServerUtilities.GetByCentralPath(centralPath, "configurations/centralpath", out Configuration configFound))
                {
                    DisableMissionControl();
                    return;
                }

                if (!ServerUtilities.Get("projects/configid/" + configFound.Id, out Project projectFound))
                {
                    DisableMissionControl();
                    return;
                }

                if (MissionControlSetup.Configurations.ContainsKey(centralPath))
                {
                    MissionControlSetup.Configurations.Remove(centralPath);
                }
                MissionControlSetup.Configurations.Add(centralPath, configFound);

                if (MissionControlSetup.Projects.ContainsKey(centralPath))
                {
                    MissionControlSetup.Projects.Remove(centralPath);
                }
                MissionControlSetup.Projects.Add(centralPath, projectFound);

                // (Konrad) This might be a good time to let users know that Mission Control is ready to go.
                AppCommand.CommunicatorHandler.Status  = Status.Success;
                AppCommand.CommunicatorHandler.Message = "Successfully connected to Mission Control!";
                AppCommand.CommunicatorHandler.Request.Make(RequestId.ReportStatus);
                AppCommand.CommunicatorEvent.Raise();

                // (Konrad) Register Updaters that are in the config file.
                CommunicatorUtilities.LaunchCommunicator();
                ApplyConfiguration(doc);
#if RELEASE2015 || RELEASE2016 || RELEASE2017
                // (Konrad) We are not going to process warnings here.
#else
                CollectWarnings(doc);
#endif
                EnableMissionControl();

                Log.AppendLog(LogMessageType.INFO, "Mission Control check in succeeded.");
            }
            catch (Exception ex)
            {
                Log.AppendLog(LogMessageType.EXCEPTION, ex.Message);
            }
        }
Esempio n. 16
0
        /// <summary>
        /// Publishes information about linked models/images/object styles in the model.
        /// </summary>
        /// <param name="doc">Revit Document.</param>
        /// <param name="filePath">Revit Document central file path.</param>
        /// <param name="version">Revit file version.</param>
        public void PublishModelSize(Document doc, string filePath, string version)
        {
            try
            {
                long fileSize;
                try
                {
                    if (filePath.StartsWith("rsn://", StringComparison.OrdinalIgnoreCase))
                    {
                        var server    = string.Empty;
                        var subfolder = string.Empty;

                        // (Konrad) This is a Revit Server project. To get it's size one must use REST API,
                        // and ping the server that it's hosted on.
                        var splits = filePath.Split('/');
                        for (var i = 2; i < splits.Length; i++)
                        {
                            if (i == 2)
                            {
                                server = splits[i];
                            }
                            else
                            {
                                subfolder = subfolder + splits[i] + (i == splits.Length - 1 ? string.Empty : "|");
                            }
                        }
                        var clientPath  = "http://" + server;
                        var requestPath = "RevitServerAdminRestService" + version + "/" + "AdminRestService.svc/" +
                                          subfolder + "/modelinfo";

                        var result = ServerUtilities.GetFileInfoFromRevitServer <RsFileInfo>(clientPath, requestPath);
                        fileSize = result.ModelSize - result.SupportSize;
                    }
                    else if (filePath.StartsWith("bim 360://", StringComparison.OrdinalIgnoreCase))
                    {
                        // (Konrad) For BIM 360 files, we can just pull the file size from local cached file.
                        // It's pretty much what is stored in the web, so will work for our purpose.
                        var fileName         = doc.WorksharingCentralGUID + ".rvt";
                        var localAppData     = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
                        var collaborationDir = Path.Combine(localAppData,
                                                            "Autodesk\\Revit\\Autodesk Revit " + doc.Application.VersionNumber, "CollaborationCache");

                        var file = Directory.GetFiles(collaborationDir, fileName, SearchOption.AllDirectories)
                                   .FirstOrDefault(x => new FileInfo(x).Directory?.Name != "CentralCache");
                        if (file == null)
                        {
                            return;
                        }

                        var fileInfo = new FileInfo(file);
                        fileSize = fileInfo.Length;
                    }
                    else
                    {
                        var fileInfo = new FileInfo(filePath);
                        fileSize = fileInfo.Length;
                    }
                }
                catch (Exception ex)
                {
                    fileSize = 0;
                    Log.AppendLog(LogMessageType.EXCEPTION, ex.Message);
                }

                var eventItem = new ModelEventData
                {
                    CentralPath = filePath.ToLower(),
                    Value       = fileSize,
                    User        = Environment.UserName.ToLower()
                };

                if (!ServerUtilities.Post(eventItem, "model/modelsizes", out ModelEventData unused))
                {
                    Log.AppendLog(LogMessageType.ERROR, "Failed to publish Model Size Data.");
                }
            }
            catch (Exception ex)
            {
                Log.AppendLog(LogMessageType.EXCEPTION, ex.Message);
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="stylesId"></param>
        public void PublishData(Document doc, string stylesId)
        {
            try
            {
                _doc = doc;

                #region Text Note Type stats

                var textTypes = new FilteredElementCollector(doc)
                                .OfClass(typeof(TextNoteType))
                                .ToDictionary(x => x.Id.IntegerValue, x => new Tuple <Element, int>(x, 0));

                var textInstances = new FilteredElementCollector(doc)
                                    .OfClass(typeof(TextNote))
                                    .WhereElementIsNotElementType();

                foreach (var t in textInstances)
                {
                    var key = t.GetTypeId().IntegerValue;
                    if (textTypes.ContainsKey(key))
                    {
                        // increment instance count
                        textTypes[key] = new Tuple <Element, int>(textTypes[key].Item1, textTypes[key].Item2 + 1);
                    }
                }

                var textStats = textTypes.Select(x => new TextNoteTypeInfo(x.Value.Item1)
                {
                    Instances = x.Value.Item2
                })
                                .ToList();

                #endregion

                #region Dimension Type stats

                var dimTypes = new FilteredElementCollector(doc)
                               .OfClass(typeof(DimensionType))
                               .Cast <DimensionType>()
                               .Where(x => !string.IsNullOrEmpty(x.get_Parameter(BuiltInParameter.SYMBOL_NAME_PARAM).AsString()))
                               .ToDictionary(x => x.Id.IntegerValue, x => new Tuple <DimensionType, int>(x, 0));

                var dimInstances = new FilteredElementCollector(doc)
                                   .OfClass(typeof(Dimension))
                                   .WhereElementIsNotElementType()
                                   .Cast <Dimension>();

                // (Konrad) There is a user override in Configuration that controls what dimension overrides are ignored
                var centralPath = FileInfoUtil.GetCentralFilePath(doc);
                var config      = MissionControlSetup.Configurations.ContainsKey(centralPath)
                    ? MissionControlSetup.Configurations[centralPath]
                    : null;

                var dimensionValueCheck = new List <string> {
                    "EQ"
                };                                                   //defaults
                if (config != null)
                {
                    dimensionValueCheck = config.Updaters.First(x => string.Equals(x.UpdaterId,
                                                                                   Properties.Resources.HealthReportTrackerGuid, StringComparison.OrdinalIgnoreCase)).UserOverrides.DimensionValueCheck.Values;
                }

                var units           = _doc.GetUnits();
                var dimSegmentStats = new List <DimensionSegmentInfo>();
                foreach (var d in dimInstances)
                {
                    var key = d.GetTypeId().IntegerValue;
                    if (dimTypes.ContainsKey(key))
                    {
                        // increment instance count
                        dimTypes[key] = new Tuple <DimensionType, int>(dimTypes[key].Item1, dimTypes[key].Item2 + 1);
                    }

                    if (d.NumberOfSegments == 0)
                    {
                        if (string.IsNullOrEmpty(d.ValueOverride))
                        {
                            continue;
                        }
                        if (dimensionValueCheck.Any(d.ValueOverride.Contains))
                        {
                            continue;
                        }

                        // dim w/ zero segments
                        dimSegmentStats.Add(new DimensionSegmentInfo(d)
                        {
#if RELEASE2021
                            ValueString = UnitFormatUtils.Format(units, d.DimensionType.GetSpecTypeId(), (double)d.Value, false),
#else
                            ValueString = UnitFormatUtils.Format(units, d.DimensionType.UnitType, (double)d.Value, false, false),
#endif
                            OwnerViewType = d.ViewSpecific
                                ? ((View)doc.GetElement(d.OwnerViewId)).ViewType.ToString()
                                : string.Empty,
                            OwnerViewId = d.OwnerViewId.IntegerValue
                        });
                    }
                    else
                    {
                        // dim w/ multiple segments
                        foreach (DimensionSegment s in d.Segments)
                        {
                            if (string.IsNullOrEmpty(s.ValueOverride))
                            {
                                continue;
                            }
                            if (dimensionValueCheck.Any(s.ValueOverride.Contains))
                            {
                                continue;
                            }

                            dimSegmentStats.Add(new DimensionSegmentInfo(s)
                            {
#if RELEASE2021
                                ValueString = UnitFormatUtils.Format(units, d.DimensionType.GetSpecTypeId(), (double)d.Value, false),
#else
                                ValueString = UnitFormatUtils.Format(units, d.DimensionType.UnitType, (double)d.Value, false, false),
#endif
                                OwnerViewType = d.ViewSpecific
                                    ? ((View)doc.GetElement(d.OwnerViewId)).ViewType.ToString()
                                    : string.Empty,
                                OwnerViewId = d.OwnerViewId.IntegerValue
                            });
                        }
                    }
                }

                var dimStats = dimTypes.Select(x => new DimensionTypeInfo(x.Value.Item1)
                {
                    Instances = x.Value.Item2
                })
                               .ToList();

                #endregion

                #region Line Style stats

                //TODO: Finish this out.

                #endregion

                var stylesStats = new StylesDataItem
                {
                    User            = Environment.UserName.ToLower(),
                    TextStats       = textStats,
                    DimStats        = dimStats,
                    DimSegmentStats = dimSegmentStats
                };

                if (!ServerUtilities.Post(stylesStats, "styles/" + stylesId + "/stylestats",
                                          out StylesDataItem unused))
                {
                    Log.AppendLog(LogMessageType.ERROR, "Failed to publish Styles Data.");
                }
            }
            catch (Exception e)
            {
                Log.AppendLog(LogMessageType.EXCEPTION, e.Message);
            }
        }
Esempio n. 18
0
        /// <summary>
        /// Publishes View count data when Document is closed.
        /// </summary>
        /// <param name="doc">Revit Document.</param>
        /// <param name="viewsId">Id of the Views Document in MongoDB.</param>
        public void PublishData(Document doc, string viewsId)
        {
            try
            {
                // (Konrad) Collect info about views.
                // Views on sheet, schedules on sheet, views total etc.
                var scheduleTotalCount = new FilteredElementCollector(doc)
                                         .OfClass(typeof(ViewSchedule))
                                         .GetElementCount();

                var viewTotalCount           = 0;
                var unclippedViews           = 0;
                var viewsOnSheet             = 0;
                var viewsOnSheetWithTemplate = 0;
                var sheetTotalCount          = 0;
                foreach (var v in new FilteredElementCollector(doc).OfClass(typeof(View)).Cast <View>().Where(x => !x.IsTemplate))
                {
                    viewTotalCount++;
                    switch (v.ViewType)
                    {
                    case ViewType.DrawingSheet:
                        sheetTotalCount++;
                        var viewIds = ((ViewSheet)v).GetAllPlacedViews();
                        foreach (var id in viewIds)
                        {
                            viewsOnSheet++;
                            var view = (View)doc.GetElement(id);
                            if (view.ViewTemplateId != ElementId.InvalidElementId)
                            {
                                viewsOnSheetWithTemplate++;
                            }
                        }
                        break;

                    case ViewType.FloorPlan:
                    case ViewType.EngineeringPlan:
                    case ViewType.AreaPlan:
                    case ViewType.CeilingPlan:
                        if (v.get_Parameter(BuiltInParameter.VIEW_BACK_CLIPPING).AsInteger() == 0)
                        {
                            unclippedViews++;
                        }
                        break;

                    case ViewType.Elevation:
                    case ViewType.Section:
                        if (v.get_Parameter(BuiltInParameter.VIEWER_BOUND_FAR_CLIPPING).AsInteger() == 0)
                        {
                            unclippedViews++;
                        }
                        break;

                    case ViewType.ThreeD:
                        if (v.get_Parameter(BuiltInParameter.VIEWER_BOUND_ACTIVE_FAR).AsInteger() == 0)
                        {
                            unclippedViews++;
                        }
                        break;
                    }
                }

                var scheduleSet = new HashSet <ElementId>();
                foreach (var ssi in new FilteredElementCollector(doc)
                         .OfClass(typeof(ScheduleSheetInstance))
                         .Cast <ScheduleSheetInstance>())
                {
                    scheduleSet.Add(ssi.ScheduleId);
                }
                var schedulesOnSheet = scheduleSet.Count;
                viewsOnSheet += schedulesOnSheet;

                var viewStats = new ViewsDataItem
                {
                    TotalViews               = viewTotalCount,
                    TotalSheets              = sheetTotalCount,
                    TotalSchedules           = scheduleTotalCount,
                    ViewsOnSheet             = viewsOnSheet,
                    ViewsOnSheetWithTemplate = viewsOnSheetWithTemplate,
                    SchedulesOnSheet         = schedulesOnSheet,
                    UnclippedViews           = unclippedViews
                };

                if (!ServerUtilities.Post(viewStats, "views/" + viewsId + "/viewstats",
                                          out ViewsData unused))
                {
                    Log.AppendLog(LogMessageType.ERROR, "Failed to publish Views Data.");
                }
            }
            catch (Exception ex)
            {
                Log.AppendLog(LogMessageType.EXCEPTION, ex.Message);
            }
        }
Esempio n. 19
0
        /// <summary>
        /// Registers availble configuration based on Central Model path match.
        /// </summary>
        private static void ApplyConfiguration(Document doc)
        {
            try
            {
                var centralPath   = FileInfoUtil.GetCentralFilePath(doc);
                var config        = MissionControlSetup.Configurations[centralPath];
                var launchSockets = false;
                foreach (var updater in config.Updaters)
                {
                    if (!updater.IsUpdaterOn)
                    {
                        continue;
                    }

                    if (string.Equals(updater.UpdaterId, AppCommand.Instance.DoorUpdaterInstance.UpdaterGuid.ToString(),
                                      StringComparison.OrdinalIgnoreCase))
                    {
                        // (Konrad) We need to register updaters from within Revit context.
                        // That's why we are running this in the Idling Event.
                        AppCommand.EnqueueTask(app =>
                        {
                            AppCommand.Instance.DoorUpdaterInstance.Register(doc, updater);
                        });
                    }
                    else if (string.Equals(updater.UpdaterId, AppCommand.Instance.DtmUpdaterInstance.UpdaterGuid.ToString(),
                                           StringComparison.OrdinalIgnoreCase))
                    {
                        ProcessTriggerRecords(centralPath);

                        AppCommand.EnqueueTask(app =>
                        {
                            AppCommand.Instance.DtmUpdaterInstance.Register(doc, updater);
                        });

                        DTMTool.DtmSynchOverrides.CreateReloadLatestOverride();
                        DTMTool.DtmSynchOverrides.CreateSynchToCentralOverride();
                    }
                    else if (string.Equals(updater.UpdaterId, Properties.Resources.LinkUnloadTrackerGuid,
                                           StringComparison.OrdinalIgnoreCase))
                    {
                        AppCommand.EnqueueTask(app =>
                        {
                            LinkUnloadMonitor.LinkUnloadMonitor.CreateLinkUnloadOverride(app);
                        });
                    }
                    else if (string.Equals(updater.UpdaterId, Properties.Resources.SheetsTrackerGuid,
                                           StringComparison.OrdinalIgnoreCase))
                    {
                        ProcessSheets(ActionType.CheckIn, doc, centralPath);

                        launchSockets = true;
                    }
                    else if (string.Equals(updater.UpdaterId, Properties.Resources.HealthReportTrackerGuid,
                                           StringComparison.OrdinalIgnoreCase))
                    {
                        // (Konrad) These are read-only methods so they don't need to run in Revit context.
                        ProcessModels(ActionType.CheckIn, doc, centralPath);
                        ProcessWorksets(ActionType.CheckIn, doc, centralPath);
#if RELEASE2015 || RELEASE2016 || RELEASE2017
                        // (Konrad) We are not going to process warnings here.
#else
                        ProcessWarnings(ActionType.CheckIn, doc, centralPath);
#endif
                        ProcessFamilies(centralPath);
                        ProcessStyle(doc, centralPath);
                        ProcessLinks(doc, centralPath);
                        ProcessViews(doc, centralPath);
                        ProcessGroups(doc, centralPath);

                        launchSockets = true;
                    }
                }

                // (Konrad) This tool will reset Shared Parameters Location to one specified in Mission Control
                if (config.GetType().GetProperty("sharedParamMonitor") != null &&
                    config.SharedParamMonitor.IsMonitorOn)
                {
                    if (File.Exists(config.SharedParamMonitor.FilePath))
                    {
                        doc.Application.SharedParametersFilename = config.SharedParamMonitor.FilePath;
                    }
                    else
                    {
                        Log.AppendLog(LogMessageType.ERROR, "Failed to reset Shared Parameter location. Could not find file specified.");
                    }
                }

                if (launchSockets)
                {
                    // (Konrad) in order not to become out of synch with the database we need a way
                    // to communicate live updates from the database to task assistant/communicator
                    var socket = new MissionControlSocket(doc);
                    socket.Start();
                    AppCommand.Socket = socket;
                }

                // Publish user/machine info to be used by Zombie
                var userInfo = new UserItem
                {
                    User    = Environment.UserName.ToLower(),
                    Machine = Environment.MachineName
                };

                if (!ServerUtilities.Post(userInfo, "users/add", out ResponseCreated unused1))
                {
                    Log.AppendLog(LogMessageType.ERROR, "Failed to publish User/Machine Data.");
                }
            }
            catch (Exception ex)
            {
                Log.AppendLog(LogMessageType.EXCEPTION, ex.Message);
            }
        }
Esempio n. 20
0
        /// <summary>
        /// Publishes information about linked models/images/object styles in the model.
        /// </summary>
        /// <param name="doc">Revit Document.</param>
        /// <param name="linksId">Id of the Links Document in MongoDB.</param>
        public void PublishData(Document doc, string linksId)
        {
            try
            {
                var dwgStyles = new FilteredElementCollector(doc)
                                .OfClass(typeof(GraphicsStyle))
                                .Cast <GraphicsStyle>()
                                .Where(x => x.GraphicsStyleCategory.Name.Contains(".dwg"))
                                .Select(x => x.GraphicsStyleCategory);

                var totalDwgStyles = dwgStyles.Sum(x => x.SubCategories.Size);

                var familyStyles = new FilteredElementCollector(doc)
                                   .OfClass(typeof(GraphicsStyle))
                                   .Cast <GraphicsStyle>()
                                   .Where(x => x.GraphicsStyleCategory.Name == "Imports in Families")
                                   .Select(x => x.GraphicsStyleCategory);
                var totalImportedStyles = familyStyles.Sum(x => x.SubCategories.Size);

                // (Konrad) Collect info about Images
                var allPlacedImageIds = new FilteredElementCollector(doc)
                                        .OfCategory(BuiltInCategory.OST_RasterImages)
                                        .Select(x => x.GetTypeId())
                                        .ToList();

                var totalUnusedImages = new FilteredElementCollector(doc)
                                        .OfClass(typeof(ImageType))
                                        .Excluding(allPlacedImageIds)
                                        .GetElementCount();

                // (Konrad) Collect all Linked Model info
                var totalLinkedCad = new FilteredElementCollector(doc)
                                     .OfClass(typeof(CADLinkType))
                                     .GetElementCount();

                var totalLinkedRvt = new FilteredElementCollector(doc)
                                     .OfClass(typeof(RevitLinkType))
                                     .GetElementCount();

                var cadLinksDic = new FilteredElementCollector(doc)
                                  .OfClass(typeof(CADLinkType))
                                  .Select(x => new DwgFileInfo {
                    Name = x.Name, ElementId = x.Id.IntegerValue
                })
                                  .ToDictionary(key => key.ElementId, value => value);

                var totalImportInstance = 0;
                foreach (var ii in new FilteredElementCollector(doc).OfClass(typeof(ImportInstance)))
                {
                    totalImportInstance++;
                    var id = ii.GetTypeId().IntegerValue;
                    if (!cadLinksDic.ContainsKey(id))
                    {
                        continue;
                    }

                    if (cadLinksDic[id].Instances == 0)
                    {
                        cadLinksDic[id].IsViewSpecific = ii.ViewSpecific;
                        cadLinksDic[id].IsLinked       = ((ImportInstance)ii).IsLinked;
                    }
                    cadLinksDic[id].Instances = cadLinksDic[id].Instances + 1;
                }

                var linkStats = new LinkDataItem
                {
                    TotalImportedDwg    = totalImportInstance,
                    ImportedDwgFiles    = cadLinksDic.Values.ToList(),
                    UnusedLinkedImages  = totalUnusedImages,
                    TotalDwgStyles      = totalDwgStyles,
                    TotalImportedStyles = totalImportedStyles,
                    TotalLinkedModels   = totalLinkedCad + totalLinkedRvt,
                    TotalLinkedDwg      = totalLinkedCad
                };

                if (!ServerUtilities.Post(linkStats, "links/" + linksId + "/linkstats",
                                          out LinkDataItem unused))
                {
                    Log.AppendLog(LogMessageType.ERROR, "Failed to publish Links Data.");
                }
            }
            catch (Exception ex)
            {
                Log.AppendLog(LogMessageType.EXCEPTION, ex.Message);
            }
        }
Esempio n. 21
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="doc"></param>
        public void SynchSheets(Document doc)
        {
            try
            {
                var centralPath = FileInfoUtil.GetCentralFilePath(doc);
                var sheetsData  = MissionControlSetup.SheetsData.ContainsKey(centralPath)
                    ? MissionControlSetup.SheetsData[centralPath]
                    : null;
                if (sheetsData == null)
                {
                    return;
                }

                var sheets = new FilteredElementCollector(doc)
                             .OfCategory(BuiltInCategory.OST_Sheets)
                             .WhereElementIsNotElementType()
                             .Cast <ViewSheet>()
                             .Select(x => new SheetItem(x, centralPath))
                             .ToDictionary(key => key.UniqueId, value => value);

                var revisions = new FilteredElementCollector(doc)
                                .OfCategory(BuiltInCategory.OST_Revisions)
                                .WhereElementIsNotElementType()
                                .Select(x => new RevisionItem(x))
                                .ToDictionary(key => key.UniqueId, value => value);

                var finalList = new List <SheetItem>();
                foreach (var ms in sheetsData.Sheets)
                {
                    if (sheets.ContainsKey(ms.UniqueId))
                    {
                        // sheet still exists in our model
                        // we can update it
                        var localSheet = sheets[ms.UniqueId];
                        localSheet.Tasks        = ms.Tasks;        // preserve mongo tasks
                        localSheet.Id           = ms.Id;           // preserve mongoIds
                        localSheet.CollectionId = ms.CollectionId; // preserve mongoIds

                        finalList.Add(localSheet);
                        sheets.Remove(ms.UniqueId);
                    }
                    else
                    {
                        // TODO: Something about this is not right. When a new sheet is added from the web interface, then approved in Revit and synched
                        var task = ms.Tasks.LastOrDefault();
                        if (task != null && task.IsNewSheet)
                        {
                            finalList.Add(ms); // this already has the ids
                        }
                        else
                        {
                            // sheet was deleted locally but still exists in mongo
                            ms.IsDeleted = true;
                            finalList.Add(ms);
                        }
                    }
                }
                finalList.AddRange(sheets.Values); // add whatever was not stored in mongo before

                var data = new SheetData
                {
                    CentralPath = centralPath.ToLower(),
                    Sheets      = finalList,
                    Revisions   = revisions.Values.ToList(),
                    Id          = sheetsData.Id
                };

                if (!ServerUtilities.Post(data, "sheets/" + sheetsData.Id,
                                          out SheetData unused))
                {
                    Log.AppendLog(LogMessageType.ERROR, "Failed to publish Sheets.");
                }

                if (MissionControlSetup.SheetsData.ContainsKey(centralPath))
                {
                    MissionControlSetup.SheetsData.Remove(centralPath);
                }
                MissionControlSetup.SheetsData.Add(centralPath, data); // store sheets record
            }
            catch (Exception e)
            {
                Log.AppendLog(LogMessageType.EXCEPTION, e.Message);
            }
        }