def __init__(self, elements=None, mode=PickMode.SINGLE, parent=None, forcePublished=False, okButtonLabel='OK'): super(ElementPickerDialog, self).__init__(parent) self.selected = [] self.mainLayout = QVBoxLayout() self.buttonLayout = QHBoxLayout() self.okButton = QPushButton(okButtonLabel) self.cancelButton = QPushButton('Cancel') self.buttonLayout.insertStretch(0) self.buttonLayout.addWidget(self.cancelButton) self.buttonLayout.addWidget(self.okButton) if not elements: elements = Show.fromPk(env.getEnvironment('show')).getElements() self.elementViewerWidget = ElementViewWidget( elements, mode=mode, parent=self, forcePublished=forcePublished) self.mainLayout.addWidget(self.elementViewerWidget) self.mainLayout.addLayout(self.buttonLayout) self.setMouseTracking(True) self.setWindowTitle('Asset Browser') self.setLayout(self.mainLayout) self.makeConnections() self.resize(800, 600)
def importEl(dir, elType, name=None, sequence=None, shot=None, clipName=None, overwriteOption=0): """Imports the files in the given directory into an element's work directory. This element either already exists (based on name/elType/sequence/shot) or a new one will be made with the given parameters. Args: dir (str): Path to the directory to import files from into the element name (str): The name of the element to import to/create. elType (str): The element type of the element to import to/create. sequence (int, optional): The sequence number of the element to import to/create. Defaults to a show-level element. shot (int, optional): The shot number of the element to import to/create. Defaults to a show-level element. clipName (str, optional): The clip name of the specified shot number where the element will imported to/created in. overwriteOption (int, optional): The action to take when encountering files of the same name that already exist when importing into an already existing element. 0: DEFAULT. Duplicate files will be overwritten by the incoming source. 1: Version up. Incoming source files will be appended with a number. 2: Skip. Incoming source files will not be imported if they are duplicates. Raises: ImportError: If the specified directory does not exist or is not a directory. """ if not os.path.isdir(dir): raise ImportError('Not a directory: {}'.format(dir)) el = Element(name, elType, show=env.getEnvironment('show'), sequence=sequence, shot=shot, clipName=clipName, makeDirs=True) if not el.exists(): el.insert() fileutils.relativeCopyTree(dir, el.work_path, overwriteOption)
def __init__(self, num, show=None, author=None, makeDirs=False, dummy=False): self.table = Sequence.TABLE self.num = num self.show = show if show else env.getEnvironment('show') self._exists = None if dummy: return if num is None: raise ValueError('Sequence\'s num can\'t be None') try: self.num = int(num) except ValueError: raise ValueError( 'Sequence number must be a number, not: {}'.format(num)) if not self.show: raise ValueError( 'Tried to fallback to environment-set show, but it was null.') fetched = self.exists(fetch=True) if fetched: self.unmap(fetched) self._exists = True else: creationInfo = env.getCreationInfo(format=False) self.author = author if author else creationInfo[0] self.creation = creationInfo[1] s = Show.fromPk(self.show) if not s: raise ValueError('No such show: {}'.format(show)) else: self.work_path = os.path.join(s.work_path, self.directory) self.release_path = os.path.join(s.release_path, self.directory) p = Person(self.author) if not p.exists(): raise ValueError('No such user: {}'.format(self.author)) if makeDirs: if not os.path.isdir(self.work_path): os.makedirs(self.work_path) if not os.path.isdir(self.release_path): os.makedirs(self.release_path)
def __init__(self, show=None, sequence=None, shot=None): self.show = show if show else env.getEnvironment('show') if not self.show: raise ValueError( 'Tried to fallback to environment-set show, but it was null.') if not Show(self.show).exists(): raise ValueError('No such show: {}'.format(self.show)) self.sequence = sequence self.shot = shot
def expand(path): parts = path.split(os.path.sep) newParts = [] for p in parts: if p.startswith('$' + env.VAR_PREFIX): p = p.replace('$' + env.VAR_PREFIX, '') repl = env.getEnvironment(p) newParts.append(repl) else: newParts.append(p) return os.path.sep.join(newParts)
def __init__(self, shotId, stage, show=None, dummy=False): self.table = Stage.TABLE self.shotId = shotId self.stage = stage self._exists = False if dummy: return shot = Shot.fromPk(self.shotId) if shot is None or not shot.exists(): raise ValueError('Shot does not exist') if stage not in Stage.STAGES: raise ValueError('Invalid stage. Must be one of: {}'.format( ', '.join(Stage.STAGES))) fetched = self.exists(fetch=True) if fetched: self.unmap(fetched) self._exists = True else: self._exists = False self.show = show if show else env.getEnvironment('show') if not self.show: raise ValueError( 'Tried to fallback to environment-set show, but it was null.' ) s = Show.fromPk(self.show) if not s: raise ValueError('No such show: {}'.format(self.show)) self.status = Stage.STATUS[0] # Set to N/A to begin with self.begin_date = None self.completion_date = None self.assigned_to = None
def rmseq(seqNum, clean=False): seq = Sequence(seqNum, show=env.getEnvironment('show', silent=True)) if not seq.exists(): raise DatabaseError('Sequence {} doesn\'t exist'.format(seqNum)) shots = seq.getShots() for shot in shots: rmshot(seqNum, shot.num, clipName=shot.clipName, clean=clean) for el in seq.getElements(exclusive=True): if el.delete(clean): continue else: raise DatabaseError('Unable to delete: {}. Cannot continue deletion.'.format(el)) if not seq.delete(clean): raise DatabaseError('Unable to delete sequence') else: print 'Successfully removed sequence'
def __init__(self, elementName, elementType, filePath, versionlessFilePath, show=None, sequence=None, shot=None, comment=None, fix=None, dummy=False): self.table = PublishedFile.TABLE if dummy: return self.elementName = elementName self.elementType = elementType self.show = show if show else env.getEnvironment('show') self.elementId = None self.fixId = None self._exists = None if not self.show: raise ValueError( 'Tried to fallback to environment-set show, but it was null.') if filePath is None: raise ValueError('Must provide a file path') if versionlessFilePath is None: raise ValueError('Must provide a versionless file path') if self.elementType is None: raise ValueError( 'Must provide an element type to attach this Published File to' ) e = Element(self.elementName, self.elementType, show=self.show, sequence=sequence, shot=shot) if not e.exists(): raise ValueError( 'No such element to attach to: {} ({}) in {}{}{}'.format( e.name, e.type, e.show, ' in sequence {}'.format(e.sequence), ' in shot {}'.format(e.shot))) else: self.elementId = e.id self.version = PublishedFile.nextVersion(self.show, self.elementId) fetched = self.exists(fetch=True) if fetched: self.unmap(fetched) self._exists = True else: self._exists = False creationInfo = env.getCreationInfo(format=False) self.author = creationInfo[0] self.creation = creationInfo[1] self.comment = comment self.file_path = filePath self.versionless_path = versionlessFilePath s = Show.fromPk(self.show) p = Person(self.author) if not s: raise ValueError('No such show: {}'.format(self.show)) if not p.exists(): raise ValueError('No such user: {}'.format(self.author)) if fix: f = Fix.byNum(fix, self.show) if not f or not f.exists(): raise ValueError( 'No such fix number: {} in show {}'.format( fix, self.show)) else: self.fixId = f.id
def main(cmd, argv): if cmd == 'pop': parser = HelixArgumentParser(prog='pop', description='Pop into a specific show') parser.add_argument('showName', help='The 4-5 letter code for the show name') args = {k:v for k,v in vars(parser.parse_args(argv)).items() if v is not None} return pop(**args) elif cmd == 'mkshow': parser = HelixArgumentParser(prog='mkshow', description='Make a new show') parser.add_argument('alias', help='The alias of the show. Has character restrictions (i.e. no spaces or special characters)') parser.add_argument('resolutionX', help='The width of this show\'s resolution') parser.add_argument('resolutionY', help='The height of this show\'s resolution') parser.add_argument('fps', help='The frames per second that the show will follow') parser.add_argument('--name', '-n', help='The full name of the show. Please surround with double quotes, i.e. "My Show"') args = {k:v for k,v in vars(parser.parse_args(argv)).items() if v is not None} return mkshow(**args) elif cmd == 'rmshow': parser = HelixArgumentParser(prog='rmshow', description='Delete an existing show. Optionally also remove associated files from disk.') parser.add_argument('showName', help='The name of the show. Surround in quotes for multi-word names.') parser.add_argument('--clean', '-c', action='store_true', help='Remove associated files/directories for this show') args = {k:v for k,v in vars(parser.parse_args(argv)).items() if v is not None} return rmshow(**args) elif cmd == 'mkseq': if not env.getEnvironment('show'): print 'Please pop into a show first' return parser = HelixArgumentParser(prog='mkseq', description='Make a new sequence in the current show') parser.add_argument('seqNum', help='The number of the sequence') args = {k:v for k,v in vars(parser.parse_args(argv)).items() if v is not None} return mkseq(**args) elif cmd == 'rmseq': if not env.getEnvironment('show'): print 'Please pop into a show first' return parser = HelixArgumentParser(prog='rmseq', description='Remove an existing sequence from the current show') parser.add_argument('seqNum', help='The number of the sequence') parser.add_argument('--clean', '-c', action='store_true', help='Remove associated files/directories for this sequence') args = {k:v for k,v in vars(parser.parse_args(argv)).items() if v is not None} return rmseq(**args) elif cmd == 'mkshot': if not env.getEnvironment('show'): print 'Please pop into a show first' return parser = HelixArgumentParser(prog='mkshot', description='Make a new shot in the current show for the given sequence.') parser.add_argument('seqNum', help='The number of the sequence to make the shot in') parser.add_argument('shotNum', help='The number of the shot to make') parser.add_argument('--start', '-s', default=0, help='Start frame of the shot') parser.add_argument('--end', '-e', default=0, help='End frame of the shot') parser.add_argument('--clipName', '-c', default=None, help='The name of the clip associated with this shot') parser.add_argument('--stages', default='delivered', help='Comma-separated list of stages to initially create for the shot. The "delivered" stage is always made.') args = {k:v for k,v in vars(parser.parse_args(argv)).items() if v is not None} return mkshot(**args) elif cmd == 'rmshot': if not env.getEnvironment('show'): print 'Please pop into a show first' return parser = HelixArgumentParser(prog='rmshot', description='Remove an existing shot in the current show for the given sequence.') parser.add_argument('seqNum', help='The number of the sequence to remove the shot from') parser.add_argument('shotNum', help='The number of the shot to remove') parser.add_argument('--clipName', default=None, help='The name of the clip associated with this shot') parser.add_argument('--clean', '-c', action='store_true', help='Remove associated files/directories for this shot') args = {k:v for k,v in vars(parser.parse_args(argv)).items() if v is not None} return rmshot(**args) elif cmd == 'mke': # Command is irrelevant without the show context set if not env.getEnvironment('show'): print 'Please pop into a show first' return parser = HelixArgumentParser(prog='mke', description='Make an element (Set, Character, Prop, Effect, etc.)') parser.add_argument('elType', help='The type of element (Set, Character, Prop, Effect, etc.) to make') parser.add_argument('name', help='The name of the element that will be made (i.e. Table). Specify "-" to indicate no name (but sequence and shot must be specified)') parser.add_argument('--sequence', '-sq', default=None, help='The sequence number') parser.add_argument('--shot', '-s', default=None, help='The shot number') parser.add_argument('--clipName', '-c', default=None, help='The clip name of the shot') args = {k:v for k,v in vars(parser.parse_args(argv)).items() if v is not None} return mke(**args) elif cmd == 'clone': if not env.getEnvironment('element'): print 'Please get an element to work on first' return parser.add_argument('--show', default=None, help='The show to clone into. If not provided, clones into the current environment\'s show.') parser.add_argument('--sequence', '-sq', default=None, help='The sequence number to clone into. If not provided, will clone into the current show or the show provided.') parser.add_argument('--shot', '-s', default=None, help='The shot number to clone into. If not provided, will clone into the sequence (if provided), otherwise the show.') args = {k:v for k,v in vars(parser.parse_args(argv)).items() if v is not None} return clone(**args) elif cmd == 'rme': if not env.getEnvironment('show'): print 'Please pop into a show first' return parser = HelixArgumentParser(prog='rme', description='Remove an exisiting element') parser.add_argument('elType', help='The type of element') parser.add_argument('name', help='The name of the element') parser.add_argument('--sequence', '-sq', default=None, help='The sequence number') parser.add_argument('--shot', '-s', default=None, help='The shot number') parser.add_argument('--clipName', default=None, help='The clip name of the shot') parser.add_argument('--clean', '-c', action='store_true', help='Remove associated files/directories for this element') args = {k:v for k,v in vars(parser.parse_args(argv)).items() if v is not None} return rme(**args) elif cmd == 'get': # Command is irrelevant without the show context set if not env.getEnvironment('show'): print 'Please pop into a show first' return parser = HelixArgumentParser(prog='get', description='Get an already existing element to work on') parser.add_argument('elType', help='The type of element') parser.add_argument('name', help='The name of the element') parser.add_argument('--sequence', '-sq', default=None, help='The sequence number') parser.add_argument('--shot', '-s', default=None, help='The shot number') args = {k:v for k,v in vars(parser.parse_args(argv)).items() if v is not None} return get(**args) elif cmd == 'pub': # Cannot publish if element hasn't been retrieved to work on yet if not env.getEnvironment('element'): print 'Please get an element to work on first' return parser = HelixArgumentParser(prog='pub', description='Publish a new version of the current working element') parser.add_argument('file', help='The path to the file OR frame from a sequence OR directory to publish') parser.add_argument('--range', '-r', type=int, nargs='+', default=None, help='The number range to publish a given frame sequence with. By default will attempt to publish the largest range found.') parser.add_argument('--force', '-f', action='store_true', help='By default, frame sequences will not publish if any frames are missing within the range (specified or found). Use this flag to force the publish to occur anyway.') args = {k:v for k,v in vars(parser.parse_args(argv)).items() if v is not None} if 'range' in args: if len(args['range']) == 1: args['range'] = (args['range'], args['range']) else: args['range'] = (args['range'][0], args['range'][1]) return pub(**args) elif cmd == 'roll': if not env.getEnvironment('element'): print 'Please get an element to work on first' return parser = HelixArgumentParser(prog='roll', description='Rolls back the current element\'s published file to the previous version, or a specific one if specified.') parser.add_argument('--version', '-v', default=None, help='Specify a specific version to rollback to.') args = {k:v for k,v in vars(parser.parse_args(argv)).items() if v is not None} return roll(**args) elif cmd == 'mod': if not env.getEnvironment('element'): print 'Please get an element to work on first' return parser = HelixArgumentParser(prog='mod', description='Modify attributes regarding the current working element') parser.add_argument('attribute', help='The name of the attribute you are trying to modify (i.e. ext if you wish to change the expected extension this element produces') parser.add_argument('value', nargs='?', default=None, help='The value to set the given attribute to. Can be omitted to retrieve the current value instead') args = {k:v for k,v in vars(parser.parse_args(argv)).items() if v is not None} return mod(**args) elif cmd == 'override': if not env.getEnvironment('element'): print 'Please get an element to work on first' return parser = HelixArgumentParser(prog='override', description='Override the current element for work in a different sequence or shot. If both sequence and shot are omitted, prints the current overrides instead. By omitting shot, the element can be overridden for a sequence in general.') parser.add_argument('--sequence', '-sq', default=None, help='The sequence number to override the element into') parser.add_argument('--shot', '-s', default=None, help='The shot number to override the element into.') args = {k:v for k,v in vars(parser.parse_args(argv)).items() if v is not None} return override(**args) elif cmd == 'file': if not env.getEnvironment('element'): print 'Please get an element to work on first' return parser = HelixArgumentParser(prog='file', description='Assigns the given file path to be this element\'s work file.') parser.add_argument('path', nargs='?', default=None, help='The path to the file that should become the work file for this element') args = {k:v for k,v in vars(parser.parse_args(argv)).items() if v is not None} return createFile(**args) elif cmd == 'import': if not env.getEnvironment('show'): print 'Please pop into a show first' return parser = HelixArgumentParser(prog='import', description='Imports a directory to become a new element if it doesn\'t exist, or into an existing element.') parser.add_argument('dir', help='The full path to the directory of files associated with the element to import into or create.') parser.add_argument('elType', help='The element type of the element') parser.add_argument('--name', '-n', help='The name of the element', default=None, nargs='?') parser.add_argument('--sequence', '-sq', default=None, help='The sequence number of the element') parser.add_argument('--shot', '-s', default=None, help='The shot number of the element') parser.add_argument('--clipName', '-c', default=None, help='The clip name of the element\'s shot') parser.add_argument('--overwriteOption', '-o', default=0, type=int, choices=[0, 1, 2], help='When encountering duplicate files on import for an element that already exists, 0 will overwrite, 1 will version up the incoming file, and 2 will skip the file.') args = {k:v for k,v in vars(parser.parse_args(argv)).items() if v is not None} return importEl(**args) elif cmd == 'export': parser = HelixArgumentParser(prog='import', description='Imports a directory to become a new element if it doesn\'t exist, or into an existing element.') parser.add_argument('dir', help='The full path to the directory where the exported element should be placed.') parser.add_argument('show', help='The element\'s show') parser.add_argument('elType', default=None, help='The name of the element to export. Will be considered a nameless element if this flag is excluded.') parser.add_argument('--name', '-n', default=None, help='The name of the element to export. Will be considered a nameless element if this flag is excluded.') parser.add_argument('--sequence', '-sq', default=None, help='The sequence number of the element') parser.add_argument('--shot', '-s', default=None, help='The shot number of the element') parser.add_argument('--clipName', '-c', default=None, help='The clip name of the element\'s shot') parser.add_argument('--work', '-w', default=False, action='store_true', help='If included, the element\'s work tree is exported.') parser.add_argument('--release', '-r', default=None, action='store_true', help='If included, the element\'s release tree is exported.') args = {k:v for k,v in vars(parser.parse_args(argv)).items() if v is not None} return export(**args) elif cmd == 'els' or cmd == 'elements': if not env.getEnvironment('show'): print 'Please pop into a show first' return parser = HelixArgumentParser(prog='elements', description='List all elements for the current show') parser.add_argument('elType', help='A comma separated list of elements to filter by', default=None, nargs='?') parser.add_argument('--sequence', '-sq', default=None, help='The sequence number to get elements from') parser.add_argument('--shot', '-s', default=None, help='The shot number to get elements from') args = {k:v for k,v in vars(parser.parse_args(argv)).items() if v is not None} return elements(**args) elif cmd == 'shots': if not env.getEnvironment('show'): print 'Please pop into a show first' return parser = HelixArgumentParser(prog='shots', description='List all shots for the current show, given a sequence number.') parser.add_argument('seqNum', help='The sequence number') args = {k:v for k,v in vars(parser.parse_args(argv)).items() if v is not None} return shots(**args) elif cmd == 'seqs' or cmd == 'sequences': if not env.getEnvironment('show'): print 'Please pop into a show first' return parser = HelixArgumentParser(prog='sequences', description='List all sequences for the current show.') args = {k:v for k,v in vars(parser.parse_args(argv)).items() if v is not None} return sequences(**args) elif cmd == 'shows': parser = HelixArgumentParser(prog='shows', description='List all shows in this database') args = {k:v for k,v in vars(parser.parse_args(argv)).items() if v is not None} return shows(**args) elif cmd == 'pwe': element = env.getEnvironment('element') if not element: print 'Element could not be retrieved, try getting it again with "ge"' return print element elif cmd == 'help' or cmd == 'h' or cmd == '?': import helix helpFile = os.path.join(helix.root, 'docs', 'help.txt') if not os.path.exists(helpFile): print 'Helix help has not been properly configured' return with open(helpFile) as file: line = file.readline() while line: print line, line = file.readline() # Debug commands elif cmd == 'dump': parser = HelixArgumentParser(prog='dump', description='Dumps the database contents to stdout') parser.add_argument('--expanded', '-e', action='store_true', help='Whether each DatabaseObject is fully expanded in the print out') args = {k:v for k,v in vars(parser.parse_args(argv)).items() if v is not None} return dump(**args) elif cmd == 'getenv': parser = HelixArgumentParser(prog='getenv', description='Gets the custom environment variables that have been set by the Helix system') args = {k:v for k,v in vars(parser.parse_args(argv)).items() if v is not None} return getenv(**args) elif cmd == 'debug': env.DEBUG = not env.DEBUG if env.DEBUG: print 'Enabled debug mode' else: print 'Disabled debug mode' elif cmd == 'sql': parser = HelixArgumentParser(prog='sql', description='Execute a SQL statement') parser.add_argument('statement', help='The SQL statement') args = {k:v for k,v in vars(parser.parse_args(argv)).items() if v is not None} return sql(**args) elif cmd == 'initTables': return initTables() elif cmd == 'exit' or cmd == 'quit': exit() else: print 'Unknown command: {}'.format(cmd)
import sys, os, shlex, shutil, getpass, traceback import argparse import helix.environment.environment as env from helix import hxdb, Show, Sequence, Shot, Element, Stage, Snapshot from helix.api.exceptions import * from helix.environment.permissions import PermissionHandler, permissionCheck from helix.utils.fileclassification import FrameSequence import helix.utils.fileutils as fileutils dbLoc = env.getEnvironment('db') if not dbLoc: raise KeyError('Database location not set in your environment') perms = PermissionHandler() # User commands @permissionCheck('CREATE_SHOW') def mkshow(alias, resolutionX, resolutionY, fps, name=None): if Show(alias, (resolutionX, resolutionY), fps, name=name, makeDirs=True).insert(): print 'Successfully created new show' return True else: raise DatabaseError('Failed to create show. Does this alias already exist?') @permissionCheck('DELETE_SHOW') def rmshow(showName, clean=False): show = Show.fromPk(showName) if not show:
def __init__(self, shot, sequence, show=None, clipName=None, author=None, comment=None, start=None, end=None, makeDirs=False, dummy=False): self.table = Snapshot.TABLE self.show = show if show else env.getEnvironment('show') self.sequence = sequence self.shot = shot self._exists = None self.sequenceId = None self.shotId = None self.first_frame = start self.last_frame = end if dummy: return if not self.show: raise ValueError('Tried to fallback to environment-set show, but it was null.') s = Show.fromPk(self.show) if not s: raise ValueError('No such show: {}'.format(show)) if self.sequence is not None: try: self.sequence = int(self.sequence) except ValueError: raise ValueError('Sequence number must be a number, not: {}'.format(self.sequence)) sq = Sequence(self.sequence, show=self.show) if not sq.exists(): raise ValueError('No such sequence {} in show {}'.format(sq.num, sq.show)) else: self.sequenceId = sq.id if self.shot is not None and self.sequence is not None: try: self.shot = int(shot) except ValueError: raise ValueError('Shot number must be a number, not: {}'.format(shot)) sh = Shot(self.shot, self.sequence, show=self.show, clipName=clipName) if not sh.exists(): raise ValueError('No such shot {} in sequence {} in show {}'.format(sh.num, sh.sequence, sh.show)) else: self.shotId = sh.id self.first_frame = self.first_frame if self.first_frame else sh.start self.last_frame = self.last_frame if self.last_frame else sh.end self.num = Snapshot.nextSnapshotNum(self.show, self.sequenceId, self.shotId) fetched = self.exists(fetch=True) if fetched: self.unmap(fetched) self._exists = True else: creationInfo = env.getCreationInfo(format=False) self.comment = comment self.author = author if author else creationInfo[0] self.creation = creationInfo[1] self.first_frame = start self.last_frame = end p = Person(self.author) if not p.exists(): raise ValueError('No such user: {}'.format(self.author)) shotDir = Shot.fromPk(self.shotId).release_path self.file_path = os.path.join(shotDir, '.snapshots', str(self.num)) if makeDirs and not os.path.isdir(self.file_path): os.makedirs(self.file_path)
def initUI(self): self.CMB_type.addItems(Fix.TYPES) self.CMB_status.setDisabled(self.fix is None) self.CMB_status.addItems(Fix.STATUS.values()) self.CMB_priority.addItems(['{}{}'.format(k, ' (' + v + ')' if v else '') for k, v in Fix.PRIORITY.iteritems()]) self.CMB_priority.setCurrentIndex(3) self.CMB_dept.addItems(['general'] + env.cfg.departments) completionList = [u.username for u in db.getUsers()] self.assignedCompleter = QCompleter(completionList, self.LNE_assignTo) self.assignedCompleter.setCaseSensitivity(Qt.CaseInsensitive) self.assignedCompleter.setCompletionMode(QCompleter.InlineCompletion) self.LNE_assignTo.setCompleter(self.assignedCompleter) self.LNE_assignTo.textChanged.connect(self.fixerChanged) self.CMB_show.addItems([s.alias for s in db.getShows()]) self.CMB_show.setCurrentIndex(self.CMB_show.findText(env.getEnvironment('show'))) today = QDate.currentDate() self.DATE_due.setDate(today.addDays(14)) self.CHK_due.clicked.connect(self.toggleDue) self.toggleDue() self.populateSeqAndShot() if self.fix is not None: self.CMB_status.setCurrentIndex(self.CMB_status.findText(self.fix.status)) self.CMB_priority.setCurrentIndex(self.fix.priority) self.CMB_dept.setCurrentIndex(self.CMB_dept.findText(self.fix.for_dept if self.fix.for_dept else 'general')) self.LNE_assignTo.setText(self.fix.fixer if self.fix.fixer else '') self.CMB_show.setCurrentIndex(self.CMB_show.findText(self.fix.show)) self.CMB_show.setDisabled(True) self.populateSeqAndShot() if self.fix.sequence: self.CMB_seq.setCurrentIndex(self.CMB_seq.findText(str(self.fix.sequence))) self.CMB_seq.setDisabled(True) self.populateShots() if self.fix.shot: shot = Shot.fromPk(self.fix.shotId) for i, s in enumerate(self.shots): if s == shot: self.CMB_shot.setCurrentIndex(i) break self.CMB_shot.setDisabled(True) self.populateElements() if self.fix.elementId: el = Element.fromPk(self.fix.elementId) for i, e in enumerate(self.elements): if e == el: self.CMB_asset.setCurrentIndex(i) break self.CMB_asset.setDisabled(True) if self.fix.deadline: dt = utils.dbTimetoDt(self.fix.deadline) self.DATE_due.setDate(QDate(dt.year, dt.month, dt.day)) self.CHK_due.setCheckState(Qt.Checked) self.LNE_title.setText(self.fix.title) self.TXT_body.setPlainText(self.fix.body) self.LNE_title.setReadOnly(True) self.TXT_body.setReadOnly(True) for comment in reversed(self.fix.commentList): commentWidget = CommentWidget(self, comment) self.LAY_comments.addWidget(commentWidget) commentWidget.replied.connect(self.handleCommentReply) self.setWindowTitle('Fix #{} ({})'.format(self.fix.num, self.fix.show)) else: self.GRP_activity.setVisible(False) self.TXT_addComment.setVisible(False) self.resize(self.width(), 200)
def __init__(self, alias, resolution, fps, name=None, author=None, makeDirs=False, dummy=False): """Construct a new show. Based on the given parameter values, this may equate to a show that already exists in the DB, or will construct an entirely new instance. Args: alias (str): The alias (internal name) of the show resolution (tuple): The image resolution for the show fps (float): The frames per second that the show will follow name (str, optional): The long, descriptive name author (str, optional): The creator of the show, defaults to the current user makeDirs (bool, optional): Whether to make the show's directories on disk, if they don't already exist. dummy (bool, optional): Whether this is a throwaway instance or not. Dummy instances are meant to be "unmapped" into since they will have no attributes set. Raises: ValueError: If the alias specified does not meet the sanitation criteria, or if the given user (if any provided) does not exist in the database already. """ self.table = Show.TABLE if dummy: return sanitary, reasons = utils.isSanitary(alias) if not sanitary: raise ValueError('Invalid alias specified:' + '\n'.join(reasons)) self.alias = alias self._exists = None fetched = self.exists(fetch=True) if fetched: self.unmap(fetched) self._exists = True else: self._exists = False if not isinstance(resolution, tuple) or len(resolution) != 2: raise ValueError( 'Invalid resolution specified, must be a length 2 tuple representing the width and height values' ) self.resolution_x = resolution[0] self.resolution_y = resolution[1] self.fps = fps self.name = name creationInfo = env.getCreationInfo(format=False) self.author = author if author else creationInfo[0] self.creation = creationInfo[1] self.work_path = os.path.join(env.getEnvironment('work'), self.directory) self.release_path = os.path.join(env.getEnvironment('release'), self.directory) p = Person(self.author) if not p.exists(): raise ValueError('No such user: {}'.format(self.author)) if makeDirs: if not os.path.isdir(self.work_path): os.makedirs(self.work_path) if not os.path.isdir(self.release_path): os.makedirs(self.release_path)
def __init__(self, name, elType, show=None, sequence=None, shot=None, clipName=None, author=None, makeDirs=False, dummy=False): self.table = Element.TABLE if dummy: return if name is not None: sanitary, reasons = utils.isSanitary(name, maxChars=25) if not sanitary: raise ValueError('Invalid element name specified:' + '\n'.join(reasons)) self.name = name self.type = elType.lower() self.show = show if show else env.getEnvironment('show') self.sequence = sequence self.shot = shot self._exists = None self.sequenceId = None self.shotId = None if name is None: if shot is None or sequence is None: raise ValueError( 'Element\'s name can only be None (considered nameless) if shot and sequence are also specified' ) else: self.name = '_{}{}{}'.format( fileutils.SEQUENCE_FORMAT.format( str(self.sequence).zfill(env.SEQUENCE_SHOT_PADDING)), fileutils.SHOT_FORMAT.format( str(self.shot).zfill(env.SEQUENCE_SHOT_PADDING)), clipName if clipName else '') if not self.type: raise ValueError('Element\'s type can\'t be None') if self.type not in Element.ELEMENT_TYPES: raise ValueError( 'Invalid element type: {}. Must be one of: {}'.format( self.type, ', '.join(Element.ELEMENT_TYPES))) if not self.show: raise ValueError( 'Tried to fallback to environment-set show, but it was null.') fetched = self.exists(fetch=True) if fetched: self.unmap(fetched) self._exists = True else: creationInfo = env.getCreationInfo(format=False) self.author = author if author else creationInfo[0] self.creation = creationInfo[1] self.status = Element.STATUS[0] self.assigned_to = None self.pubVersion = 0 self.version = 1 self.thumbnail = None self.shot_clipName = clipName s = Show.fromPk(self.show) if not s: raise ValueError('No such show: {}'.format(show)) p = Person(self.author) if not p.exists(): raise ValueError('No such user: {}'.format(self.author)) baseWorkDir = s.work_path baseReleaseDir = s.release_path if self.sequence is not None: try: self.sequence = int(self.sequence) except ValueError: raise ValueError( 'Sequence number must be a number, not: {}'.format( self.sequence)) sq = Sequence(self.sequence, show=self.show) if not sq.exists(): raise ValueError('No such sequence {} in show {}'.format( sq.num, sq.show)) else: self.sequenceId = sq.id baseWorkDir = sq.work_path baseReleaseDir = sq.release_path if self.shot is not None and self.sequence is not None: try: self.shot = int(shot) except ValueError: raise ValueError( 'Shot number must be a number, not: {}'.format(shot)) sh = Shot(self.shot, self.sequence, show=self.show, clipName=self.shot_clipName) if not sh.exists(): raise ValueError( 'No such shot {} in sequence {} in show {}'.format( sh.num, sh.sequence, sh.show)) else: self.shotId = sh.id baseWorkDir = sh.work_path baseReleaseDir = sh.release_path self.work_path = os.path.join(baseWorkDir, self.directory) self.release_path = os.path.join(baseReleaseDir, self.directory) if makeDirs: if not os.path.isdir(self.work_path): os.makedirs(self.work_path) if not os.path.isdir(self.release_path): os.makedirs(self.release_path)
def __init__(self, fixType, title, body, dept, show=None, sequence=None, shot=None, clipName=None, elementName=None, elementType=None, author=None, status=STATUS[0], priority=3, dummy=False): self.table = Fix.TABLE self.commentList = [] if dummy: return self.title = title self.body = body self.show = show if show else env.getEnvironment('show') self.sequence = sequence self.shot = shot self.elementName = elementName self.elementType = elementType self._exists = None self.sequenceId = None self.shotId = None self.elementId = None if not title: raise ValueError('Must specify a fix title') if not body: raise ValueError( 'Must specify details for the fix in the body text') if not self.show: raise ValueError( 'Tried to fallback to environment-set show, but it was null.') fetched = self.exists(fetch=True) if fetched: self.unmap(fetched) self._exists = True else: creationInfo = env.getCreationInfo(format=False) self.type = fixType.lower() self.author = author if author else creationInfo[0] self.creation = creationInfo[1] self.status = status if status in Fix.STATUS.values( ) else Fix.STATUS[0] self.priority = priority if priority in Fix.PRIORITY.keys() else 3 self.fixer = None self.fix_date = None self.deadline = None self.assign_date = None self.num = Fix.nextFixNum(self.show) self.for_dept = dept.lower() if self.type not in Fix.TYPES: raise ValueError('Type must be one of: {}, not: {}'.format( ', '.join(Fix.TYPES, self.type))) if self.for_dept not in env.cfg.departments and self.for_dept != 'general': raise ValueError( 'Invalid department ({}) to assign fix to. Options are: {}' .format(self.for_dept, ', '.join(['general'] + env.cfg.departments))) s = Show.fromPk(self.show) if not s: raise ValueError('No such show: {}'.format(show)) p = Person(self.author) if not p.exists(): raise ValueError('No such user: {}'.format(self.author)) if self.sequence is not None: try: self.sequence = int(self.sequence) except ValueError: raise ValueError( 'Sequence number must be a number, not: {}'.format( self.sequence)) sq = Sequence(self.sequence, show=self.show) if not sq.exists(): raise ValueError('No such sequence {} in show {}'.format( sq.num, sq.show)) else: self.sequenceId = sq.id if self.shot is not None and self.sequence is not None: try: self.shot = int(shot) except ValueError: raise ValueError( 'Sequence number must be a number, not: {}'.format( shot)) sh = Shot(self.shot, self.sequence, show=self.show, clipName=clipName) if not sh.exists(): raise ValueError( 'No such shot {}{} in sequence {} in show {}'.format( sh.num, sh.clipName if sh.clipName else '', sh.sequence, sh.show)) else: self.shotId = sh.id if self.elementType: el = Element(self.elementName, self.elementType, self.show, self.sequence, self.shot) if not el.exists(): raise ValueError( 'No such element {} ({}){}{} in show {}'.format( el.name, el.type, ' in shot {}'.format(el.shot) if el.shot else '', ' in sequence {}'.format(el.sequence) if el.sequence else '', el.show)) else: self.elementId = el.id
def makeRelative(path, envVar): envValue = env.getEnvironment(envVar) return path.replace(envValue, '${}{}'.format(env.VAR_PREFIX, envVar.upper()))