Asking extension users to reload pyrevit on file change?

I’ve got a basic system that is supposed to inform my colleagues that a script has been updated.
I do this by using a smartbutton that does a version check on revit startup/pyrevit reload.
If there’s a new version, the icon of my ‘info’ button changes color, informing them of a change.
(I like the idea of unintrusive updates notes)

Now, this is ofcourse only usefull for when pyrevit loads. And though that’s fine in some cases. it poses a problem when I’ve implemented library changes, since some modules will need to be reloaded.

Now, I’d like for that smartbutton to be updated as soon as I release my update.
If I release an update during a revit session, that smartbutton should be ‘reloaded’ specifically.
Any thoughs? Suggestions?
Should I be using hooks? How do I reinitialize a specific button?

using a bat file in the startup folder would get people updated whenever windows starts
%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup
I have seen that used in revitron and @davidvadkerti tools as well.
Revitron is your best bet
his bat file points to this

import os
from rpm import config
from rpm.system.ui import UI
from rpm.system.update import Update
from pyrevit.coreutils.ribbon import ICON_LARGE
from pyrevit.coreutils.ribbon import get_current_ui
from pyrevit import EXEC_PARAMS
from pyrevit import script
from _winreg import EnumValue, OpenKey, HKEY_CURRENT_USER, KEY_READ

__context__ = 'zero-doc'

template = r"""
@echo off

set pwd=%CD%
set pyrevit={}
set extensions={}
set log="C:\temp\pyRevitUpdate.log"

echo %DATE% >%log% 2>&1
echo %TIME% >>%log% 2>&1

call :pull %pyrevit% >>%log% 2>&1

cd "%extensions%"

for /D %%d in (*) do (
	if exist "%%d\.git" (
		call :pull %extensions%\%%d >>%log% 2>&1
	)
)

cd %pwd%

goto:end

:pull
echo:
cd %1
echo %1
set "status="
for /f "delims=" %%s in ('git status --porcelain') do set status=%%s
if not "%status%" == "" (
	echo Working copy is dirty - skipping
) else (
	git pull
)
cd ..

:end
"""

def getBundleFile(name):
    return os.path.join(EXEC_PARAMS.command_path, name)

def getButton():
    tabs = get_current_ui().get_pyrevit_tabs()
    for tab in tabs:
        button = tab.find_child(EXEC_PARAMS.command_name)
        if button:
            return button
    return None

def setIcon(state):
	uibutton = getButton()
	if state:
		uibutton.set_icon(getBundleFile('on.png'), icon_size=ICON_LARGE)
	else:
		uibutton.set_icon(getBundleFile('icon.png'), icon_size=ICON_LARGE)

def getStartUpFolder():
	shellFolders = OpenKey(HKEY_CURRENT_USER, 
						'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders', 
						0, 
						KEY_READ)
	try:
		count = 0
		while True:
			name, value, type = EnumValue(shellFolders, count) 
			if name == 'Startup':
				return value
			count = count + 1
	except WindowsError:
		pass

startUpFolder = getStartUpFolder()
autoUpdateFile = os.path.join(startUpFolder, 'pyRevitUpdate.bat')

def __selfinit__(script_cmp, ui_button_cmp, __rvt__):
	if os.system('git --version') != 0:
		return False
	if os.path.isfile(autoUpdateFile):
		update_icon = script_cmp.get_bundle_file('on.png')
		ui_button_cmp.set_icon(update_icon, icon_size=ICON_LARGE)
	return True

if __name__ == '__main__':
	if os.path.isfile(autoUpdateFile):
		os.remove(autoUpdateFile)
		setIcon(False)
	else:
		f = open(autoUpdateFile, 'w')
		f.write(template.format(config.RPM_PYREVIT_DIR, config.RPM_EXTENSIONS_DIR))
		f.close()
		setIcon(True)

Thanks for the swift reply Jean-Marc,
Luckily I’ve got the updating part of the script down.
(We have a central server that hosts the extension, as soon as I write there, everyone gets the update)

In other words: people will have the latest update as soon as they launch revit.
At some point we’re going to be switching to virtual machines, at that point I’ll rework that part of the extension I think. Perhaps indeed a .bat file will do the trick nicely.

Anyway.
About the updating of that button.
So… do you think it’s possible to use a hook say… ‘doc-idle’ to change my button color using what you have shown in get button?

def updateButtonIconForVersionUpdate():
    tabs = get_current_ui().get_pyrevit_tabs()
    for tab in tabs:
        button = tab.find_child(MyCustomCommandName)
        if button:
            button.set_icon(etc..)

EDIT:
Also, does windows 10 come with git by default?

doc-idle not idea
git not by default but there are github implementation within pyrevit I guess as pyrevit updates through it.
might be somewhere there:

from pyrevit.versionmgr import updater

To get the button:

from pyrevit import script

button = script.get_button()

there is also the toggle icon method that automatically switches between on.png and off.png in the bundle

script.toggle_icon(True)
1 Like