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()

Reply via email to