Family Quick Check For Corrupt Families

Hello
here is an example with IFailuresPreprocessor, to be improved if necessary

import clr
import sys
import System
from System.Collections.Generic import List, IList, Dictionary

clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *

clr.AddReference('RevitAPIUI')
from Autodesk.Revit.UI import *
from Autodesk.Revit.UI.Events import ViewActivatedEventArgs, ViewActivatingEventArgs, DialogBoxShowingEventArgs 

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

projDoc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = DocumentManager.Instance.CurrentUIApplication.Application

pf_path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86)
sys.path.append(pf_path + '\\IronPython 2.7\\Lib')

class FailureAdvancedHandler(IFailuresPreprocessor):
	# create a dictionnary to store families with warnings
	dict_Warning = Dictionary[System.String, List[System.String]]()
	def __init__(self, famDoc):
		self._famDoc = famDoc
		
	def PreprocessFailures(self, failuresAccessor):
		failMessages = failuresAccessor.GetFailureMessages()
		if failMessages.Count == 0:
			return FailureProcessingResult.Continue
		transName = failuresAccessor.GetTransactionName()
		try:
			self.__class__.dict_Warning.Add(self._famDoc.Title, List[System.String]([m.GetDescriptionText() for m in failMessages]))
			# if alert is an warn remove it 
			if failuresAccessor.GetSeverity() == FailureSeverity.Warning:
				for currentMessage in failMessages:	
					failuresAccessor.DeleteWarning(currentMessage)  
				return FailureProcessingResult.Continue
			# if alert is an error resolve it (by delete elements or by split group etc...)       
			elif failuresAccessor.GetSeverity() == FailureSeverity.Error:
				for currentMessage in failMessages:
					failuresAccessor.ResolveFailure(currentMessage)
				return FailureProcessingResult.ProceedWithCommit
			else:
				pass
		except Exception as e:
			import traceback
			errors.append(traceback.format_exc())
		return FailureProcessingResult.Continue

toList = lambda x : x if hasattr(x, '__iter__') and not isinstance(x, (str, System.String)) else [x]
lstfamiliesPath = toList(IN[0])
errors = []
dict_warnings = None
dict_corrupted = Dictionary[System.String, System.String]()
for familyPath in lstfamiliesPath:
	try:
		famDoc = app.OpenDocumentFile(familyPath)
		TransactionManager.Instance.ForceCloseTransaction()
		t = Transaction(famDoc, 'Test')
		t.Start()
		failureOptions = t.GetFailureHandlingOptions()
		handler = FailureAdvancedHandler(famDoc)
		failureOptions.SetFailuresPreprocessor(handler)
		t.SetFailureHandlingOptions(failureOptions)
		if famDoc.IsFamilyDocument:
			famManager = famDoc.FamilyManager
			for familyType in famManager.Types:
				famManager.CurrentType = familyType
				famDoc.Regenerate() 
	except Exception as e:
		import traceback
		error = traceback.format_exc()
		fileName = System.IO.Path.GetFileNameWithoutExtension(familyPath)
		dict_corrupted.Add(fileName, error)
	else:
		t.Commit()
		t.Dispose()
		famDoc.Close(False)
		famDoc.Dispose()

dict_warnings = FailureAdvancedHandler.dict_Warning

OUT = dict_corrupted, dict_warnings
3 Likes