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 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 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 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 done(self, fail): interop.refresh() Utils.p4Logger().debug("Failed: %s" % (fail)) self.fail = fail
def update(self, position): interop.refresh() Utils.p4Logger().debug("Update: %s" % (position)) self.ui.setValue(position) self.position = position
def setTotal(self, total): interop.refresh() Utils.p4Logger().debug("Total: %s" % (total)) self.ui.setMaximum(total) pass
def setDescription(self, description, unit): interop.refresh() Utils.p4Logger().debug("Desc: %s, %s" % (description, unit)) pass
def init(self, type): interop.refresh() Utils.p4Logger().debug("Begin: %s" % (type)) self.type = type self.ui.incrementCurrent()
def syncAllChanged(self, *args): try: self.p4.run_sync("...") Utils.p4Logger().info("Got latest revisions for client") except P4Exception as e: displayErrorUI(e)
def populateFileRevisions(self, *args): self.statusBar.showMessage("") try: index = self.fileTree.selectedIndexes() except IndexError as e: Utils.p4Logger().error(e) raise if not index or not index[0].internalPointer().data: return index = index[0] try: name, filetype, time, action, change, fullname = index.internalPointer( ).data except ValueError as e: Utils.p4Logger().info(index.internalPointer().data) raise e self.getRevisionBtn.setEnabled(False) self.getLatestBtn.setEnabled(False) self.getPreviewBtn.setEnabled(False) if filetype == 'Folder': self.getRevisionBtn.setVisible(False) self.getLatestBtn.setVisible(False) self.getPreviewBtn.setVisible(False) self.isSceneFile = False self.clearRevisions() return else: self.getRevisionBtn.setVisible(True) self.getLatestBtn.setVisible(True) self.getPreviewBtn.setVisible(True) if Utils.queryFileExtension(fullname, interop.getSceneFiles()): self.getPreviewBtn.setEnabled(True) self.getPreviewBtn.setText("Preview Scene Revision") self.isSceneFile = True else: self.getPreviewBtn.setText("Preview File Revision") self.isSceneFile = False try: with self.p4.at_exception_level(P4.RAISE_ERRORS): files = self.p4.run_filelog("-l", fullname) except P4Exception as e: # TODO - Better error handling here, what if we can't connect etc #eMsg, type = parsePerforceError(e) self.statusBar.showMessage("{0} isn't on client".format( os.path.basename(fullname))) self.clearRevisions() self.getLatestBtn.setEnabled(False) self.getPreviewBtn.setEnabled(False) return self.getLatestBtn.setEnabled(True) self.getPreviewBtn.setEnabled(True) try: with self.p4.at_exception_level(P4.RAISE_ERRORS): p4FileInfo = self.p4.run_fstat(fullname) if p4FileInfo: fileInfo = p4FileInfo[0] if 'otherLock' in fileInfo: self.statusBar.showMessage( "{0} currently locked by {1}".format( os.path.basename(fullname), fileInfo['otherLock'][0])) if fileInfo['otherLock'][0].split('@')[0] != self.p4.user: self.getRevisionBtn.setEnabled(False) elif 'otherOpen' in fileInfo: self.statusBar.showMessage( "{0} currently opened by {1}".format( os.path.basename(fullname), fileInfo['otherOpen'][0])) if fileInfo['otherOpen'][0].split('@')[0] != self.p4.user: self.getRevisionBtn.setEnabled(False) else: self.statusBar.showMessage( "{0} currently opened by {1}@{2}".format( os.path.basename(fullname), self.p4.user, self.p4.client)) self.getRevisionBtn.setEnabled(True) except P4Exception: self.statusBar.showMessage("{0} is not checked out".format( os.path.basename(fullname))) self.getRevisionBtn.setEnabled(True) # Generate revision dictionary self.fileRevisions = [] if files: Utils.p4Logger().debug('filelog(%s):%s' % (fullname, files)) for revision in files[0].each_revision(): self.fileRevisions.append({ "revision": revision.rev, "action": revision.action, "date": revision.time, "desc": revision.desc, "user": revision.user, "client": revision.client }) self.tableWidget.setRowCount(len(self.fileRevisions)) # Map a file action to the path of it's UI icon actionToIcon = { 'edit': os.path.join(interop.getIconPath(), "File0440.png"), 'add': os.path.join(interop.getIconPath(), "File0242.png"), 'delete': os.path.join(interop.getIconPath(), "File0253.png"), 'move/delete': os.path.join(interop.getIconPath(), "File0253.png"), 'purge': os.path.join(interop.getIconPath(), "File0253.png") } # Populate table for i, revision in enumerate(self.fileRevisions): columns = [("#{0}".format(revision['revision']), None, False), (revision['user'], None, False), (revision['action'].capitalize(), actionToIcon.get(revision['action']), False), (revision['date'], None, False), (revision['client'], None, False), (revision['desc'], None, True)] for j, data in enumerate(columns): self.setRevisionTableColumn(i, j, *data) self.tableWidget.resizeColumnsToContents() self.tableWidget.resizeRowsToContents() self.tableWidget.horizontalHeader().setStretchLastSection(True)
def populateSubDir(self, idx=None, root="//depot"): # Overcomplicated way to figure out if idx is root or not # Would be better to check if .parent() exists and if not return the root path if idx: idxPathModel = PerforceItem.absoluteP4Path(idx) idxPathSubDirs = [idxPath.data() for idxPath in idxPathModel] idxFullPath = '/'.join(idxPathSubDirs) p4path = '/'.join([root, idxFullPath]) treeItem = idx.internalPointer() # Pop empty "None" child treeItem.popChild() else: p4path = root treeItem = self.rootItem isDepotPath = root.startswith("//depot") isClientPath = not isDepotPath clientRoot = "//{0}".format(self.p4.client) # dirpath = '/'.join([p4path,'*']) with self.p4.at_exception_level(P4.RAISE_ERRORS): fstat_args = ['-Olhp', '-Dl', '/'.join([p4path, '*'])] # if not showDeleted: # fstat_args.insert(1, '-F "^headAction=delete & ^headAction=move/delete"') p4fstat = self.p4.run_fstat(*fstat_args) files = [] folders = [] for f in p4fstat: # p4 fstat returns directory information as well if f.get('dir'): folders.append(f) else: files.append(f) for f in folders: # For some reason fstat gives us the depot path, we ~should~ be safe with a simple replace if isClientPath: f['dir'] = f['dir'].replace('//depot', clientRoot) Utils.p4Logger().debug('Dir: \t%s' % f['dir']) treeItem.appendFolderItem(f['dir']) for f in files: filepath = f['depotFile'] if isDepotPath else f['clientFile'] Utils.p4Logger().debug('File: \t%s' % filepath) # Check if this is in a pending changelist, # which gives us different fields to query if f.get('change'): if f['action'] in ['delete', 'move/delete' ] and isClientPath: continue treeItem.appendFileItem(filepath, f['type'], '', f['action'], f['workRev']) else: # Only show deleted files in depot view (for the purpose of undeleting them) if f['headAction'] in ['delete', 'move/delete' ] and isClientPath: continue treeItem.appendFileItem(filepath, f['headType'], f['headTime'], f['headAction'], f['headRev']) # Show pending changelist folders in client view # (fstat is configured to automatically add the files above if they exist in the current directory, # but if they exist in a subdir they won't be found by default) if isClientPath: # if not showDeleted: # fstat_args.insert(1, '-F "^headAction=delete & ^headAction=move/delete"') # Query pending changes (just default for now) fstat_pending_args = [ '-Or', '-F', 'change=default', '/'.join([p4path, '...']) ] p4fstat = self.p4.run_fstat(*fstat_pending_args) if p4fstat: p4fstat = p4fstat[0] Utils.p4Logger().debug( 'fstat(%s): %s' % (fstat_pending_args, p4fstat['clientFile'])) workspaceRoot = os.path.normpath( self.p4.run_info()[0]['clientRoot'].replace('\\', '/')) p4path = os.path.normpath(p4path).replace( workspaceRoot, '') p4PendingPath = os.path.normpath( p4fstat['clientFile']).replace(workspaceRoot, '') pendingPath, pendingFile = os.path.split(p4PendingPath) pendingPathSplit = pendingPath.split(os.sep) commonPrefixSplit = os.path.commonprefix( [pendingPath, p4path]).split(os.sep) uncommonDirectories = filter( lambda x: x not in commonPrefixSplit, pendingPathSplit) if uncommonDirectories: currentDir = uncommonDirectories[0] currentFolders = [ os.path.basename(f['dir']) for f in folders ] Utils.p4Logger().debug(commonPrefixSplit) Utils.p4Logger().debug(uncommonDirectories) if not currentDir in currentFolders: Utils.p4Logger().debug( 'Adding pending path folder') treeItem.appendFolderItem( os.path.join(p4path, currentDir)) Utils.p4Logger().debug('\n\n')
def populate(self, rootdir): self.rootItem = PerforceItem(None) Utils.p4Logger().debug('Populating: %s' % rootdir) self.populateSubDir(idx=None, root=rootdir)
# Only allow __init__.py based modules (in folders) to make things simpler modules = filter(lambda x: not x.endswith('.py'), modules) modules = filter(lambda x: not x.endswith('.pyc'), modules) # Get only the relative directory paths modules = [os.path.basename(x) for x in modules] for module in modules: name, mod = loadInteropModule(module, cwd) try: if not mod.validate(): continue except AttributeError as e: Utils.p4Logger().debug('%s has no validate() method, skipping' % name) continue Utils.p4Logger().info("Configuring for %s" % name) mod.setup() submodule = getattr(mod, 'interop') interop = getattr(submodule, name) break else: interop = None # interop = __import__('perforce.interop.MayaInterop', fromlist=['MayaInterop']) # print getattr(interop, 'MayaInterop') # # Import app specific utilities, maya opens scenes differently than nuke etc # # Are we in maya or nuke?