Hey guys,
I find myself batch processing a lot of files for one reason or another and
I also find myself running over similar directories over and over to do the
batch processing.
So I put together a hand UI class to help with this and I thought I would
share it.
- Drag in your directories. Right click to change it or remove and drag in
a new one.
- Right click on formats and choose a format for the files you want to
process
- Click save locations to create an appdata folder with your directories
and formats, this way you can boot the UI again and all your locations are
saved so you can run your processes again
- When you click run on selected, the tool will iterate over your selected
directories and process the files in them that you have specified with your
file format.
Please feel free to add anything you want to it, extra file formats,
different processes etc. I threw it together to help with repetitive tasks
like this and it works for me :)
Enjoy!
Cheers,
Ben
--
You received this message because you are subscribed to the Google Groups
"Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/python_inside_maya/c70793f2-8175-4d2f-b441-29169c67c1a1%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
__author__ = 'ben.hearn'
from PyQt4 import QtCore, QtGui
import sys
import os
import ast
import ntpath
class DirectoryFunctions(QtGui.QDialog):
def __init__(self):
QtGui.QDialog.__init__(self)
self.appDataDir = os.path.join(os.getenv('APPDATA'), 'CUSTOM_DIR')
global dirIn
self.dirIn = QtGui.QDialog()
self.dirIn.resize(850, 450)
self.dirIn.setWindowTitle("Port levels")
self.dirIn.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
# Master display is the table view that shows our
self.masterDisplay = QtGui.QTableWidget()
self.masterDisplay.setColumnCount(2)
self.masterDisplay.setHorizontalHeaderLabels(['Directories', 'Format'])
width = self.masterDisplay.width()
# Setting the stretch to expand with the table
self.masterDisplay.horizontalHeader().setResizeMode(0, QtGui.QHeaderView.Stretch)
self.masterDisplay.horizontalHeader().setResizeMode(1, QtGui.QHeaderView.Stretch)
self.masterDisplay.verticalHeader().hide()
# Create target layout
btnRun = QtGui.QPushButton('Run On Selected')
targetLayout = QtGui.QHBoxLayout()
targetLayout.addWidget(btnRun)
# Create appdata button layout
btnCreateAppData = QtGui.QPushButton('Save Locations')
btnRemoveDir = QtGui.QPushButton('Remove Directory')
appLayout = QtGui.QHBoxLayout()
appLayout.addWidget(btnCreateAppData)
appLayout.addWidget(btnRemoveDir)
masterLayout = QtGui.QVBoxLayout()
masterLayout.addWidget(self.masterDisplay)
masterLayout.addLayout(targetLayout)
masterLayout.addLayout(appLayout)
self.masterDisplay.setAcceptDrops(True)
self.masterDisplay.dragEnterEvent = self.dragEnterEvent
self.masterDisplay.dragMoveEvent = self.dragMoveEvent
self.masterDisplay.dropEvent = self.dropEvent
self.masterDisplay.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.masterDisplay.customContextMenuRequested.connect(self.openMenu)
btnCreateAppData.pressed.connect(self.createAppData)
btnRemoveDir.pressed.connect(self.removeDir)
btnRun.pressed.connect(self.runOnSelected)
self.dirIn.setLayout(masterLayout)
self.dirIn.show()
self.setupUI()
# ----------------------------------------------------------------------------------------------- #
""" Overidden QT drag/drop events """
def dragEnterEvent(self, event):
event.accept()
def dragMoveEvent(self, event):
event.accept()
def dropEvent(self, event):
md = event.mimeData()
if md.hasUrls():
for url in md.urls():
urlPath = str(url.path())
if urlPath.startswith('/'):
urlPath = urlPath[1:]
if not os.path.isdir(urlPath):
event.ignore()
continue
self.masterDisplay.insertRow(self.masterDisplay.rowCount())
rowNum = self.masterDisplay.rowCount()-1
item = QtGui.QTableWidgetItem(urlPath)
item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
self.masterDisplay.setItem(rowNum, 0, item)
else:
event.ignore()
event.accept()
# ----------------------------------------------------------------------------------------------- #
def openMenu(self, options=[]):
""" Opens up a QT drop down menu on your mouse position """
dirPath = None
currentRow = self.masterDisplay.currentRow()
currentColumn = self.masterDisplay.currentColumn()
if currentColumn == 0:
options = ['Choose Dir']
elif currentColumn == 1:
options = ['.txt', '.ma', '.mb', '.py']
position = QtGui.QCursor.pos()
menu = QtGui.QMenu()
for o in options:
menu.addAction(o)
action = menu.exec_(position)
if action:
actionText = action.text()
else:
return
if currentColumn == 0:
self.chooseDir()
elif currentColumn == 1:
self.addFormat(actionText)
# ----------------------------------------------------------------------------------------------- #
def chooseDir(self):
""" Allows the user to choose a new directory when you right click """
dirPath = self.openWindowsBrowser()
indices = self.masterDisplay.selectedIndexes()
if dirPath:
dirPath = self.fixPathing(dirPath)
if not os.path.isdir(dirPath):
return
for i in indices:
row = i.row()
self.createQtContent(dirPath, row, 0, True)
# ----------------------------------------------------------------------------------------------- #
def addFormat(self, formatString=''):
""" Adds the format string to the format column """
indices = self.masterDisplay.selectedIndexes()
for i in indices:
row = i.row()
column = i.column()
self.addFormatItem(row, column, formatString)
# ----------------------------------------------------------------------------------------------- #
def addFormatItem(self, row, column, exportFormat):
formatItem = QtGui.QTableWidgetItem(exportFormat)
formatItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
self.masterDisplay.setItem(row, column, formatItem)
# ----------------------------------------------------------------------------------------------- #
def openWindowsBrowser(self):
dirPath = QtGui.QFileDialog.getExistingDirectory(None, 'Select Directory')
return dirPath
# ----------------------------------------------------------------------------------------------- #
def createAppData(self):
""" We create an appdata file in this function to store the source level directories and export location """
appDataFile = os.path.join(self.appDataDir, 'custom_dirs.txt')
appDataDict = {}
for r in range(self.masterDisplay.rowCount()):
for c in range(self.masterDisplay.columnCount()):
if c == 0:
sourceDir = str(self.masterDisplay.item(r, c).text())
elif c == 1:
if self.masterDisplay.item(r, c) is not None:
formatString = str(self.masterDisplay.item(r, c).text())
else:
formatString = ''
appDataDict.update({sourceDir:formatString})
with open(appDataFile, 'w+') as appDataFile:
appDataFile.write(str(appDataDict))
# ----------------------------------------------------------------------------------------------- #
def setupUI(self):
""" Saves the appdata file """
appDataFile = os.path.join(self.appDataDir, 'custom_dirs.txt')
exportDirs = None
if not os.path.exists(self.appDataDir):
os.makedirs(self.appDataDir)
if not os.path.exists(appDataFile):
return
else:
with open(appDataFile) as f:
for line in f:
exportDirs = line
exportDirs = ast.literal_eval(exportDirs)
if exportDirs:
for index, sourceDir in enumerate(exportDirs):
self.masterDisplay.insertRow(index)
self.createQtContent(sourceDir, index, 0, False)
self.createQtContent(exportDirs[sourceDir], index, 1, True)
# ----------------------------------------------------------------------------------------------- #
def createQtContent(self, content, row, column, selectable=False):
""" Creates a QTableWidgetItem """
item = QtGui.QTableWidgetItem(content)
item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
self.masterDisplay.setItem(row, column, item)
# ----------------------------------------------------------------------------------------------- #
def fixPathing(self, filePath):
""" Replaces pathing slashes """
return filePath.replace('\\', '/')
# ----------------------------------------------------------------------------------------------- #
def removeDir(self):
""" Removes the directory from the UI and saves the file """
indices = self.masterDisplay.selectedIndexes()
for i in indices:
column = i.column()
row = i.row()
if column == 0:
rowCount = self.masterDisplay.rowCount()
if row == rowCount:
row = row-1
self.masterDisplay.removeRow(row)
continue
item = QtGui.QTableWidgetItem('')
item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
self.masterDisplay.setItem(row, 1, item)
self.createAppData()
# ----------------------------------------------------------------------------------------------- #
def runOnSelected(self):
""" Runs over the selected directories """
exportDirectories = []
indices = self.masterDisplay.selectedIndexes()
if len(indices) < 1:
QtGui.QMessageBox.information(self.masterDisplay, 'Info','Please select an item to export')
return
for i in indices:
row = i.row()
sourceDir = self.masterDisplay.item(row, 0)
formatString = self.masterDisplay.item(row, 1)
if sourceDir is None or formatString is None or sourceDir == '' or formatString == '':
QtGui.QMessageBox.information(self.masterDisplay, 'Info','Cannot run without a source dir or format')
return
sourceDir = str(sourceDir.text())
formatString = str(formatString.text())
for root, dir, files in os.walk(sourceDir):
for f in files:
if os.path.splitext(f)[-1] == formatString:
# Do something here
print f
print 'DONE!'
def run():
app = QtGui.QApplication(sys.argv)
ex = DirectoryFunctions()
sys.exit(app.exec_())
run()