Hooks doc-opened

So I’ve created this simple hook that ensures that filename is correctly populated in a specific projectparameter.

If it’s not a projectfile of our firm: do nothing.

All works but hooks keeps opening a popup screen with the title when for example I load 3 items from 3 different files which is weird to me as I’m not printing anything.

I’m thinking:

  • my load family from projectfile
  • gets job to load x families in y revitfiles.
  • opens x1 in background from y1 revitfile
  • hook pops up: prints family name
  • opens x2 in backgorund from y2 revitfile
  • hook pops up: prints family name.

Q1: is hook doc-opened always activated eventhough I exit the script if N/A?

def clean_filename(file_path):
    filename = os.path.basename(file_path)  # Extract filename
    filename_no_ext = os.path.splitext(filename)[0]  # Remove extension
    
    # Only remove the last _part IF it's NOT _rXX (e.g., _r25)
    cleaned_name = re.sub(r"_(?!r\d+$)[^_]+$", "", filename_no_ext)
    
    return cleaned_name + ".rvt"  # Add back the .rvt extension

def starts_with_four_digits(s):
    return re.match(r'^\d{4}', s) is not None

def checkfilename():
    if not HOST_APP.is_newer_than(2021):
        script.exit()
    if revit.doc.IsFamilyDocument:
        script.exit()
    try:
        ProjectInformations = DB.FilteredElementCollector(revit.doc).OfCategory(DB.BuiltInCategory.OST_ProjectInformation)

        for pi in ProjectInformations:
            current_pi = pi
        s_blad_bestandsnaam = current_pi.LookupParameter("s_blad_bestandsnaam")
        
        if not s_blad_bestandsnaam:
            script.exit()
        
        bestandsnaam_huidig = s_blad_bestandsnaam.AsString()   
        bestandsnaam = clean_filename(revit.doc.PathName)

        if not starts_with_four_digits(bestandsnaam):
            script.exit()
       
        if bestandsnaam_huidig == bestandsnaam:
            script.exit()
        
        with revit.Transaction("s_blad_bestandsnaam aanpassen"):
            s_blad_bestandsnaam.Set(bestandsnaam)
            alert("Je gebruikt \"{}\" als bestandsnaam terwijl je bestandsnaam \"{}\" is. \n\n Dit wordt nu aangepast.".format(bestandsnaam_huidig, bestandsnaam))
    except:
        pass

checkfilename()

Q2: why isn’t it printing in the original print popup?
(I don’t want to see hooks at all as it’s not a projectfile so it shouldn’t be active at all)

Probably catching the document in a weird state.

hooks should use the following to access safely the Document being loaded:

from pyrevit import EXEC_PARAMS
doc = EXEC_PARAMS.event_args.Document

This works as expected:

import os
import re
from pyrevit.forms import alert
from pyrevit import script, revit, DB, HOST_APP
from pyrevit import EXEC_PARAMS

# event arguments
EXEC_PARAMS.event_args

doc = EXEC_PARAMS.event_args.Document


def clean_filename(file_path):
    filename = os.path.basename(file_path)  # Extract filename
    filename_no_ext = os.path.splitext(filename)[0]  # Remove extension

    # Only remove the last _part IF it's NOT _rXX (e.g., _r25)
    cleaned_name = re.sub(r"_(?!r\d+$)[^_]+$", "", filename_no_ext)

    return cleaned_name + ".rvt"  # Add back the .rvt extension


def starts_with_four_digits(s):
    return re.match(r"^\d{4}", s) is not None


def checkfilename():
    if not HOST_APP.is_newer_than(2021):
        print("This script requires Revit 2022 or newer.")
        script.exit()
    if doc.IsFamilyDocument:
        print("This script does not run in family documents.")
        script.exit()
    try:
        ProjectInformations = DB.FilteredElementCollector(revit.doc).OfCategory(
            DB.BuiltInCategory.OST_ProjectInformation
        )

        for pi in ProjectInformations:
            current_pi = pi
        s_blad_bestandsnaam = current_pi.LookupParameter("Titree")

        if not s_blad_bestandsnaam:
            print("Parameter 'Titree' not found in Project Information.")
            script.exit()

        bestandsnaam_huidig = s_blad_bestandsnaam.AsString()
        bestandsnaam = clean_filename(revit.doc.PathName)

        if not starts_with_four_digits(bestandsnaam):
            alert(
                'The filename "{}" does not start with 4 digits. \n\n This is a requirement.'.format(
                    bestandsnaam
                ))
            script.exit()

        if bestandsnaam_huidig == bestandsnaam:
            alert(
                'You are using "{}" as the filename while your filename is "{}". \n\n This will now be adjusted.'.format(
                    bestandsnaam_huidig, bestandsnaam
                )
            )
            script.exit()

        with revit.Transaction("s_blad_bestandsnaam aanpassen"):
            s_blad_bestandsnaam.Set(bestandsnaam)
            alert(
                'Je gebruikt "{}" als bestandsnaam terwijl je bestandsnaam "{}" is. \n\n Dit wordt nu aangepast.'.format(
                    bestandsnaam_huidig, bestandsnaam
                )
            )
    except:
        pass


checkfilename()
1 Like

My first guess was that the alert() method wasn’t catching up with the event, but after seeing your declaration of the document, I thought about EXEC PARAMS

Hmmm still the double popups.

import os
import re
from pyrevit.forms import alert
from pyrevit import revit, DB, HOST_APP, script
from pyrevit import EXEC_PARAMS

# event arguments
EXEC_PARAMS.event_args
doc = EXEC_PARAMS.event_args.Document

def clean_filename(file_path):
    filename = os.path.basename(file_path)  # Extract filename
    filename_no_ext = os.path.splitext(filename)[0]  # Remove extension
    
    # Only remove the last _part IF it's NOT _rXX (e.g., _r25)
    cleaned_name = re.sub(r"_(?!r\d+$)[^_]+$", "", filename_no_ext)
    
    return cleaned_name + ".rvt"  # Add back the .rvt extension

def starts_with_four_digits(s):
    return re.match(r'^\d{4}', s) is not None

def checkfilename():
    if not HOST_APP.is_newer_than(2021):
        script.exit()
    if doc.IsFamilyDocument:
        script.exit()
    try:
        ProjectInformations = DB.FilteredElementCollector(revit.doc).OfCategory(DB.BuiltInCategory.OST_ProjectInformation)

        for pi in ProjectInformations:
            current_pi = pi
        s_blad_bestandsnaam = current_pi.LookupParameter("s_blad_bestandsnaam")
        
        if not s_blad_bestandsnaam:
            script.exit()
        
        bestandsnaam_huidig = s_blad_bestandsnaam.AsString()   
        bestandsnaam = clean_filename(revit.doc.PathName)

        if not starts_with_four_digits(bestandsnaam):
            script.exit()
        # print revit.doc.PathName
        # print bestandsnaam_huidig
        # print bestandsnaam
        if bestandsnaam_huidig == bestandsnaam:
            script.exit()
        
        with revit.Transaction("s_blad_bestandsnaam aanpassen"):
            s_blad_bestandsnaam.Set(bestandsnaam)
            alert("Je gebruikt \"{}\" als bestandsnaam terwijl je bestandsnaam \"{}\" is. \n\n Dit wordt nu aangepast.".format(bestandsnaam_huidig, bestandsnaam))
    except:
        pass

checkfilename()

Food for thoughts
Could it be related to the load family script (and not to hooks?)
Below part of the load script.

  print "geladen uit: {}".format(bieb) #shown in original popup output window
                    for res in items:                            
                        doc2 = HOST_APP.app.OpenDocumentFile(bieb_path_n_file)                    
                        
                        #targetDoc = forms.select_open_docs()                        
                        
                        fam = doc2.GetElement(DB.ElementId(res.id))   
                        # print fam                 
                        try:
                            doc3 = doc2.EditFamily(fam)
                            with revit.Transaction("a", doc3):
                                #ParameterType is absolete in 2021 onward.
                                if HOST_APP.is_newer_than(2021):                           
                                    settempparam = doc3.FamilyManager.AddParameter("JM_random_parameter", DB.GroupTypeId.IdentityData, DB.SpecTypeId.String.Text, False)
                                else:
                                    settempparam = doc3.FamilyManager.AddParameter("JM_random_parameter", DB.BuiltInParameterGroup.PG_IDENTITY_DATA, DB.ParameterType.Text, False)
                            with revit.Transaction("a", doc3):
                                doc3.FamilyManager.RemoveParameter(settempparam)
                            doc3.LoadFamily(activedoc, FamilyOption())
                            doc3.Close(False)
                            print "\t{}".format(res.naam) #shown in NEW popup output window
                        except:

most possible, that, or another hook kicking in

missing a bit of context to fully understand where the issue can come from./

So I am finally understanding what goes ‘wrong’.

Let me explain it better (now I understand the cause).

I have a hook that checks a file name.

  1. I run a script
  2. script print ‘running script started’
  3. output window popup showing ‘running script started’.
  4. Script opens projectfile in the background
  5. script print ‘loaded from file …’
  6. NEW output window popup showing ‘loaded from file ….’
  7. Script opens another projectfile in the background
  8. script print ‘loaded from file …’
  9. ANOTHER output window popup showing ‘loaded from file ….’

What python does:

The popup has an OutputId which is set tot the pyRevit command it belongs to.
source: pyrevitlib/pyrevit/output__init__.py/def output_id(self)

So

  1. popup = script id.

  2. popup = hook check_file_name is probably seen as new pyrevit command thus new popup

  3. popup = hook check_file_name is probably seen as new pyrevit command thus new popup

This is what I think is happening.

Unsure if it’s logical to have hooks labelled as pyrevit commands.

Your thoughts?