def testFix(self): fix1 = Fix('Test fix', 'This is the body', show='foobar') self.assertTrue(fix1._exists) self.assertTrue(fix1.exists()) self.assertTrue(Show(fix1.show).exists()) self.assertIs(fix1.sequence, None) self.assertIs(fix1.sequenceId, None) self.assertFalse( Fix('Test fix2', 'This is the body', show='foobar').exists()) self.assertFalse( Fix('Test fix', 'This is the body', show='foobar', sequence=100).exists()) # Nonextant sequence with self.assertRaises(ValueError): f = Fix('Test fix', 'This is the body', show='foobar', sequence=200) # Nonextant user with self.assertRaises(ValueError): f = Fix('Another fix', 'This is the body', show='foobar', author='Bob') with Manager(willCommit=False) as mgr: for c in [c[0] for c in mgr.getColumnNames(fix1.table)]: self.assertTrue(hasattr(fix1, c)) # Try inserting again, should fail self.assertFalse(fix1.insert())
def populateSeqAndShot(self): self.CMB_seq.clear() self._show = Show.fromPk(str(self.CMB_show.currentText())) seqs = [str(s.num) for s in self._show.getSequences()] self.CMB_seq.addItems(['--'] + sorted(seqs, key=lambda s: int(s))) self.populateShots()
def setUpClass(cls): if not os.path.exists(os.environ['HELIX_DB']): if not os.path.isdir(os.path.dirname(os.environ['HELIX_DB'])): os.makedirs(os.path.dirname(os.environ['HELIX_DB'])) open(os.environ['HELIX_DB'], 'w').close() with Manager() as mgr: mgr.initTables() Person('spaouellet').insert() Person('foo').insert() Show('foobar', makeDirs=True).insert() Sequence(100, 'foobar', makeDirs=True).insert() Sequence(900, 'foobar', makeDirs=True).insert() Shot(100, 100, 'foobar', makeDirs=True).insert() Shot(200, 100, 'foobar', makeDirs=True).insert() Shot(200, 900, 'foobar', makeDirs=True).insert() Element('test', 'prop', 'foobar', makeDirs=True).insert() e = Element('camera', 'camera', 'foobar', sequence=100, makeDirs=True) e.set('assigned_to', 'foo', insertIfMissing=True) Element('render', 'plate', 'foobar', shot=100, sequence=100, makeDirs=True).insert() Fix('Test fix', 'This is the body', show='foobar').insert() env.setEnvironment('show', 'foobar')
def parent(self): if self.shotId is not None: return Shot.fromPk(self.shotId) elif self.sequenceId is not None: return Sequence.fromPk(self.sequenceId) else: return Show.fromPk(self.show)
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 target(self): if self.elementId: return Element.fromPk(self.elementId) elif self.shotId: return Shot.fromPk(self.shotId) elif self.sequenceId: return Sequence.fromPk(self.sequenceId) elif self.show: return Show.fromPk(self.show)
def getShow(alias): from helix.database.show import Show with Manager(willCommit=False) as mgr: query = """SELECT * FROM {} WHERE alias='{}'""".format(Show.TABLE, alias) row = mgr.connection().execute(query).fetchone() if row and row[0]: return Show.dummy().unmap(row) return None
def getShows(): from helix.database.show import Show with Manager(willCommit=False) as mgr: query = """SELECT * FROM {}""".format(Show.TABLE) rows = mgr.connection().execute(query).fetchall() shows = [] for r in rows: shows.append(Show.dummy().unmap(r)) return shows
def testElement(self): el = Element('test', 'prop', 'foobar', 100, 100) self.assertFalse(el._exists) self.assertFalse(el.exists()) self.assertTrue(Show(el.show).exists()) self.assertTrue(Sequence(el.sequence, el.show).exists()) self.assertTrue(Shot(el.shot, el.sequence, el.show).exists()) self.assertTrue(Element('test', 'prop', 'foobar').exists()) el.insert() pf = PublishedFile('test', 'prop', '', shot=100, sequence=100, show='foobar') pf.insert() self.assertEqual(el.getPublishedFiles()[0].id, pf.id) self.assertIn(el.table, Manager.TABLE_LIST) self.assertFalse(os.path.exists(el.work_path)) self.assertFalse(os.path.exists(el.release_path)) # No element type with self.assertRaises(ValueError): badEl = Element('foo', None, 'foobar') # Can be nameless, but only if we give shot and seq with self.assertRaises(ValueError): badEl = Element(None, 'prop', 'foobar') # Should be procedurally generated self.assertIsNotNone(Element(None, 'prop', 'foobar', 100, 100).name) # Improper element type with self.assertRaises(ValueError): badEl = Element('foo', 'bar', 'foobar') with Manager(willCommit=False) as mgr: for c in [c[0] for c in mgr.getColumnNames(el.table)]: self.assertTrue(hasattr(el, c)) # Try inserting again, should fail self.assertFalse(Element('test', 'prop', 'foobar').insert())
def populateElements(self): self.CMB_asset.clear() show = str(self.CMB_show.currentText()) seq = int(str(self.CMB_seq.currentText())) if str(self.CMB_seq.currentText()) and str(self.CMB_seq.currentText()) != '--' else None shotIndex = self.CMB_shot.currentIndex() if str(self.CMB_shot.currentText()) and str(self.CMB_shot.currentText()) != '--' else None shot = self.shots[shotIndex] if shotIndex and self.shots else None container = Show.fromPk(show) if shot: container = shot elif seq: container = Sequence(seq, show=show) self.elements = sorted(container.getElements(exclusive=True), key=lambda e: str(e)) self.CMB_asset.addItems(['--'] + [str(e) for e in self.elements]) self.elements = ['--'] + self.elements
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 testShot(self): shot = Shot(100, 100) self.assertTrue(shot._exists) self.assertTrue(shot.exists()) self.assertTrue(Show(shot.show).exists()) self.assertTrue(Sequence(shot.sequence).exists()) self.assertIn(shot.table, Manager.TABLE_LIST) self.assertTrue(os.path.exists(shot.work_path)) self.assertTrue(os.path.exists(shot.release_path)) with self.assertRaises(ValueError): badShot = Shot(100, None, show='nonextant') with self.assertRaises(ValueError): badShot = Shot(None, None, 'foobar') # Bad shot number with self.assertRaises(ValueError): badShot = Shot('foo', 100, 'foobar') # Bad seq number with self.assertRaises(ValueError): badShot = Shot(100, 'foo', 'foobar') # Should convert self.assertEqual(Shot('100', '100', 'foobar').num, 100) self.assertEqual(Shot('100', '100', 'foobar').sequence, 100) # Non-extant sequence with self.assertRaises(ValueError): badShot = Shot(100, 200, 'foobar') with Manager(willCommit=False) as mgr: for c in [c[0] for c in mgr.getColumnNames(shot.table)]: self.assertTrue(hasattr(shot, c)) # Try inserting again, should fail self.assertFalse(shot.insert())
def testSequence(self): seq1 = Sequence(200) self.assertFalse(seq1._exists) self.assertFalse(seq1.exists()) self.assertTrue(Show(seq1.show).exists()) seq = Sequence(100, show='foobar') self.assertEqual( Shot(100, 100, 'foobar').id, seq.getShots([100])[0].id) self.assertEqual(len(seq.getShots(300)), 0) with self.assertRaises(ValueError): badSeq = Sequence(100, show='nonextant') with self.assertRaises(ValueError): badSeq = Sequence(None) # Bad number with self.assertRaises(ValueError): badSeq = Sequence('foo') # Should convert self.assertEqual(Sequence('100', show='foobar').num, 100) self.assertIn(seq1.table, Manager.TABLE_LIST) self.assertFalse(os.path.exists(seq1.work_path)) self.assertFalse(os.path.exists(seq1.release_path)) with Manager(willCommit=False) as mgr: for c in [c[0] for c in mgr.getColumnNames(seq1.table)]: self.assertTrue(hasattr(seq1, c)) # Try inserting again, should fail self.assertFalse(Sequence(100, show='foobar').insert())
def parent(self): return Show.fromPk(self.show)
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, 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 __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 __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 testShow(self): # TODO: validate table columns are in object attrs show = Show('foobar') self.assertTrue(show._exists) self.assertTrue(show.exists()) self.assertEqual( show.exists(fetch=True), ('foobar', None, '/tmp/helixTest/work/foobar', '/tmp/helixTest/release/foobar', 'spaouellet', show.creation)) self.assertEqual(show.alias, 'foobar') self.assertEqual(show.name, None) self.assertEqual(show.work_path, '/tmp/helixTest/work/foobar') self.assertEqual(show.release_path, '/tmp/helixTest/release/foobar') self.assertEqual(show.author, 'spaouellet') self.assertEqual(show, Show.fromPk(getattr(show, show.pk))) self.assertEqual(show.get('alias'), 'foobar') self.assertEqual( Sequence(100, 'foobar').id, show.getSequences([100])[0].id) self.assertEqual(len(show.getSequences(200)), 0) self.assertEqual( Shot(200, 900, 'foobar').id, show.getShots(900, 200)[0].id) self.assertEqual( Shot(200, 900, 'foobar').id, show.getShots(900, [100, 200])[0].id) self.assertEqual(len(show.getShots()), 3) self.assertEqual(len(show.getElements()), 3) self.assertEqual( Element('test', 'prop', 'foobar').id, show.getElements('test', 'prop')[0].id) self.assertEqual(len(show.getElements(status='ip')), 0) self.assertEqual(len(show.getElements(authors='bob')), 0) self.assertEqual(len(show.getElements(authors='spaouellet')), 3) self.assertEqual(len(show.getElements(assignedTo='foo')), 1) self.assertEqual( len(show.getElements(assignedTo='foo', authors='bob')), 0) with self.assertRaises(ValueError): # Non-sanitary alias Show('foo bar') with self.assertRaises(ValueError): # Long alias Show('thisaliasiswaytoolong') # Nonextant attributes self.assertIs(show.get('randomAttr'), None) self.assertEqual(show.get('randomAttr', 'default'), 'default') self.assertIn(show.table, Manager.TABLE_LIST) self.assertTrue(os.path.exists(show.work_path)) self.assertTrue(os.path.exists(show.release_path)) # Test dummy show doesn't exist nonextant = Show('nonextant') self.assertFalse(nonextant._exists) self.assertFalse(nonextant.exists()) self.assertIs(nonextant.exists(fetch=True), None) show.set('name', 'Testing') del show show = Show('foobar') # Remaking, should have saved show.name self.assertEqual(show.name, 'Testing') # Test setting on a non-db-extant show show2 = Show('show2') show2.set('name', 'Show2') # We set without inserting del show2 show2 = Show('show2') self.assertIs(show2.name, None) # Now set while inserting show2.set('name', 'Show2', insertIfMissing=True) del show2 show2 = Show('show2') self.assertEqual(show2.name, 'Show2') # Table columns exist in attrs with Manager(willCommit=False) as mgr: for c in [c[0] for c in mgr.getColumnNames(show2.table)]: self.assertTrue(hasattr(show2, c)) # Try inserting again, should fail self.assertFalse(show.insert())