def close(self): # @ToDo this stll seems to be maya specific try: self.revisionUi.deleteLater() except Exception as e: print "Error cleaning up P4 revision UI : ", e try: self.openedUi.deleteLater() except Exception as e: print "Error cleaning up P4 opened UI : ", e # try: # # Deleting maya menus is bad, but this is a dumb way of error checking # if "PerforceMenu" in self.perforceMenu: # interop.closeWindow(self.perforceMenu) # else: # raise RuntimeError("Menu name doesn't seem to belong to Perforce, not deleting") # except Exception as e: # print "Error cleaning up P4 menu : ", e try: self.submitUI.deleteLater() except Exception as e: print "Error cleaning up P4 submit UI : ", e Utils.p4Logger().info("Disconnecting from server") try: self.p4.disconnect() except Exception as e: print "Error disconnecting P4 daemon : ", e
def validateConnected(self, function, *args): with self.p4.at_exception_level(P4.RAISE_ERRORS): try: result = self.p4.run_login('-s') except P4Exception as e: Utils.p4Logger().info( 'Connected to server, but no login session. Disconnecting and attempting to login again.' ) with self.p4.at_exception_level(P4.RAISE_NONE): self.p4.disconnect() if not self.p4.connected(): # QtWidgets.QMessageBox.critical(None, 'Perforce Error', "Not connected to Perforce server, please connect first.", QtWidgets.QMessageBox.Warning) self.connectToServer(args) else: # A little heavy handed, but forces the cwd to the client root even if we have a valid login ticket self.p4.cwd = self.p4.run_info()[0]['clientRoot'].replace( '\\', '/') if not self.p4.connected(): QtWidgets.QMessageBox.critical( None, 'Perforce Error', "Can't connect to server, check 'p4 set' for more information about what could be wrong", QtWidgets.QMessageBox.Warning) else: function(args)
def outputInfo(self, info): interop.refresh() Utils.p4Logger().debug("INFO: %s" % (info)) if self.shouldCancel: return OutputHandler.REPORT | OutputHandler.CANCEL else: return OutputHandler.HANDLED
def createWorkspace(self, *args): workspaceRoot = None # @ToDo remove this, it's badly written right now. # Safer to use P4V for the initial setup to rewrite this to be more reliable # Give the artist 3 chances to choose a folder (assuming they choose a bad path) tries = 3 i = 0 while i < tries: workspaceRoot = QtWidgets.QFileDialog.getExistingDirectory( interop.main_parent_window(), "Specify workspace root folder") i += 1 if workspaceRoot: break else: raise IOError("Can't set workspace") try: workspaceSuffixDialog = QtWidgets.QInputDialog workspaceSuffix = workspaceSuffixDialog.getText( interop.main_parent_window(), "Workspace", "Optional Name Suffix (e.g. Uni, Home):") Utils.createWorkspace(self.p4, workspaceRoot, str(workspaceSuffix[0])) Utils.writeToP4Config(self.p4.p4config_file, "P4CLIENT", self.p4.client) except P4Exception as e: displayErrorUI(e)
def syncFile(self, *args): try: self.p4.run_sync("-f", interop.getCurrentSceneFile()) Utils.p4Logger().info("Got latest revision for {0}".format( interop.getCurrentSceneFile())) except P4Exception as e: displayErrorUI(e)
def onRevertToSelection(self, *args): index = self.tableWidget.rowCount() - 1 item = self.fileRevisions[index] currentRevision = item['revision'] index = self.tableWidget.currentRow() item = self.fileRevisions[index] rollbackRevision = item['revision'] data = self.getSelectedTreeItemData() if not data: return # Full path is stored in the final column filePath = data[-1] Utils.p4Logger().debug(filePath) desc = "Rollback #{0} to #{1}".format(currentRevision, rollbackRevision) if CmdsChangelist.syncPreviousRevision(self.p4, filePath, rollbackRevision, desc): QtWidgets.QMessageBox.information(interop.main_parent_window(), "Success", "Successful {0}".format(desc)) self.populateFileRevisions()
def getPreview(self, *args): index = self.tableWidget.currentRow() item = self.fileRevisions[index] revision = item['revision'] data = self.getSelectedTreeItemData() if not data: return # Full path is stored in the final column filePath = data[-1] fileName = data[0] path = os.path.join(interop.getTempPath(), fileName) try: tmpPath = path self.p4.run_print("-o", tmpPath, "{0}#{1}".format(filePath, revision)) Utils.p4Logger().info( "Synced preview to {0} at revision {1}".format( tmpPath, revision)) if self.isSceneFile: interop.openScene(tmpPath) else: Utils.open_file(tmpPath) except P4Exception as e: displayErrorUI(e)
def outputMessage(self, msg): interop.refresh() Utils.p4Logger().debug("Msg: %s" % (msg)) if self.shouldCancel: return OutputHandler.REPORT | OutputHandler.CANCEL else: return OutputHandler.HANDLED
def incrementCurrent(self): self.currentFile += 1 self.overallProgressBar.setValue(self.currentFile) Utils.p4Logger().debug('%s, %s' % (self.totalFiles, self.currentFile)) if self.currentFile >= self.totalFiles: self.setComplete(True)
def createShot(self, *args): shotNameDialog = QtWidgets.QInputDialog shotName = shotNameDialog.getText(interop.main_parent_window(), "Create Shot", "Shot Name:") if not shotName[1]: return if not shotName[0]: Utils.p4Logger().warning("Empty shot name") return shotNumDialog = QtWidgets.QInputDialog shotNum = shotNumDialog.getText(interop.main_parent_window(), "Create Shot", "Shot Number:") if not shotNum[1]: return if not shotNum[0]: Utils.p4Logger().warning("Empty shot number") return shotNumberInt = -1 try: shotNumberInt = int(shotNum[0]) except ValueError as e: Utils.p4Logger().warning(e) return Utils.p4Logger().info( "Creating folder structure for shot {0}/{1} in {2}".format( shotName[0], shotNumberInt, self.p4.cwd)) dir = Utils.createShotFolders(self.p4.cwd, shotName[0], shotNumberInt) self.run_checkoutFolder(None, dir)
def outputStat(self, stat): if 'totalFileCount' in stat: self.totalFileCount = int(stat['totalFileCount']) Utils.p4Logger().debug("TOTAL FILE COUNT: %s" % (self.totalFileCount)) if 'totalFileSize' in stat: self.totalFileSize = int(stat['totalFileSize']) Utils.p4Logger().debug("TOTAL FILE SIZE: %s" % (self.totalFileSize)) if self.shouldCancel: return OutputHandler.REPORT | OutputHandler.CANCEL else: return OutputHandler.HANDLED
def onExpandedFolder(self, *args): index = args[0] treeItem = index.internalPointer() Utils.p4Logger().debug('Expanding %s...' % treeItem.data[-1]) if not index.child(0, 0).isValid(): Utils.p4Logger().debug('\tLoading empty directory') self.model.populateSubDir(index, self.root) self.fileTree.setModel(self.model) self.model.layoutChanged.emit()
def revertSelected(self, *args): index = self.tableWidget.currentRow() fileName = self.entries[index]['File'] filePath = self.entries[index]['Folder'] depotFile = os.path.join(filePath, fileName) try: Utils.p4Logger().info(self.p4.run_revert("-k", depotFile)) except P4Exception as e: displayErrorUI(e) self.updateTable()
def onSyncLatest(self, *args): data = self.getSelectedTreeItemData() if not data: return # Full path is stored in the final column filePath = data[-1] try: self.p4.run_sync("-f", filePath) Utils.p4Logger().info( "{0} synced to latest version".format(filePath)) self.populateFileRevisions() except P4Exception as e: displayErrorUI(e)
def fileRevisions(self, *args): try: self.revisionUi.deleteLater() except: pass self.revisionUi = FileRevisionWindow.FileRevisionUI(self.p4) # Delete the UI if errors occur to avoid causing winEvent and event # errors (in Maya 2014) try: self.revisionUi.create() self.revisionUi.show() except: self.revisionUi.deleteLater() Utils.p4Logger().error(traceback.format_exc())
def queryOpened(self, *args): try: self.openedUi.deleteLater() except: pass self.openedUi = OpenedFilesWindow.OpenedFilesUI() # Delete the UI if errors occur to avoid causing winEvent and event # errors (in Maya 2014) try: self.openedUi.create(self.p4) self.openedUi.show() except: self.openedUi.deleteLater() Utils.p4Logger().error(traceback.format_exc())
def initMenu(p4): global ui # try: # # cmds.deleteUI(ui.perforceMenu) # AppUtils.closeWindow(ui.perforceMenu) # except: # pass # interop.initCallbacks() try: ui = PerforceMenu.MainShelf(p4) ui.addMenu() except ValueError as e: Utils.p4Logger().critical(e)
def querySceneStatus(self, *args): try: scene = interop.getCurrentSceneFile() if not scene: Utils.p4Logger().warning("Current scene file isn't saved.") return with self.p4.at_exception_level(P4.RAISE_ERRORS): result = self.p4.run_fstat("-Oa", scene)[0] text = ''.join( ["{0} : {1}\n".format(x, result[x]) for x in result]) QtWidgets.QMessageBox.information(interop.main_parent_window(), "Scene Info", text) except P4Exception as e: displayErrorUI(e)
def createAsset(self, *args): assetNameDialog = QtWidgets.QInputDialog assetName = assetNameDialog.getText(interop.main_parent_window(), "Create Asset", "Asset Name:") if not assetName[1]: return if not assetName[0]: Utils.p4Logger().warning("Empty asset name") return Utils.p4Logger().info( "Creating folder structure for asset {0} in {1}".format( assetName[0], self.p4.cwd)) dir = Utils.createAssetFolders(self.p4.cwd, assetName[0]) self.run_checkoutFolder(None, dir)
def openSelectedFile(self, *args): index = self.tableWidget.currentRow() item = self.entries[index] fileName = item['File'] filePath = item['Folder'] depotFile = os.path.join(filePath, fileName) try: result = self.p4.run_fstat(depotFile)[0] clientFile = result['clientFile'] if Utils.queryFileExtension(depotFile, interop.getSceneFiles()): interop.openScene(clientFile) else: Utils.open_file(clientFile) except P4Exception as e: displayErrorUI(e)
def syncAll(self, *args): reply = QtWidgets.QMessageBox.warning( interop.main_parent_window(), 'Are you sure?', 'Are you sure? This will force every file to redownload and can take some time to complete.', QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No) if reply == QtWidgets.QMessageBox.No: return # progress = SubmitProgressUI(len(files)) # progress.create("Submit Progress") # callback = TestOutputAndProgress(progress) # progress.show() try: self.p4.run_sync("-f", "...") Utils.p4Logger().info("Got latest revisions for client") except P4Exception as e: displayErrorUI(e)
def setCurrentWorkspace(self, *args): workspacePath = QtWidgets.QFileDialog.getExistingDirectory( interop.main_parent_window(), "Select existing workspace") for client in self.p4.run_clients(): if workspacePath.replace("\\", "/") == client['Root'].replace("\\", "/"): root, client = os.path.split(str(workspacePath)) self.p4.client = client Utils.p4Logger().info( "Setting current client to {0}".format(client)) # REALLY make sure we save the P4CLIENT variable if platform.system() == "Linux" or platform.system( ) == "Darwin": os.environ['P4CLIENT'] = self.p4.client Utils.saveEnvironmentVariable("P4CLIENT", self.p4.client) else: self.p4.set_env('P4CLIENT', self.p4.client) Utils.writeToP4Config(self.p4.p4config_file, "P4CLIENT", self.p4.client) break else: QtWidgets.QMessageBox.warning( interop.main_parent_window(), "Perforce Error", "{0} is not a workspace root".format(workspacePath))
def firstTimeLogin(p4, enterUsername=True, enterPassword=True, parent=None, *args): username = None password = None if enterUsername: username, ok = QtWidgets.QInputDialog(None, QtCore.Qt.WindowStaysOnTopHint).getText( parent, "Enter username", "Username:"******"Invalid username") p4.user = str(username) if True or enterPassword: password, ok = QtWidgets.QInputDialog(None, QtCore.Qt.WindowStaysOnTopHint).getText( parent, "Enter password", "Password:"******"Invalid password") p4.password = str(password) # Validate SSH Login / Attempt to login try: Utils.p4Logger().info(p4.run_login("-a")) except P4Exception as e: regexKey = re.compile(ur'(?:[0-9a-fA-F]:?){40}') # regexIP = re.compile(ur'[0-9]+(?:\.[0-9]+){3}?:[0-9]{4}') errorMsg = str(e).replace('\\n', ' ') key = re.findall(regexKey, errorMsg) # ip = re.findall(regexIP, errorMsg) if key: Utils.p4Logger().info(p4.run_trust("-i", key[0])) Utils.p4Logger().info(p4.run_login("-a")) else: raise e if username: Utils.writeToP4Config(p4.p4config_file, "P4USER", str(username[0]))
def openFirstFile(selected, error): if not error: if len(selected) == 1 and Utils.queryFileExtension( selected[0], interop.getSceneFiles()): if not interop.getCurrentSceneFile() == selected[0]: result = QtWidgets.QMessageBox.question( interop.main_parent_window(), "Open Scene?", "Do you want to open the checked out scene?", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) if result == QtWidgets.QMessageBox.StandardButton.Yes: interop.openScene(selected[0])
def run_checkoutFile(self, *args): for file in args[1:]: Utils.p4Logger().info("Processing {0}...".format(file)) result = None try: # @ToDO set this up to use p4.at_exception_level result = self.p4.run_fstat(file) except P4Exception as e: pass try: if result: if 'otherLock' in result[0]: raise P4Exception( "[Warning]: {0} already locked by {1}\"".format( file, result[0]['otherLock'][0])) else: Utils.p4Logger().info(self.p4.run_edit(file)) Utils.p4Logger().info(self.p4.run_lock(file)) else: Utils.p4Logger().info(self.p4.run_add(file)) Utils.p4Logger().info(self.p4.run_lock(file)) except P4Exception as e: displayErrorUI(e)
def submitChange(self, *args): try: self.submitUI.deleteLater() except: pass self.submitUI = SubmitChangeWindow.SubmitChangeUi() # Delete the UI if errors occur to avoid causing winEvent # and event errors (in Maya 2014) try: files = self.p4.run_opened("-u", self.p4.user, "-C", self.p4.client, "...") interop.refresh() entries = [] for file in files: filePath = file['clientFile'] entry = { 'File': filePath, 'Folder': os.path.split(filePath)[0], 'Type': file['type'], 'Pending_Action': file['action'], } entries.append(entry) print "Submit Files : ", files self.submitUI.create(self.p4, entries) self.submitUI.show() except: self.submitUI.deleteLater() Utils.p4Logger().error(traceback.format_exc())
def onComplete(*args): selectedFiles = [] error = None if preCallback: preCallback(fileDialog.selectedFiles()) # Only add files if we didn't cancel if args[0] == 1: for file in fileDialog.selectedFiles(): if Utils.isPathInClientRoot(self.p4, file): try: Utils.p4Logger().info(p4command(p4args, file)) selectedFiles.append(file) except P4Exception as e: Utils.p4Logger().warning(e) error = e else: Utils.p4Logger().warning( "{0} is not in client root.".format(file)) fileDialog.deleteLater() if finishCallback: finishCallback(selectedFiles, error)
def openScene(filePath): with open(filePath) as f: Utils.p4Logger().info(f.read())
def on_submit(self): if not self.validateText(): QtWidgets.QMessageBox.warning(interop.main_parent_window(), "Submit Warning", "No valid description entered") return files = [] for i in range(self.tableWidget.rowCount()): cellWidget = self.tableWidget.cellWidget(i, 0) if cellWidget.findChild( QtWidgets.QCheckBox).checkState() == QtCore.Qt.Checked: files.append(self.fileList[i]['File']) keepCheckedOut = self.chkboxLockedWidget.checkState() progress = SubmitProgressUI(len(files)) progress.create("Submit Progress") callback = TestOutputAndProgress(progress) progress.show() # self.p4.progress = callback # self.p4.handler = callback # Remove student setting from Maya .ma files # @ToDo make this a generic callback # for submitFile in files: # if ".ma" in submitFile: # try: # pathData = self.p4.run_where(submitFile)[0] # Utils.removeStudentTag(pathData['path']) # except P4Exception as e: # print e try: CmdsChangelist.submitChange( self.p4, files, str(self.descriptionWidget.toPlainText()), callback, keepCheckedOut) if not keepCheckedOut: clientFiles = [] for file in files: try: path = self.p4.run_fstat(file)[0] clientFiles.append(path['clientFile']) except P4Exception as e: displayErrorUI(e) # Bug with windows, doesn't make files writable on submit for # some reason Utils.removeReadOnlyBit(clientFiles) self.close() except P4Exception as e: self.p4.progress = None self.p4.handler = None displayErrorUI(e) progress.close() self.p4.progress = None self.p4.handler = None
def done(self, fail): interop.refresh() Utils.p4Logger().debug("Failed: %s" % (fail)) self.fail = fail