Skip to content

Instantly share code, notes, and snippets.

@simonmcconnell
Created July 9, 2018 00:30
Show Gist options
  • Save simonmcconnell/590cd08781df897711c349f7225dc482 to your computer and use it in GitHub Desktop.
Save simonmcconnell/590cd08781df897711c349f7225dc482 to your computer and use it in GitHub Desktop.
Update pages for project and all includes
# it was discovered that Citect was not updating all the projects when running "Update project and all included projects"
import win32api
import time
import win32com.client as wc
from pywintypes import com_error
RUN_PROJECT = 'MNM_RUN'.upper()
SYSTEM_PROJECTS = {x.upper() for x in {
'SxW_Style_Include',
'Example',
'Library_Controls',
'Tab_Style_Include',
}}
class Project:
def __init__(self, name):
self.name = name
self.include_projects = self.includes()
def __str__(self):
return self.name
def __repr__(self):
return f"Project({self.name!r})"
def __lt__(self, other):
return self.name < other.name
def wait_for_selection(self):
gb.ProjectSelect(self.name)
while gb.ProjectSelected().upper() != self.name.upper():
time.sleep(0.2)
def includes(self) -> set:
self.include_projects = set()
self.wait_for_selection()
print(f'Getting include projects for {self.name}')
try:
first_include = gb.ProjectFirstInclude().upper()
if first_include not in SYSTEM_PROJECTS:
self.include_projects.add(first_include)
print(f'added first include: {first_include}')
except com_error as e:
# hex(x & 0xffffffff) to get the hex representation
print(win32api.FormatMessage(e.excepinfo[5]))
return self.include_projects # no includes, this is the end of the line
except:
print("undefined error in <includes>, probably not connected any more, i.e. RPC error")
# TODO: handle the RPC error when no automation interface present
return self.include_projects # probably not connected anymore
while True:
try:
next_include = gb.ProjectNextInclude().upper()
# print(f"project {project}, include {next_include}")
if next_include not in SYSTEM_PROJECTS:
self.include_projects.add(next_include)
print(f'added {next_include}')
except com_error as e:
# should return Operation Aborted if there are no more projects
print(win32api.FormatMessage(e.excepinfo[5]))
return self.include_projects
def update_pages(self, fast_update=False, pack_libraries=False):
self.wait_for_selection()
if pack_libraries:
print(f"Packing libraries for {self.name}...")
try:
gb.ProjectPackLibraries()
except com_error as e:
print(f"Failed to pack libraries with error {hex(e.excepinfo[5] & 0xffffffff)} "
f"{win32api.FormatMessage(e.excepinfo[5])}")
try:
print(f"Updating pages for {self.name}...")
gb.ProjectUpdatePages(fast_update)
except com_error as e:
print(f"Failed to update pages with error {hex(e.excepinfo[5] & 0xffffffff)} "
f"{win32api.FormatMessage(e.excepinfo[5])}")
def compile(self):
self.wait_for_selection()
return gb.ProjectCompile()
if __name__ == "__main__":
gb = wc.Dispatch("GraphicsBuilder.Application.6.1")
gb.ProjectSelect(RUN_PROJECT)
checked_projects = set()
run_project = Project(RUN_PROJECT)
projects_to_check = {run_project.name}
projects = set()
while projects_to_check:
p = Project(projects_to_check.pop())
projects.add(p)
projects_to_check.update(p.include_projects - checked_projects)
checked_projects.add(p.name)
while projects:
deepest_children = [p for p in projects if not p.include_projects]
for deepest_child in deepest_children:
deepest_child.update_pages()
projects.discard(deepest_child)
for project in projects:
project.include_projects.discard(deepest_child.name)
print(f"Compiling {run_project.name}")
run_project.compile()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment