def reject(self): QtWidgets.QDialog.reject(self) from stalker.db.session import DBSession if self.version: DBSession.delete(self.version) DBSession.commit() DBSession.rollback()
def accept(self): """overridden accept method """ if not self.name_lineEdit.is_valid: QtWidgets.QMessageBox.critical( self, 'Error', 'Please fix <b>name</b> field!' ) return name = self.name_lineEdit.text() windows_path = self.windows_path_lineEdit.text() linux_path = self.linux_path_lineEdit.text() osx_path = self.osx_path_lineEdit.text() from stalker import Repository from stalker.db.session import DBSession logged_in_user = self.get_logged_in_user() if self.mode == 'Create': # Create a new Repository try: repo = Repository( name=name, windows_path=windows_path, linux_path=linux_path, osx_path=osx_path ) self.repository = repo DBSession.add(repo) DBSession.commit() except Exception as e: DBSession.rollback() QtWidgets.QMessageBox.critical( self, 'Error', str(e) ) return elif self.mode == 'Update': # Update the repository try: self.repository.name = name self.repository.windows_path = windows_path self.repository.linux_path = linux_path self.repository.osx_path = osx_path self.repository.updated_by = logged_in_user DBSession.add(self.repository) DBSession.commit() except Exception as e: DBSession.rollback() QtWidgets.QMessageBox.critical( self, 'Error', str(e) ) return super(MainDialog, self).accept()
def closeEvent(self, event): """if user tries to close the publish_checker dialog pop up a question dialog """ answer = QtWidgets.QMessageBox.question( self, 'DO NOT Close Window!!!', 'You should <b>NOT</b> close this window!!!<br/>' ' <br/>' 'Drag Publish Checker to the side and fix your scene<br/>' 'When fixed hit Check buttons until Published!!!<br/>' ' <br/>' 'Close Anyway !!!', QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No) if answer == QtWidgets.QMessageBox.Yes: # delete any empty published versions if created if self.version.is_latest_published_version() \ and self.version.absolute_full_path == '.' \ and self.version.extension == '' \ and not self.version.created_with: # this means the last published version is empty from stalker.db.session import DBSession try: DBSession.delete(self.version) # DBSession.commit() # no need to commit except Exception: DBSession.rollback() event.accept() else: event.ignore()
def accept(self): """overridden accept method """ if not self.name_lineEdit.is_valid: QtWidgets.QMessageBox.critical(self, 'Error', 'Please fix <b>name</b> field!') return name = self.name_lineEdit.text() custom_template = self.custom_template_plainTextEdit.toPlainText() filename_template_items = \ self.filename_templates_double_list_widget.secondary_items() filename_template_ids = [] for item in filename_template_items: filename_template_id = \ int(item.text().split('(')[-1].split(')')[0]) filename_template_ids.append(filename_template_id) from stalker import FilenameTemplate filename_templates = FilenameTemplate.query\ .filter(FilenameTemplate.id.in_(filename_template_ids)).all() from stalker import Structure from stalker.db.session import DBSession logged_in_user = self.get_logged_in_user() if self.mode == 'Create': # Create a new Structure try: structure = Structure(name=name, templates=filename_templates, custom_template=custom_template, created_by=logged_in_user) self.structure = structure DBSession.add(structure) DBSession.commit() except Exception as e: DBSession.rollback() QtWidgets.QMessageBox.critical(self, 'Error', str(e)) return elif self.mode == 'Update': # Update the structure try: self.structure.name = name self.structure.templates = filename_templates self.structure.custom_template = custom_template self.structure.updated_by = logged_in_user DBSession.add(self.structure) DBSession.commit() except Exception as e: DBSession.rollback() QtWidgets.QMessageBox.critical(self, 'Error', str(e)) return super(MainDialog, self).accept()
def create_user(self): """ Creates new user """ from stalker.db.session import DBSession from stalker import User new_user = User( name="{0}".format(self.user_name), login="******".format(self.user_login), email="{0}".format(self.user_email), password="******".format(self.user_password) ) #Checks if the user's name and e-mail address are registered in the database. #Sends a warning message to the user if registered. if not User.query.filter_by(email=self.user_email).scalar() == None: QtWidgets.QMessageBox.warning( self, "Warning", "The email address you entered already belongs to an existing user , Please re-enter your e-mail address!" ) elif not User.query.filter_by(login=self.user_login).scalar() == None: QtWidgets.QMessageBox.warning( self, "Warning", "The user '{0}' already exists, Please enter new username!".format(self.user_login) ) else: try: # Save the user to database DBSession.save(new_user) #Gets the string representation of an exception except BaseException as e: DBSession.rollback() QtWidgets.QMessageBox.critical( self, "Error", str(e) ) # now we can give the information message QtWidgets.QMessageBox.information( self, "Success", "User '{0}' successfully created!".format(self.user_login) ) # then we can close this dialog self.close()
def accept(self): """the overridden accept method """ target_entity_type = self.target_entity_type_combo_box.currentText() if not self.name_line_edit.is_valid: QtWidgets.QMessageBox.critical(self, 'Error', 'Please fix <b>name</b> field!') return name = self.name_line_edit.text() path = self.path_line_edit.text() if path == '': QtWidgets.QMessageBox.critical(self, 'Error', 'Please fix <b>path</b> field!') return filename = self.filename_line_edit.text() if path == '': QtWidgets.QMessageBox.critical( self, 'Error', 'Please fix <b>filename</b> field!') return logged_in_user = self.get_logged_in_user() from stalker.db.session import DBSession if self.mode == 'Create': try: from stalker import FilenameTemplate # create a new FilenameTemplate ft = FilenameTemplate(name=name, path=path, filename=filename, target_entity_type=target_entity_type, created_by=logged_in_user) self.filename_template = ft DBSession.add(ft) DBSession.commit() except Exception as e: DBSession.rollback() QtWidgets.QMessageBox.critical(self, 'Error', str(e)) return elif self.mode == 'Update': try: self.filename_template.name = name self.filename_template.path = path self.filename_template.filename = filename self.filename_template.updated_by = logged_in_user DBSession.add(self.filename_template) DBSession.commit() except Exception as e: DBSession.rollback() QtWidgets.QMessageBox.critical(self, 'Error', str(e)) return super(MainDialog, self).accept()
def create_ticket_statuses(): """creates the default ticket statuses """ from stalker import defaults, User # create as admin admin = User.query.filter(User.login == defaults.admin_name).first() # create statuses for Tickets ticket_names = defaults.ticket_status_names ticket_codes = defaults.ticket_status_codes create_entity_statuses('Ticket', ticket_names, ticket_codes, admin) # Again I hate doing this in this way from stalker import Type types = Type.query \ .filter_by(target_entity_type="Ticket") \ .all() t_names = [t.name for t in types] # create Ticket Types logger.debug("Creating Ticket Types") from stalker.db.session import DBSession if 'Defect' not in t_names: ticket_type_1 = Type( name='Defect', code='Defect', target_entity_type='Ticket', created_by=admin, updated_by=admin ) DBSession.add(ticket_type_1) if 'Enhancement' not in t_names: ticket_type_2 = Type( name='Enhancement', code='Enhancement', target_entity_type='Ticket', created_by=admin, updated_by=admin ) DBSession.add(ticket_type_2) from sqlalchemy.exc import IntegrityError try: DBSession.commit() except IntegrityError: DBSession.rollback() logger.debug("Ticket Types are already in the database!") else: # DBSession.flush() logger.debug("Ticket Types are created successfully")
def create_ticket_statuses(): """creates the default ticket statuses """ from stalker import User # create as admin admin = User.query.filter(User.login == defaults.admin_name).first() # create statuses for Tickets ticket_names = defaults.ticket_status_names ticket_codes = defaults.ticket_status_codes create_entity_statuses('Ticket', ticket_names, ticket_codes, admin) # Again I hate doing this in this way from stalker import Type types = Type.query \ .filter_by(target_entity_type="Ticket") \ .all() t_names = [t.name for t in types] # create Ticket Types logger.debug("Creating Ticket Types") if 'Defect' not in t_names: ticket_type_1 = Type( name='Defect', code='Defect', target_entity_type='Ticket', created_by=admin, updated_by=admin ) DBSession.add(ticket_type_1) if 'Enhancement' not in t_names: ticket_type_2 = Type( name='Enhancement', code='Enhancement', target_entity_type='Ticket', created_by=admin, updated_by=admin ) DBSession.add(ticket_type_2) try: DBSession.commit() except IntegrityError: DBSession.rollback() logger.debug("Ticket Types are already in the database!") else: # DBSession.flush() logger.debug("Ticket Types are created successfully")
def create_entity_statuses(entity_type="", status_names=None, status_codes=None, user=None): """creates the default task statuses """ if not entity_type: raise ValueError("Please supply entity_type") if not status_names: raise ValueError("Please supply status names") if not status_codes: raise ValueError("Please supply status codes") # create statuses for entity from stalker import Status, StatusList logger.debug("Creating %s Statuses" % entity_type) statuses = Status.query.filter(Status.name.in_(status_names)).all() status_names_in_db = map(lambda x: x.name, statuses) for name, code in zip(status_names, status_codes): if name not in status_names_in_db: logger.debug("Creating Status: %s (%s)" % (name, code)) new_status = Status(name=name, code=code, created_by=user, updated_by=user) statuses.append(new_status) DBSession.add(new_status) # create the Status List status_list = StatusList.query.filter(StatusList.target_entity_type == entity_type).first() if status_list is None: logger.debug("No %s Status List found, creating new!" % entity_type) status_list = StatusList( name="%s Statuses" % entity_type, target_entity_type=entity_type, created_by=user, updated_by=user ) else: logger.debug("%s Status List already created, updating statuses" % entity_type) status_list.statuses = statuses DBSession.add(status_list) try: DBSession.commit() except IntegrityError as e: logger.debug("error in DBSession.commit, rolling back: %s" % e) DBSession.rollback() else: logger.debug("Created %s Statuses successfully" % entity_type) DBSession.flush()
def get_alembic_version(): """returns the alembic version of the database """ # try to query the version value conn = DBSession.connection() engine = conn.engine if engine.dialect.has_table(conn, 'alembic_version'): sql_query = 'select version_num from alembic_version' try: return DBSession.connection().execute(sql_query).fetchone()[0] except (OperationalError, ProgrammingError, TypeError): DBSession.rollback() return None else: return None
def accept(self): """overridden accept method """ if not self.name_line_edit.is_valid: QtWidgets.QMessageBox.critical(self, 'Error', 'Please fix <b>name</b> field!') return name = self.name_line_edit.text() width = self.width_spin_box.value() height = self.height_spin_box.value() pixel_aspect = self.pixel_aspect_double_spin_box.value() from stalker import ImageFormat from stalker.db.session import DBSession logged_in_user = self.get_logged_in_user() if self.mode == 'Create': # Create a new Image Format try: imf = ImageFormat(name=name, width=width, height=height, pixel_aspect=pixel_aspect, created_by=logged_in_user) self.image_format = imf DBSession.add(imf) DBSession.commit() except Exception as e: DBSession.rollback() QtWidgets.QMessageBox.critical(self, 'Error', str(e)) return elif self.mode == 'Update': # Update the image format try: self.image_format.name = name self.image_format.width = width self.image_format.height = height self.image_format.pixel_aspect = pixel_aspect self.image_format.updated_by = logged_in_user DBSession.add(self.image_format) DBSession.commit() except Exception as e: DBSession.rollback() QtWidgets.QMessageBox.critical(self, 'Error', str(e)) return super(MainDialog, self).accept()
def tearDown(self): """clean up the test """ import datetime from stalker import defaults from stalker.db.declarative import Base from stalker.db.session import DBSession # clean up test database DBSession.rollback() connection = DBSession.connection() engine = connection.engine connection.close() Base.metadata.drop_all(engine, checkfirst=True) DBSession.remove() defaults.timing_resolution = datetime.timedelta(hours=1)
def register(class_): """Registers the given class to the database. It is mainly used to create the :class:`.Action`\ s needed for the :class:`.User`\ s and :class:`.Group`\ s to be able to interact with the given class. Whatever class you have created needs to be registered. Example, lets say that you have a data class which is specific to your studio and it is not present in Stalker Object Model (SOM), so you need to extend SOM with a new data type. Here is a simple Data class inherited from the :class:`.SimpleEntity` class (which is the simplest class you should inherit your classes from or use more complex classes down to the hierarchy):: from sqlalchemy import Column, Integer, ForeignKey from stalker.models.entity import SimpleEntity class MyDataClass(SimpleEntity): '''This is an example class holding a studio specific data which is not present in SOM. ''' __tablename__ = 'MyData' __mapper_arguments__ = {'polymorphic_identity': 'MyData'} my_data_id = Column('id', Integer, ForeignKey('SimpleEntities.c.id'), primary_key=True) Now because Stalker is using Pyramid authorization mechanism it needs to be able to have an :class:`.Permission` about your new class, so you can assign this :class;`.Permission` to your :class:`.User`\ s or :class:`.Group`\ s. So you ned to register your new class with :func:`stalker.db.register` like shown below:: from stalker import db db.register(MyDataClass) This will create the necessary Actions in the 'Actions' table on your database, then you can create :class:`.Permission`\ s and assign these to your :class:`.User`\ s and :class:`.Group`\ s so they are Allowed or Denied to do the specified Action. :param class_: The class itself that needs to be registered. """ from stalker.models.auth import Permission # create the Permissions permissions_db = Permission.query.all() if not isinstance(class_, type): raise TypeError('To register a class please supply the class itself.') # register the class name to entity_types table from stalker import (EntityType, StatusMixin, DateRangeMixin, ReferenceMixin, ScheduleMixin) class_name = class_.__name__ if not EntityType.query.filter_by(name=class_name).first(): new_entity_type = EntityType(class_name) # update attributes if issubclass(class_, StatusMixin): new_entity_type.statusable = True if issubclass(class_, DateRangeMixin): new_entity_type.dateable = True if issubclass(class_, ScheduleMixin): new_entity_type.schedulable = True if issubclass(class_, ReferenceMixin): new_entity_type.accepts_references = True DBSession.add(new_entity_type) for action in defaults.actions: for access in ['Allow', 'Deny']: permission_obj = Permission(access, action, class_name) if permission_obj not in permissions_db: DBSession.add(permission_obj) try: DBSession.commit() except IntegrityError: DBSession.rollback()
def create_entity_statuses(entity_type='', status_names=None, status_codes=None, user=None): """creates the default task statuses """ if not entity_type: raise ValueError('Please supply entity_type') if not status_names: raise ValueError('Please supply status names') if not status_codes: raise ValueError('Please supply status codes') # create statuses for entity from stalker import Status, StatusList logger.debug("Creating %s Statuses" % entity_type) statuses = Status.query.filter(Status.name.in_(status_names)).all() logger.debug('status_names: %s' % status_names) logger.debug('statuses: %s' % statuses) status_names_in_db = list(map(lambda x: x.name, statuses)) logger.debug('statuses_names_in_db: %s' % status_names_in_db) for name, code in zip(status_names, status_codes): if name not in status_names_in_db: logger.debug('Creating Status: %s (%s)' % (name, code)) new_status = Status( name=name, code=code, created_by=user, updated_by=user ) statuses.append(new_status) DBSession.add(new_status) else: logger.debug( 'Status %s (%s) is already created skipping!' % (name, code) ) # create the Status List status_list = StatusList.query\ .filter(StatusList.target_entity_type == entity_type)\ .first() if status_list is None: logger.debug('No %s Status List found, creating new!' % entity_type) status_list = StatusList( name='%s Statuses' % entity_type, target_entity_type=entity_type, created_by=user, updated_by=user ) else: logger.debug("%s Status List already created, updating statuses" % entity_type) status_list.statuses = statuses DBSession.add(status_list) try: DBSession.commit() except IntegrityError as e: logger.debug("error in DBSession.commit, rolling back: %s" % e) DBSession.rollback() else: logger.debug("Created %s Statuses successfully" % entity_type) DBSession.flush()
def accept(self): """the overridden accept method """ target_entity_type = self.target_entity_type_combo_box.currentText() if not self.name_line_edit.is_valid: QtWidgets.QMessageBox.critical( self, 'Error', 'Please fix <b>name</b> field!' ) return name = self.name_line_edit.text() path = self.path_line_edit.text() if path == '': QtWidgets.QMessageBox.critical( self, 'Error', 'Please fix <b>path</b> field!' ) return filename = self.filename_line_edit.text() if path == '': QtWidgets.QMessageBox.critical( self, 'Error', 'Please fix <b>filename</b> field!' ) return logged_in_user = self.get_logged_in_user() from stalker.db.session import DBSession if self.mode == 'Create': try: from stalker import FilenameTemplate # create a new FilenameTemplate ft = FilenameTemplate( name=name, path=path, filename=filename, target_entity_type=target_entity_type, created_by=logged_in_user ) self.filename_template = ft DBSession.add(ft) DBSession.commit() except Exception as e: DBSession.rollback() QtWidgets.QMessageBox.critical( self, 'Error', str(e) ) return elif self.mode == 'Update': try: self.filename_template.name = name self.filename_template.path = path self.filename_template.filename = filename self.filename_template.updated_by = logged_in_user DBSession.add(self.filename_template) DBSession.commit() except Exception as e: DBSession.rollback() QtWidgets.QMessageBox.critical( self, 'Error', str(e) ) return super(MainDialog, self).accept()
def accept(self): """create/update the project """ # Name if not self.name_lineEdit.is_valid: QtWidgets.QMessageBox.critical(self, 'Error', 'Please fix <b>name</b> field!') return name = self.name_lineEdit.text() # Code if not self.code_lineEdit.is_valid: QtWidgets.QMessageBox.critical(self, 'Error', 'Please fix <b>code</b> field!') return code = self.code_lineEdit.text() # Type from stalker import Type index = self.type_comboBox.currentIndex() type_id = self.type_comboBox.itemData(index) type_ = Type.query.get(type_id) # None type is ok # Image Format image_format = self.image_format.get_current_image_format() if not image_format: QtWidgets.QMessageBox.critical( self, 'Error', 'Please select an valid <b>Image Format</b>!') return # FPS fps = self.fps_spinBox.value() # Repository repo = self.get_current_repository() if not repo: QtWidgets.QMessageBox.critical( self, 'Error', 'Please select an valid <b>Repository</b>!') return # Structure structure = self.get_current_structure() if not structure: QtWidgets.QMessageBox.critical( self, 'Error', 'Please select an valid <b>Structure</b>!') return # Status from stalker import Status index = self.status_comboBox.currentIndex() status_id = self.status_comboBox.itemData(index) status = Status.query.get(status_id) if not status: QtWidgets.QMessageBox.critical( self, 'Error', 'Please select an valid <b>Status</b>!') return # TODO: Add Client Data fields (which I don't care for now) logged_in_user = self.get_logged_in_user() # create or update project from stalker.db.session import DBSession if self.mode == 'Create': # create a new project from stalker import Project new_project = Project(name=name, code=code, type=type_, repositories=[repo], structure=structure, image_format=image_format, fps=fps, created_by=logged_in_user) DBSession.add(new_project) try: DBSession.commit() except Exception as e: DBSession.rollback() QtWidgets.QMessageBox.critical(self, 'Error', str(e)) return else: # update the project self.project.updated_by = logged_in_user self.project.name = name self.project.code = code self.project.type = type_ self.project.repositories = [repo] self.project.structure = structure self.project.image_format = image_format self.project.fps = fps self.project.status = status DBSession.add(self.project) try: DBSession.commit() except Exception as e: DBSession.rollback() QtWidgets.QMessageBox.critical(self, 'Error', str(e)) return super(MainDialog, self).accept()
def save_previs_to_shots(self, take_name): """exports previs to animation shots """ self.pre_publish_previs() shot_tasks = self.scene_shot_tasks shot_nodes = self.shot_list shots_to_export = [] for shot_node in shot_nodes: for shot_task in shot_tasks: for task in shot_task.tasks: if task.type == self.anim_type: shot_number = shot_task.name.split('_')[-1] if shot_node.getShotName() == shot_number: shots_to_export.append([shot_node, task, shot_number]) from anima.env import mayaEnv from stalker import Version from anima.ui.progress_dialog import ProgressDialogManager pdm = ProgressDialogManager() pdm.close() m_env = mayaEnv.Maya() versions = [] description = 'Auto Created By Shot Exporter' # create versions to save and show in pop-up window for shot_info in shots_to_export: version = Version( task=shot_info[1], description=description, take_name=take_name, created_by=self.logged_in_user ) versions.append(version) if len(versions) != len(shots_to_export): from stalker.db.session import DBSession DBSession.rollback() raise RuntimeError('Something is critically wrong. Contact Mehmet ERER.') # pop-up a window to show everything will be saved properly before actually doing it message = 'Shots will be Saved as Below:\r\n' message += '\r' index = 0 for shot_info in shots_to_export: v = versions[index] message += 'shot[ %s ] -> %s\n' % (shot_info[2], v) index += 1 dialog = pm.confirmDialog(title='Important Warning', message=message, button=['OK, Start Saving Shots', 'STOP, wrong paths!']) if dialog == 'OK, Start Saving Shots': pass else: from stalker.db.session import DBSession DBSession.rollback() raise RuntimeError('Process Interrupted by User.') previs_version = self.current_version errored_shots = [] ind = 0 caller = pdm.register(len(shots_to_export), 'Batch Saving Previs Shot Nodes to Animation Shot Tasks...') from anima.env.mayaEnv import toolbox reload(toolbox) from stalker.db.session import DBSession for shot_info in shots_to_export: shot_task = versions[ind].task.parent try: # open previs version m_env.open(previs_version, force=True, reference_depth=3, skip_update_check=True) # clear scene except_this_shot = pm.PyNode(shot_info[0].name()) self.clear_scene(except_this_shot) # set frame range before save toolbox.Animation.set_range_from_shot() # update shot.cut_in and shot.cut_out info cut_in = pm.playbackOptions(q=1, min=1) cut_out = pm.playbackOptions(q=1, max=1) shot_task.cut_in = int(cut_in) shot_task.cut_out = int(cut_out) # save it m_env.save_as(versions[ind]) except: errored_shots.append(shot_info[2]) else: # store information to database DBSession.add(shot_task) DBSession.add(versions[ind]) DBSession.commit() ind += 1 caller.step() if errored_shots: message = 'Shots could not be saved:\r\n' message += '\r' for shot in errored_shots: message += '[ %s ]\n' % shot pm.confirmDialog(title='Error', message=message, button='OK') DBSession.rollback() raise RuntimeError('Some Shots could not be saved. Contact Mehmet ERER.') # leave it as empty new file pm.newFile(force=True) message = 'Previs to Shots\r\n' message += '\r' message += 'Completed Succesfully.\r\n' pm.confirmDialog(title='Info', message=message, button='OK')
def accept(self): """overridden accept method """ if not self.name_lineEdit.is_valid: QtWidgets.QMessageBox.critical( self, 'Error', 'Please fix <b>name</b> field!' ) return name = self.name_lineEdit.text() custom_template = self.custom_template_plainTextEdit.toPlainText() filename_template_items = \ self.filename_templates_double_list_widget.secondary_items() filename_template_ids = [] for item in filename_template_items: filename_template_id = \ int(item.text().split('(')[-1].split(')')[0]) filename_template_ids.append(filename_template_id) from stalker import FilenameTemplate filename_templates = FilenameTemplate.query\ .filter(FilenameTemplate.id.in_(filename_template_ids)).all() from stalker import Structure from stalker.db.session import DBSession logged_in_user = self.get_logged_in_user() if self.mode == 'Create': # Create a new Structure try: structure = Structure( name=name, templates=filename_templates, custom_template=custom_template, created_by=logged_in_user ) self.structure = structure DBSession.add(structure) DBSession.commit() except Exception as e: DBSession.rollback() QtWidgets.QMessageBox.critical( self, 'Error', str(e) ) return elif self.mode == 'Update': # Update the structure try: self.structure.name = name self.structure.templates = filename_templates self.structure.custom_template = custom_template self.structure.updated_by = logged_in_user DBSession.add(self.structure) DBSession.commit() except Exception as e: DBSession.rollback() QtWidgets.QMessageBox.critical( self, 'Error', str(e) ) return super(MainDialog, self).accept()
def register(class_): """Registers the given class to the database. It is mainly used to create the :class:`.Action`\ s needed for the :class:`.User`\ s and :class:`.Group`\ s to be able to interact with the given class. Whatever class you have created needs to be registered. Example, lets say that you have a data class which is specific to your studio and it is not present in Stalker Object Model (SOM), so you need to extend SOM with a new data type. Here is a simple Data class inherited from the :class:`.SimpleEntity` class (which is the simplest class you should inherit your classes from or use more complex classes down to the hierarchy):: from sqlalchemy import Column, Integer, ForeignKey from stalker.models.entity import SimpleEntity class MyDataClass(SimpleEntity): '''This is an example class holding a studio specific data which is not present in SOM. ''' __tablename__ = 'MyData' __mapper_arguments__ = {'polymorphic_identity': 'MyData'} my_data_id = Column('id', Integer, ForeignKey('SimpleEntities.c.id'), primary_key=True) Now because Stalker is using Pyramid authorization mechanism it needs to be able to have an :class:`.Permission` about your new class, so you can assign this :class;`.Permission` to your :class:`.User`\ s or :class:`.Group`\ s. So you ned to register your new class with :func:`stalker.db.register` like shown below:: from stalker import db db.register(MyDataClass) This will create the necessary Actions in the 'Actions' table on your database, then you can create :class:`.Permission`\ s and assign these to your :class:`.User`\ s and :class:`.Group`\ s so they are Allowed or Denied to do the specified Action. :param class_: The class itself that needs to be registered. """ from stalker.models.auth import Permission # create the Permissions permissions_db = Permission.query.all() if not isinstance(class_, type): raise TypeError("To register a class please supply the class itself.") # register the class name to entity_types table from stalker import EntityType, StatusMixin, DateRangeMixin, ReferenceMixin, ScheduleMixin class_name = class_.__name__ if not EntityType.query.filter_by(name=class_name).first(): new_entity_type = EntityType(class_name) # update attributes if issubclass(class_, StatusMixin): new_entity_type.statusable = True if issubclass(class_, DateRangeMixin): new_entity_type.dateable = True if issubclass(class_, ScheduleMixin): new_entity_type.schedulable = True if issubclass(class_, ReferenceMixin): new_entity_type.accepts_references = True DBSession.add(new_entity_type) for action in defaults.actions: for access in ["Allow", "Deny"]: permission_obj = Permission(access, action, class_name) if permission_obj not in permissions_db: DBSession.add(permission_obj) try: DBSession.commit() except IntegrityError: DBSession.rollback()
def accept(self): """overridden accept method """ if not self.name_line_edit.is_valid: QtWidgets.QMessageBox.critical( self, 'Error', 'Please fix <b>name</b> field!' ) return name = self.name_line_edit.text() width = self.width_spin_box.value() height = self.height_spin_box.value() pixel_aspect = self.pixel_aspect_double_spin_box.value() from stalker import ImageFormat from stalker.db.session import DBSession logged_in_user = self.get_logged_in_user() if self.mode == 'Create': # Create a new Image Format try: imf = ImageFormat( name=name, width=width, height=height, pixel_aspect=pixel_aspect, created_by=logged_in_user ) self.image_format = imf DBSession.add(imf) DBSession.commit() except Exception as e: DBSession.rollback() QtWidgets.QMessageBox.critical( self, 'Error', str(e) ) return elif self.mode == 'Update': # Update the image format try: self.image_format.name = name self.image_format.width = width self.image_format.height = height self.image_format.pixel_aspect = pixel_aspect self.image_format.updated_by = logged_in_user DBSession.add(self.image_format) DBSession.commit() except Exception as e: DBSession.rollback() QtWidgets.QMessageBox.critical( self, 'Error', str(e) ) return super(MainDialog, self).accept()
def accept(self): """overridden accept method """ # get the info task = self.tasks_combo_box.currentTask() resource = self.get_current_resource() # war the user if the resource is not the logged_in_user if resource != self.logged_in_user: msg_box = QtWidgets.QMessageBox(self) msg_box.setWindowTitle( 'Entering TimeLog On Behalf of Somebody Else' ) msg_box.setText( "You're entering a TimeLog on behalf of somebody else???" ) accept_button = msg_box.addButton( 'Accept the responsibility', QtWidgets.QMessageBox.AcceptRole ) cancel_button = msg_box.addButton( 'Cancel', QtWidgets.QMessageBox.RejectRole ) msg_box.setDefaultButton(cancel_button) msg_box.exec_() clicked_button = msg_box.clickedButton() msg_box.deleteLater() if clicked_button == cancel_button: return description = self.description_plain_text_edit.toPlainText() revision_cause_text = \ self.revision_type_combo_box.currentText().replace(' ', '_') is_complete = self.set_as_complete_radio_button.isChecked() submit_to_final_review = \ self.submit_for_final_review_radio_button.isChecked() # get the revision Types from stalker import Type revision_type = Type.query\ .filter(Type.target_entity_type == 'Note')\ .filter(Type.name == revision_cause_text)\ .first() date = self.calendar_widget.selectedDate() start = self.start_time_edit.time() end = self.end_time_edit.time() # construct proper datetime.DateTime instances import datetime start_date = datetime.datetime( date.year(), date.month(), date.day(), start.hour(), start.minute() ) end_date = datetime.datetime( date.year(), date.month(), date.day(), end.hour(), end.minute() ) today_midnight = datetime.datetime.now().replace( hour=23, minute=59, second=59, microsecond=999 ) # raise an error if the user is trying to enter a TimeLog to the future if start_date > today_midnight or end_date > today_midnight: QtWidgets.QMessageBox.critical( self, 'Error', 'Gelecege TimeLog giremezsiniz!!!', ) return # convert them to utc from anima.utils import local_to_utc utc_start_date = local_to_utc(start_date) utc_end_date = local_to_utc(end_date) # create a TimeLog # print('Task : %s' % task.name) # print('Resource : %s' % resource.name) # print('utc_start_date: %s' % utc_start_date) # print('utc_end_date : %s' % utc_end_date) # now if we are not using extra time just create the TimeLog from stalker import TimeLog from stalker.db.session import DBSession from stalker.exceptions import (OverBookedError, DependencyViolationError) utc_now = local_to_utc(datetime.datetime.now()) # TODO: Remove this in a later version import stalker from distutils.version import LooseVersion if LooseVersion(stalker.__version__) >= LooseVersion('0.2.18'): # inject timezone info import pytz utc_start_date = utc_start_date.replace(tzinfo=pytz.utc) utc_end_date = utc_end_date.replace(tzinfo=pytz.utc) utc_now = utc_now.replace(tzinfo=pytz.utc) from sqlalchemy.exc import IntegrityError if not self.timelog: try: new_time_log = TimeLog( task=task, resource=resource, start=utc_start_date, end=utc_end_date, description=description, date_created=utc_now ) except (OverBookedError, DependencyViolationError) as e: # inform the user that it can not do that QtWidgets.QMessageBox.critical( self, 'Error', '%s' % e ) DBSession.rollback() return try: DBSession.add(new_time_log) DBSession.commit() self.timelog_created = True except IntegrityError as e: DBSession.rollback() QtWidgets.QMessageBox.critical( self, 'Error', 'Database Error!!!' '<br>' '%s' % e ) return else: # just update the date values self.timelog.start = utc_start_date self.timelog.end = utc_end_date self.timelog.date_updated = utc_now DBSession.add(self.timelog) DBSession.commit() if self.no_time_left: # we have no time left so automatically extend the task from stalker import Task schedule_timing, schedule_unit = \ task.least_meaningful_time_unit( task.total_logged_seconds ) if schedule_timing != 0: task.schedule_timing = schedule_timing task.schedule_unit = schedule_unit # also create a Note from stalker import Note new_note = Note( content='Extending timing of the task <b>%s h %s min.</b>' % ( self.extended_hours, self.extended_minutes ), type=revision_type, created_by=self.logged_in_user, date_created=utc_now ) DBSession.add(new_note) task.notes.append(new_note) try: DBSession.commit() except IntegrityError as e: QtWidgets.QMessageBox.critical( self, 'Error', 'Database Error!!!' '<br>' '%s' % e ) DBSession.rollback() return if is_complete: # set the status to complete from stalker import Type, Status status_cmpl = Status.query.filter(Status.code == 'CMPL').first() forced_status_type = \ Type.query.filter(Type.name == 'Forced Status').first() # also create a Note from stalker import Note new_note = Note( content='%s has changed this task status to Completed' % resource.name, type=forced_status_type, created_by=self.logged_in_user, date_created=utc_now ) DBSession.add(new_note) task.notes.append(new_note) task.status = status_cmpl DBSession.commit() elif submit_to_final_review: # clip the Task timing to current time logs from stalker import Task schedule_timing, schedule_unit = \ task.least_meaningful_time_unit( task.total_logged_seconds ) task.schedule_timing = schedule_timing task.schedule_unit = schedule_unit DBSession.add(task) try: DBSession.commit() except IntegrityError as e: QtWidgets.QMessageBox.critical( self, 'Error', 'Database Error!!!' '<br>' '%s' % e ) DBSession.rollback() return # request a review reviews = task.request_review() for review in reviews: review.created_by = review.updated_by = self.logged_in_user review.date_created = utc_now review.date_updated = utc_now DBSession.add_all(reviews) # and create a Note for the Task request_review_note_type = \ Type.query\ .filter(Type.target_entity_type == 'Note')\ .filter(Type.name == 'Request Review')\ .first() from stalker import Note request_review_note = Note( type=request_review_note_type, created_by=self.logged_in_user, date_created=utc_now ) DBSession.add(request_review_note) DBSession.add(task) task.notes.append(request_review_note) try: DBSession.commit() except IntegrityError as e: DBSession.rollback() QtWidgets.QMessageBox.critical( self, 'Error', 'Database Error!!!' '<br>' '%s' % e ) return # Fix statuses from anima import utils utils.fix_task_statuses(task) try: DBSession.commit() except IntegrityError as e: DBSession.rollback() QtWidgets.QMessageBox.critical( self, 'Error', 'Database Error!!!' '<br>' '%s' % e ) return # if nothing bad happens close the dialog super(MainDialog, self).accept()
def save_previs_to_shots(self, take_name): """exports previs to animation shots """ self.pre_publish_previs() shot_tasks = self.scene_shot_tasks shot_nodes = self.shot_list shots_to_export = [] for shot_node in shot_nodes: for shot_task in shot_tasks: for task in shot_task.tasks: if task.type == self.anim_type: shot_number = shot_task.name.split('_')[-1] if shot_node.getShotName() == shot_number: shots_to_export.append( [shot_node, task, shot_number]) from anima.env import mayaEnv from stalker import Version from anima.ui.progress_dialog import ProgressDialogManager pdm = ProgressDialogManager() pdm.close() m_env = mayaEnv.Maya() versions = [] description = 'Auto Created By Shot Exporter' # create versions to save and show in pop-up window for shot_info in shots_to_export: version = Version(task=shot_info[1], description=description, take_name=take_name, created_by=self.logged_in_user) versions.append(version) if len(versions) != len(shots_to_export): from stalker.db.session import DBSession DBSession.rollback() raise RuntimeError( 'Something is critically wrong. Contact Mehmet ERER.') # pop-up a window to show everything will be saved properly before actually doing it message = 'Shots will be Saved as Below:\r\n' message += '\r' index = 0 for shot_info in shots_to_export: v = versions[index] message += 'shot[ %s ] -> %s\n' % (shot_info[2], v) index += 1 dialog = pm.confirmDialog( title='Important Warning', message=message, button=['OK, Start Saving Shots', 'STOP, wrong paths!']) if dialog == 'OK, Start Saving Shots': pass else: from stalker.db.session import DBSession DBSession.rollback() raise RuntimeError('Process Interrupted by User.') previs_version = self.current_version errored_shots = [] ind = 0 caller = pdm.register( len(shots_to_export), 'Batch Saving Previs Shot Nodes to Animation Shot Tasks...') from anima.env.mayaEnv import toolbox from stalker.db.session import DBSession for shot_info in shots_to_export: shot_task = versions[ind].task.parent try: # open previs version m_env.open(previs_version, force=True, reference_depth=3, skip_update_check=True) # clear scene except_this_shot = pm.PyNode(shot_info[0].name()) self.clear_scene(except_this_shot) # set frame range before save anima.env.mayaEnv.animation.Animation.set_range_from_shot() # update shot.cut_in and shot.cut_out info cut_in = pm.playbackOptions(q=1, min=1) cut_out = pm.playbackOptions(q=1, max=1) shot_task.cut_in = int(cut_in) shot_task.cut_out = int(cut_out) # save it m_env.save_as(versions[ind]) except: errored_shots.append(shot_info[2]) else: # store information to database DBSession.add(shot_task) DBSession.add(versions[ind]) DBSession.commit() ind += 1 caller.step() if errored_shots: message = 'Shots could not be saved:\r\n' message += '\r' for shot in errored_shots: message += '[ %s ]\n' % shot pm.confirmDialog(title='Error', message=message, button='OK') DBSession.rollback() raise RuntimeError( 'Some Shots could not be saved. Contact Mehmet ERER.') # leave it as empty new file pm.newFile(force=True) message = 'Previs to Shots\r\n' message += '\r' message += 'Completed Succesfully.\r\n' pm.confirmDialog(title='Info', message=message, button='OK')
task_from_db = Task.query.get(task_id) # now query the total_logged_seconds benchmark_start = time.time() total_logged_seconds = task_from_db.total_logged_seconds benchmark_end = time.time() print('total_logged_seconds: %s sec' % total_logged_seconds) print('old way worked in: %s sec' % (benchmark_end - benchmark_start)) # now use the new way of doing it benchmark_start = time.time() quick_total_logged_seconds = task_from_db.total_logged_seconds benchmark_end = time.time() print('quick_total_logged_seconds: %s sec' % quick_total_logged_seconds) print('new way worked in: %s sec' % (benchmark_end - benchmark_start)) assert total_logged_seconds == quick_total_logged_seconds # clean up test database DBSession.rollback() connection = DBSession.connection() engine = connection.engine connection.close() Base.metadata.drop_all(engine, checkfirst=True) DBSession.remove() stalker.defaults.timing_resolution = datetime.timedelta(hours=1) DBSession.close_all() drop_db(database_name)
def accept(self): """create/update the project """ # Name if not self.name_lineEdit.is_valid: QtWidgets.QMessageBox.critical( self, 'Error', 'Please fix <b>name</b> field!' ) return name = self.name_lineEdit.text() # Code if not self.code_lineEdit.is_valid: QtWidgets.QMessageBox.critical( self, 'Error', 'Please fix <b>code</b> field!' ) return code = self.code_lineEdit.text() # Type from stalker import Type index = self.type_comboBox.currentIndex() type_id = self.type_comboBox.itemData(index) type_ = Type.query.get(type_id) # None type is ok # Image Format image_format = self.image_format.get_current_image_format() if not image_format: QtWidgets.QMessageBox.critical( self, 'Error', 'Please select a valid <b>Image Format</b>!' ) return # FPS fps = self.fps_spinBox.value() # Repository repo = self.get_current_repository() if not repo: QtWidgets.QMessageBox.critical( self, 'Error', 'Please select a valid <b>Repository</b>!' ) return # Structure structure = self.get_current_structure() if not structure: QtWidgets.QMessageBox.critical( self, 'Error', 'Please select a valid <b>Structure</b>!' ) return # Status from stalker import Status index = self.status_comboBox.currentIndex() status_id = self.status_comboBox.itemData(index) status = Status.query.get(status_id) if not status: QtWidgets.QMessageBox.critical( self, 'Error', 'Please select a valid <b>Status</b>!' ) return # TODO: Add Client Data fields (which I don't care for now) logged_in_user = self.get_logged_in_user() # create or update project from stalker.db.session import DBSession if self.mode == 'Create': # create a new project from stalker import Project new_project = Project( name=name, code=code, type=type_, repositories=[repo], structure=structure, image_format=image_format, fps=fps, created_by=logged_in_user ) DBSession.add(new_project) try: DBSession.commit() except Exception as e: DBSession.rollback() QtWidgets.QMessageBox.critical( self, 'Error', str(e) ) return else: # update the project self.project.updated_by = logged_in_user self.project.name = name self.project.code = code self.project.type = type_ self.project.repositories = [repo] self.project.structure = structure self.project.image_format = image_format self.project.fps = fps self.project.status = status DBSession.add(self.project) try: DBSession.commit() except Exception as e: DBSession.rollback() QtWidgets.QMessageBox.critical( self, 'Error', str(e) ) return super(MainDialog, self).accept()