# Relative-refs.pyw
"""A short python script for repathing xrefs in Autocad."""
import win32com.client,os, os.path, tkFileDialog
from Tkinter import *
from tkMessageBox import askokcancel
from time import sleep
# Get a COM object for Autocad
acad = win32com.client.Dispatch("AutoCAD.Application")
def repath(filename):
print 'Repathing %s...' %filename
doc = acad.Documents.Open(filename)
blocks = doc.Database.Blocks # Internally xrefs are just blocks!
xrefs = [item for item in blocks if item.IsXRef]
if xrefs:
for xref in xrefs:
old_path = xref.Path
new_path = os.path.join('..\\x-ref\\',os.path.basename(old_path))
xref.Path = new_path
print 'Old path name was %s, new path name is %s.\n' %(old_path, new_path)
try:
doc.Close(True) # Close and save
except: # Something when wrong,
doc.Close(False) # close then report it
raise
class Logger:
"""A filelike object that prints its input on the screen."""
def __init__(self, logfile=None):
"""Takes one argument, a file like object for logging."""
print 'Starting logger...'
if not logfile:
self.logfile = open('relative-refs.log','w')
else:
self.logfile = logfile
sys.stderr = self # Super cheap logging facility...
sys.stdout = self # Just redirect output to a file.
print 'Logger running...'
def write(self, line):
sys.__stdout__.write(line)
self.logfile.write(line)
def close(self):
"""The close method restores stdout and stderr to normal."""
self.logfile.close()
sys.stderr = sys.__stderr__
sys.stdout = sys.__stdout__
class Tktextfile:
"""A file like interface to the Tk text widget."""
def __init__(self, root):
"""Create a scrollable text widget to be written to."""
self.root = root
self.text = Text(root,width=40,height=20)
self.text.pack(side=LEFT, expand=True, fill=BOTH)
scrollbar = Scrollbar(root)
scrollbar.pack(side=RIGHT,fill=Y)
self.text.configure(yscrollcommand=scrollbar.set)
scrollbar.config(command=self.text.yview)
self.text.focus()
def write(self, line):
"""Write method for file like widget."""
self.text.insert(INSERT, line)
self.text.see(END)
def close(self):
"""Fake close method."""
pass
if __name__ == '__main__':
if acad.Visible:
acad.Visible = False
root = Tk()
text = Tktextfile(root)
logger = Logger(text)
dir = tkFileDialog.askdirectory()
answer = askokcancel('RePath','Re path all dwg files in ' + dir + '?')
if answer:
for dirpath, subdirs, files in os.walk(dir):
for name in files:
ext = name.split('.')[-1] or ''
# We want dwg files which are not in the x-ref directory
if ext.lower() == 'dwg' and 'x-ref' not in dirpath.lower():
drawing = os.path.join(dirpath, name)
try:
repath(drawing)
except:
print 'Unable to repath drawing %s!' %drawing
root.update()
acad.Visible = True