def remove_tasks(self): """removes the user from task """ task_ids = self.get_multi_integer(self.request, 'task_id') as_param = self.request.params.get('as', None) from stalker import Task # get the tasks that the user is a resource only task_filter = Task.query\ .filter(Task.id.in_(task_ids)) if as_param is None or as_param == 'resource': tasks = task_filter\ .filter(Task.resources.contains(self.entity))\ .all() for task in tasks: task.resources.remove(self.entity) elif as_param == 'responsible': tasks = task_filter\ .filter(Task.responsible.contains(self.entity))\ .all() for task in tasks: task.responsible.remove(self.entity) elif as_param == 'watcher': tasks = task_filter\ .filter(Task.watchers.contains(self.entity))\ .all() for task in tasks: task.watchers.remove(self.entity) from stalker.db.session import DBSession DBSession.flush()
def update_sequence(request): """runs when adding a new sequence """ logged_in_user = get_logged_in_user(request) sequence_id = request.params.get('sequence_id') sequence = Sequence.query.filter_by(id=sequence_id).first() name = request.params.get('name') code = request.params.get('code') status_id = request.params.get('status_id') status = Status.query.filter_by(id=status_id).first() if sequence and code and name and status: # get descriptions description = request.params.get('description') #update the sequence sequence.name = name sequence.code = code sequence.description = description sequence.status = status sequence.updated_by = logged_in_user sequence.date_updated = datetime.datetime.now() DBSession.add(sequence) else: logger.debug('there are missing parameters') logger.debug('name : %s' % name) logger.debug('status : %s' % status) HTTPServerError() return HTTPOk()
def test_OverbookedError_3(self): """testing if a OverBookedError will be raised when the resource is already booked for the given time period. Simple case diagram: ##### ####### """ # time_log1 kwargs = copy.copy(self.kwargs) kwargs["resource"] = self.test_resource2 kwargs["start"] = datetime.datetime(2013, 3, 22, 4, 0, tzinfo=pytz.utc) kwargs["duration"] = datetime.timedelta(8) time_log1 = TimeLog(**kwargs) from stalker.db.session import DBSession DBSession.add(time_log1) DBSession.commit() # time_log2 kwargs["duration"] = datetime.timedelta(10) from stalker.exceptions import OverBookedError with pytest.raises(OverBookedError) as cm: TimeLog(**kwargs) assert str(cm.value) == \ 'The resource has another TimeLog between %s and %s' % ( time_log1.start, time_log1.end )
def test_authenticate_updates_user_password_if_stalker_fails_but_ldap_successes(ldap_server, create_db, monkeypatch): """testing if the anima.utils.authenticate() will update the user password if stalker fails but ldap doesn't fail and the user exists """ from ldap3.extend import StandardExtendedOperations def mock_return(*arg, **kwargs): return "pipeline" monkeypatch.setattr(StandardExtendedOperations, "who_am_i", mock_return) # This is not working with mock server login = '******' ldap_password = '******' stalker_password = '******' # create a user in Stalker with a different password from stalker import User from stalker.db.session import DBSession new_user = User(login=login, password=stalker_password, email='*****@*****.**', name='Pipeline') DBSession.add(new_user) DBSession.commit() assert new_user.check_password(ldap_password) is False assert new_user.check_password(stalker_password) is True # now authenticate with the new password from anima.utils import authenticate result = authenticate(login, ldap_password) # result should be True assert result is True # and the password should be updated pipeline_user = User.query.filter(User.login==login).first() assert pipeline_user is not None assert new_user.check_password(ldap_password) is True assert new_user.check_password(stalker_password) is False
def test_status_list_attribute_is_skipped_and_there_is_a_db_setup_but_no_suitable_StatusList( self): """testing if a TypeError will be raised even a database is setup but there is no suitable StatusList for StatusListNoAutoAddClass in the database """ # create a StatusList for StatusListAutoAddClass test_status_list = StatusList( name="StatusListAutoAddClass Statuses", statuses=[ Status(name="Status1", code="Sts1"), Status(name="Status2", code="Sts2"), Status(name="Status3", code="Sts3"), ], target_entity_type=StatusListAutoAddClass, ) # add it to the db DBSession.add(test_status_list) DBSession.commit() # now try to create a StatusListAutoAddClass without a status_list # argument self.assertRaises( TypeError, StatusListNoAutoAddClass, **{"name": "Test StatusListNoAutoAddClass"} )
def fix_reference_namespace(cls): """fixes reference namespace """ ref_count = len(pm.listReferences(recursive=True)) if ref_count > 25: result = pm.windows.confirmBox( 'Fix Reference Namespace', 'You have %s references in your scene,\n' 'this will take too much time\n\nIs that Ok?' % ref_count ) if not result: return from stalker import LocalSession from anima.env import mayaEnv m = mayaEnv.Maya() local_session = LocalSession() logged_in_user = local_session.logged_in_user if not logged_in_user: raise RuntimeError('Please login before running the script') versions = m.fix_reference_namespaces() for version in versions: version.created_by = logged_in_user from stalker.db.session import DBSession DBSession.commit()
def setUp(self): """set the test """ super(SimpleEntityDBTester, self).setUp() from stalker import User import json self.test_user = User( name="Test User", login="******", email="*****@*****.**", password="******", generic_text=json.dumps({'Phone number': '123'}, sort_keys=True), ) from stalker.db.session import DBSession DBSession.add(self.test_user) DBSession.commit() import datetime import pytz self.date_created = \ datetime.datetime(2010, 10, 21, 3, 8, 0, tzinfo=pytz.utc) self.date_updated = self.date_created self.kwargs = { "name": "Test Entity", "code": "TstEnt", "description": "This is a test entity, and this is a proper \ description for it", "created_by": self.test_user, "updated_by": self.test_user, "date_created": self.date_created, "date_updated": self.date_updated, 'generic_text': json.dumps({'Phone number': '123'}, sort_keys=True), }
def create_statuses_and_status_lists(): """Creates the statuses needed for Project, Task, Asset, Shot and Sequence entities """ # Also create basic Status and status lists for # Project, Asset, Shot, Sequence # Project project_status_list = StatusList.query\ .filter_by(target_entity_type='Project').first() if not project_status_list: project_status_list = StatusList(name='Project Statuses', target_entity_type='Project') new = Status.query.filter_by(code='NEW').first() wip = Status.query.filter_by(code='WIP').first() cmpl = Status.query.filter_by(code='CMPL').first() # now use them in status lists project_status_list.statuses = [new, wip, cmpl] # Warning! Not using scoped_session here, it is the plain old session DBSession.add_all([ project_status_list, ]) DBSession.commit()
def test_tasks_are_correctly_scheduled_when_compute_resources_is_False( self): """testing if the tasks are correctly scheduled when the compute resources is False """ tjp_sched = TaskJugglerScheduler(compute_resources=False) from stalker import Studio test_studio = Studio(name='Test Studio', now=datetime.datetime(2013, 4, 16, 0, 0, tzinfo=pytz.utc)) test_studio.start = \ datetime.datetime(2013, 4, 16, 0, 0, tzinfo=pytz.utc) test_studio.end = datetime.datetime(2013, 4, 30, 0, 0, tzinfo=pytz.utc) test_studio.daily_working_hours = 9 from stalker.db.session import DBSession DBSession.add(test_studio) tjp_sched.studio = test_studio tjp_sched.schedule() DBSession.commit() # check if the task and project timings are all adjusted assert \ datetime.datetime(2013, 4, 16, 9, 0, tzinfo=pytz.utc) == \ self.test_proj1.computed_start assert \ datetime.datetime(2013, 4, 24, 10, 0, tzinfo=pytz.utc) == \ self.test_proj1.computed_end assert \ datetime.datetime(2013, 4, 16, 9, 0, tzinfo=pytz.utc) == \ self.test_task1.computed_start assert \ datetime.datetime(2013, 4, 18, 16, 0, tzinfo=pytz.utc) == \ self.test_task1.computed_end assert len(self.test_task1.computed_resources) == 2 assert self.test_task1.computed_resources[0] in \ [self.test_user1, self.test_user2, self.test_user3, self.test_user4, self.test_user5] assert self.test_task1.computed_resources[1] in \ [self.test_user1, self.test_user2, self.test_user3, self.test_user4, self.test_user5] assert \ datetime.datetime(2013, 4, 18, 16, 0, tzinfo=pytz.utc) == \ self.test_task2.computed_start assert \ datetime.datetime(2013, 4, 24, 10, 0, tzinfo=pytz.utc) == \ self.test_task2.computed_end assert len(self.test_task2.computed_resources) == 2 assert self.test_task2.computed_resources[0] in \ [self.test_user1, self.test_user2, self.test_user3, self.test_user4, self.test_user5] assert self.test_task2.computed_resources[1] in \ [self.test_user1, self.test_user2, self.test_user3, self.test_user4, self.test_user5]
def test_version_number_attribute_is_set_to_a_lower_then_it_should_be(self): """testing if the version_number attribute will be set to a correct unique value when it is set to a lower number then it should be """ self.test_version.version_number = -1 self.assertEqual(self.test_version.version_number, 1) self.test_version.version_number = -10 self.assertEqual(self.test_version.version_number, 1) DBSession.add(self.test_version) DBSession.commit() self.test_version.version_number = -100 # it should be 1 again self.assertEqual(self.test_version.version_number, 1) new_version = Version(**self.kwargs) self.assertEqual(new_version.version_number, 2) new_version.version_number = 1 self.assertEqual(new_version.version_number, 2) new_version.version_number = 100 self.assertEqual(new_version.version_number, 100)
def accept(self): """overridden accept method """ # get the project try: project_id = self.projects_combo_box.currentData() except AttributeError: index = self.projects_combo_box.currentIndex() project_id = self.projects_combo_box.itemData(index) from stalker import Project project = Project.query.get(project_id) # get the users user_names = [ item.text() for item in self.users_double_list_widget.secondary_items() ] from stalker import User if user_names: users = User.query.filter(User.name.in_(user_names)) else: users = [] # set the project users project.users = users from stalker.db.session import DBSession DBSession.commit() super(MainDialog, self).accept()
def test_update_paths_will_preserve_extension(self): """testing if update_paths method will preserve the extension. """ # create a FilenameTemplate for Task instances ft = FilenameTemplate( name="Task Filename Template", target_entity_type="Task", path="{{project.code}}/{%- for parent_task in parent_tasks -%}" "{{parent_task.nice_name}}/{%- endfor -%}", filename="{{task.nice_name}}_{{version.take_name}}" '_v{{"%03d"|format(version.version_number)}}{{extension}}', ) self.test_project.structure.templates.append(ft) new_version1 = Version(**self.kwargs) DBSession.add(new_version1) DBSession.commit() new_version1.update_paths() self.assertEqual(new_version1.path, "tp/SH001/Task1") extension = ".ma" new_version1.extension = extension self.assertEqual(new_version1.filename, "Task1_TestTake_v001.ma") # rename the task and update the paths self.test_task1.name = "Task2" # now call update_paths and expect the extension to be preserved new_version1.update_paths() self.assertEqual(new_version1.filename, "Task2_TestTake_v001.ma") self.assertEqual(new_version1.extension, extension)
def tearDown(self): os.rmdir(self.test_repo.linux_path) os.rmdir(self.test_repo.windows_path) os.rmdir(self.test_repo.osx_path) DBSession.remove() testing.tearDown()
def test_logged_in_user_returns_the_stored_User_instance_from_last_time( self): """testing if logged_in_user returns the logged in user """ # create a new user from stalker import User new_user = User(name='Test User', login='******', email='*****@*****.**', password='******') # save it to the Database from stalker.db.session import DBSession DBSession.add(new_user) DBSession.commit() assert new_user.id is not None # save it to the local storage from stalker import LocalSession local_session = LocalSession() local_session.store_user(new_user) # save the session local_session.save() # now get it back with a new local_session local_session2 = LocalSession() assert local_session2.logged_in_user_id == new_user.id assert local_session2.logged_in_user == new_user
def set_shot_from_range(self, version): """sets the Shot.cut_in and Shot.cut_out attributes from the current frame range if the current task is related to a Stalker Shot instance. :param Stalker.Version version: A Stalker Version instance. :return: """ # check if this is a shot related task is_shot_related_task = False shot = None from stalker import Shot for task in version.task.parents: if isinstance(task, Shot): is_shot_related_task = True shot = task break if is_shot_related_task and shot: # set frame ranges cut_in, cut_out = self.get_frame_range() shot.cut_in = int(cut_in) shot.cut_out = int(cut_out) from stalker.db.session import DBSession DBSession.add(shot) DBSession.commit()
def loads(self, data): """Decodes Stalker data :param data: :return: """ from stalker.db.session import DBSession from stalker import Asset, Task, Shot, Sequence, Version, Type if isinstance(data, str): data = json.loads(data) # get the entity_type entity_type = data['entity_type'] # set default entity class to Task entity_class = Task if entity_type == 'Asset': entity_class = Asset elif entity_type == 'Shot': entity_class = Shot # this is a bug data['sequences'] = [] elif entity_type == 'Sequence': entity_class = Sequence version_data = data['versions'] data['versions'] = [] # get the type if 'type' in data: type_data = data['type'] if type_data: type_name = type_data['name'] type_ = Type.query.filter(Type.name == type_name).first() if not type_: # create a Type type_ = Type(**type_data) data['type'] = type_ data['project'] = self.project entity = entity_class(**data) DBSession.add(entity) DBSession.commit() # create Versions if version_data: for v_data in version_data: # get Version info v_data['task'] = entity v = Version(**v_data) # update version_number v.version_number = v_data['version_number'] v.is_published = v_data['is_published'] # for each child task call a new StalkerEntityDecoder for t in data['tasks']: child_task = self.loads(t) entity.tasks.append(child_task) return entity
def get_entity(self): """returns one Structure instance data as JSON """ response = super(StructureViews, self).get_entity() from stalker import Structure from stalker.db.session import DBSession r = DBSession.query(Structure.custom_template)\ .filter(Structure.id == self.entity_id)\ .first() # get template counts from stalker.models.structure import Structure_FilenameTemplates template_count = \ DBSession.query( Structure_FilenameTemplates.c.filenametemplate_id ).filter( Structure_FilenameTemplates.c.structure_id == self.entity_id ).count() from stalker_pyramid import entity_type_to_url data = { 'custom_template': r[0], 'templates': { '$ref': '%s/%s/templates' % (entity_type_to_url['Structure'], self.entity_id), 'length': template_count } } return self.update_response_data(response, data)
def setUp(self): """setup the test """ super(RepositoryTester, self).setUp() self.patcher = PlatformPatcher() # create a couple of test tags from stalker import Tag self.test_tag1 = Tag(name="test tag 1") self.test_tag2 = Tag(name="test tag 2") self.kwargs = { "name": "a repository", "description": "this is for testing purposes", "tags": [self.test_tag1, self.test_tag2], "linux_path": "/mnt/M/Projects", "osx_path": "/Volumes/M/Projects", "windows_path": "M:/Projects" } from stalker import Repository from stalker.db.session import DBSession self.test_repo = Repository(**self.kwargs) DBSession.add(self.test_repo) DBSession.commit()
def test_status_list_attribute_is_skipped_and_there_is_a_db_setup_but_no_suitable_StatusList( self): """testing if a TypeError will be raised even a database is setup but there is no suitable StatusList for StatusListNoAutoAddClass in the database """ # create a StatusList for StatusListAutoAddClass test_status_list = StatusList( name="StatusListAutoAddClass Statuses", statuses=[ Status(name="Status1", code="Sts1"), Status(name="Status2", code="Sts2"), Status(name="Status3", code="Sts3"), ], target_entity_type=StatusListAutoAddClass, ) # add it to the db from stalker.db.session import DBSession DBSession.add(test_status_list) DBSession.commit() # now try to create a StatusListAutoAddClass without a status_list # argument with pytest.raises(TypeError) as cm: StatusListNoAutoAddClass(name="Test StatusListNoAutoAddClass") assert str(cm.value) == \ "StatusListNoAutoAddClass instances can not be initialized " \ "without a stalker.models.status.StatusList instance, please " \ "pass a suitable StatusList " \ "(StatusList.target_entity_type=StatusListNoAutoAddClass) with " \ "the 'status_list' argument"
def test_status_list_attribute_is_skipped_and_there_is_a_db_setup(self): """testing if there will be no error and the status_list attribute is filled with the correct StatusList instance coming from the database if there is already a database setup and there is a StatusList instance defined for the StatusListAutoAddClass. """ # create a StatusList for StatusListAutoAddClass test_status_list = StatusList( name="StatusListAutoAddClass Statuses", statuses=[ Status(name="Status1", code="Sts1"), Status(name="Status2", code="Sts2"), Status(name="Status3", code="Sts3"), ], target_entity_type=StatusListAutoAddClass, ) # add it to the db DBSession.add(test_status_list) DBSession.commit() # now try to create a StatusListAutoAddClass without a status_list # argument test_StatusListAutoAddClass = StatusListAutoAddClass( name="Test StatusListAutoAddClass", ) # now check if the status_list is equal to test_status_list self.assertEqual( test_StatusListAutoAddClass.status_list, test_status_list )
def test_stalker_entity_decoder_will_not_create_existing_tasks(create_db, create_empty_project): """testing if JSON decoder will not recreate existing data """ from stalker import Task project = create_empty_project import json from anima.utils import task_hierarchy_io global __here__ file_path = os.path.join(__here__, "data", "test_template3.json") with open(file_path) as f: data = json.load(f) decoder = \ task_hierarchy_io.StalkerEntityDecoder( project=project ) loaded_entity = decoder.loads(data) from stalker.db.session import DBSession DBSession.add(loaded_entity) DBSession.commit() # now there should be only one Assets task from stalker import Task assets_tasks = Task.query.filter(Task.name=='Assets').all() assert len(assets_tasks) == 1
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 setup(settings=None): """Utility function that helps to connect the system to the given database. if the database is None then the it setups using the default database in the settings file. :param settings: This is a dictionary which has keys prefixed with "sqlalchemy" and shows the settings. The most important one is the engine. The default is None, and in this case it uses the settings from stalker.config.Config.database_engine_settings """ if settings is None: settings = defaults.database_engine_settings logger.debug("no settings given, using the default: %s" % settings) logger.debug("settings: %s" % settings) # create engine engine = engine_from_config(settings, "sqlalchemy.") logger.debug("engine: %s" % engine) # create the Session class DBSession.remove() DBSession.configure(bind=engine, extension=None) # create the database logger.debug("creating the tables") Base.metadata.create_all(engine) # update defaults update_defaults_with_studio()
def test_committing_data(self): """testing committing and retrieving data back """ kwargs = copy.copy(self.kwargs) d1 = DAGMixinFooMixedInClass(**kwargs) d2 = DAGMixinFooMixedInClass(**kwargs) d3 = DAGMixinFooMixedInClass(**kwargs) d4 = DAGMixinFooMixedInClass(**kwargs) d1.children = [d2, d3] d2.children = [d4] from stalker.db.session import DBSession DBSession.add_all([d1, d2, d3, d4]) DBSession.commit() del d1, d2, d3, d4 all_data = DAGMixinFooMixedInClass.query.all() assert len(all_data) == 4 assert isinstance(all_data[0], DAGMixinFooMixedInClass) assert isinstance(all_data[1], DAGMixinFooMixedInClass) assert isinstance(all_data[2], DAGMixinFooMixedInClass) assert isinstance(all_data[3], DAGMixinFooMixedInClass)
def test_start_end_and_duration_values_are_rounded_to_the_Studio_timing_resolution( self): """testing if the start and end dates are rounded to the Studio timing_resolution """ import logging logging.getLogger('stalker.models.studio').setLevel(logging.DEBUG) from stalker.models.studio import Studio studio = Studio(name='Test Studio', timing_resolution=datetime.timedelta(minutes=5)) from stalker.db.session import DBSession DBSession.add(studio) DBSession.commit() self.kwargs['start'] = \ datetime.datetime(2013, 3, 22, 2, 38, 55, 531, tzinfo=pytz.utc) self.kwargs['end'] = \ datetime.datetime(2013, 3, 24, 16, 46, 32, 102, tzinfo=pytz.utc) new_foo_obj = DateRangeMixFooMixedInClass(**self.kwargs) # check the start expected_start = \ datetime.datetime(2013, 3, 22, 2, 40, tzinfo=pytz.utc) assert new_foo_obj.start == expected_start # check the end expected_end = \ datetime.datetime(2013, 3, 24, 16, 45, tzinfo=pytz.utc) assert new_foo_obj.end == expected_end # check the duration assert new_foo_obj.duration == expected_end - expected_start
def get_entity(self): """return one StatusList instance as json """ sql = """select "StatusLists".target_entity_type from "StatusLists" where "StatusLists".id = :id """ from sqlalchemy import text from stalker.db.session import DBSession conn = DBSession.connection() result = conn.execute(text(sql), id=self.entity_id) r = result.fetchone() # get statuses count from stalker.models.status import StatusList_Statuses statuses_count = DBSession.query(StatusList_Statuses.c.status_id)\ .filter(StatusList_Statuses.c.status_list_id == self.entity_id)\ .count() from stalker_pyramid import entity_type_to_url data = { 'statuses': { '$ref': '%s/%s/statuses' % (entity_type_to_url['StatusList'], self.entity_id), 'length': statuses_count }, 'target_entity_type': r[0] } # update with super data response = super(StatusListViews, self).get_entity() return self.update_response_data(response, data)
def create_good(request): """creates a new Good """ logger.debug('***create good method starts ***') logged_in_user = get_logged_in_user(request) utc_now = local_to_utc(datetime.datetime.now()) came_from = request.params.get('came_from', '/') name = request.params.get('name', None) msrp = request.params.get('msrp', None) unit = request.params.get('unit', None) cost = request.params.get('cost', None) price_list_name = request.params.get('price_list_name', None) logger.debug('came_from : %s' % came_from) logger.debug('name : %s' % name) logger.debug('msrp : %s' % msrp) logger.debug('unit : %s' % unit) logger.debug('cost : %s' % cost) logger.debug('price_list_name : %s' % price_list_name) # create and add a new good if name and msrp and unit and cost and price_list_name: price_list = query_price_list(price_list_name) try: # create the new group new_good = Good(name=name, msrp=int(msrp), unit=unit, cost=int(cost), price_lists=[price_list]) new_good.created_by = logged_in_user new_good.date_created = utc_now new_good.date_updated = utc_now new_good.price_lists = [price_list] DBSession.add(new_good) logger.debug('added new good successfully') request.session.flash('success:Good <strong>%s</strong> is ' 'created successfully' % name) logger.debug('***create good method ends ***') except BaseException as e: request.session.flash('error: %s' % e) HTTPFound(location=came_from) else: logger.debug('not all parameters are in request.params') transaction.abort() return Response('There are missing parameters: ' 'name: %s' % name, 500) return Response('successfully created %s!' % name)
def _set_defaults(self): """setup the default values """ # set size policies # self.name_lineEdit self.type_comboBox.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) self.status_comboBox.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) self.client_comboBox.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) self.agency_comboBox.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) self.production_company_comboBox.setSizePolicy( QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) # invalidate the name and code fields by default self.name_lineEdit.set_invalid('Enter a name') self.code_lineEdit.set_invalid('Enter a code') # update type field from stalker import Type from stalker.db.session import DBSession project_types = \ DBSession.query(Type.id, Type.name)\ .filter(Type.target_entity_type == 'Project')\ .order_by(Type.name)\ .all() self.type_comboBox.clear() self.type_comboBox.addItem('', -1) for type_id, type_name in project_types: self.type_comboBox.addItem(type_name, type_id) self.image_format.fill_combo_box() self.fill_repository_combo_box() self.fill_structure_combo_box() # fill status field sql = """select "SimpleEntities".id, "SimpleEntities".name from "Statuses" join "SimpleEntities" on "Statuses".id = "SimpleEntities".id join "StatusList_Statuses" on "Statuses".id = "StatusList_Statuses".status_id join "StatusLists" on "StatusLists".id = "StatusList_Statuses".status_list_id where "StatusLists".target_entity_type = 'Project'""" all_project_statuses = \ DBSession.connection().execute(sql).fetchall() for st_id, st_name in all_project_statuses: self.status_comboBox.addItem(st_name, st_id)
def setUp(self): """set up the test """ db.setup() db.init() self.temp_path = tempfile.mkdtemp() self.repo = Repository( name='Test Repository', linux_path=self.temp_path, windows_path=self.temp_path, osx_path=self.temp_path ) self.status_new = Status.query.filter_by(code='NEW').first() self.status_wip = Status.query.filter_by(code='WIP').first() self.status_cmpl = Status.query.filter_by(code='CMPL').first() self.project_status_list = \ StatusList.query.filter_by(target_entity_type='Project').first() self.task_filename_template = FilenameTemplate( name='Task Filename Template', target_entity_type='Task', path='{{project.code}}/{%- for parent_task in parent_tasks -%}' '{{parent_task.nice_name}}/{%- endfor -%}', filename='{{version.nice_name}}' '_v{{"%03d"|format(version.version_number)}}{{extension}}' ) self.project_structure = Structure( name='Project Structure', templates=[self.task_filename_template] ) self.project = Project( name='Test Project', code='TP', status_list=self.project_status_list, repository=self.repo, structure=self.project_structure ) self.task = Task( name='Test Task', project=self.project ) from stalker.db.session import DBSession DBSession.add(self.task) DBSession.commit() self.version = Version( task=self.task ) self.kwargs = { 'name': 'Photoshop', 'extensions': ['psd'], 'structure': ['Outputs'] } self.external_env = ExternalEnv(**self.kwargs)
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 tearDownClass(cls): """teardown once """ from anima import defaults shutil.rmtree(defaults.local_storage_path, True) shutil.rmtree(cls.repo_path) # configure with transaction manager DBSession.remove()
def test_tasks_are_correctly_scheduled(self): """testing if the tasks are correctly scheduled """ tjp_sched = TaskJugglerScheduler(compute_resources=True) from stalker import Studio test_studio = Studio( name='Test Studio', now=datetime.datetime(2013, 4, 16, 0, 0, tzinfo=pytz.utc) ) test_studio.start = \ datetime.datetime(2013, 4, 16, 0, 0, tzinfo=pytz.utc) test_studio.end = \ datetime.datetime(2013, 4, 30, 0, 0, tzinfo=pytz.utc) test_studio.daily_working_hours = 9 from stalker.db.session import DBSession DBSession.add(test_studio) tjp_sched.studio = test_studio tjp_sched.schedule() DBSession.commit() # check if the task and project timings are all adjusted assert \ datetime.datetime(2013, 4, 16, 9, 0, tzinfo=pytz.utc) == \ self.test_proj1.computed_start assert \ datetime.datetime(2013, 4, 24, 10, 0, tzinfo=pytz.utc) == \ self.test_proj1.computed_end assert \ datetime.datetime(2013, 4, 16, 9, 0, tzinfo=pytz.utc) == \ self.test_task1.computed_start assert \ datetime.datetime(2013, 4, 18, 16, 0, tzinfo=pytz.utc) == \ self.test_task1.computed_end assert \ sorted([self.test_user1, self.test_user2], key=lambda x: x.name) == \ sorted(self.test_task1.computed_resources, key=lambda x: x.name) assert \ datetime.datetime(2013, 4, 18, 16, 0, tzinfo=pytz.utc) == \ self.test_task2.computed_start assert \ datetime.datetime(2013, 4, 24, 10, 0, tzinfo=pytz.utc) == \ self.test_task2.computed_end assert len(self.test_task2.computed_resources) == 2 possible_resources = [ self.test_user2, self.test_user3, self.test_user4, self.test_user5 ] for r in self.test_task2.computed_resources: assert r in possible_resources
def setUp(self): """setup the test """ super(SceneTester, self).setUp() # create a test project, user and a couple of shots from stalker import Type self.project_type = Type( name="Test Project Type", code='test', target_entity_type='Project', ) # create a repository self.repository_type = Type( name="Test Type", code='test', target_entity_type='Repository' ) from stalker import Repository self.test_repository = Repository( name="Test Repository", type=self.repository_type, ) # create projects from stalker import Project self.test_project = Project( name="Test Project 1", code='tp1', type=self.project_type, repository=self.test_repository, ) self.test_project2 = Project( name="Test Project 2", code='tp2', type=self.project_type, repository=self.test_repository, ) # the parameters self.kwargs = { "name": "Test Scene", 'code': 'tsce', "description": "A test scene", "project": self.test_project, } # the test sequence self.test_scene = Scene(**self.kwargs) from stalker.db.session import DBSession DBSession.add(self.test_scene) DBSession.commit()
def delete_budgetentry_action(budgetentry): logger.debug('delete_budgetentry_action %s' % budgetentry.name) budgetentry_name = budgetentry.name try: DBSession.delete(budgetentry) transaction.commit() except Exception as e: transaction.abort() c = StdErrToHTMLConverter(e) transaction.abort()
def export_as(self, version): """the export action for max environment """ import MaxPlus # check if there is something selected if MaxPlus.SelectionManager.GetCount() < 1: raise RuntimeError("There is nothing selected to export") # check if this is the first version if version.is_published and not self.allow_publish_on_export: # it is not allowed to publish the first version (desdur) raise RuntimeError( 'It is not allowed to Publish while export!!!' '<br><br>' 'Export it normally. Then open the file and publish it.' ) # do not save if there are local files # self.check_external_files(version) # set the extension to max by default version.update_paths() version.extension = self.extensions[0] # define that this version is created with Max version.created_with = self.name # create the folder if it doesn't exists import os try: os.makedirs(version.absolute_path) except OSError: # already exists pass # workspace_path = os.path.dirname(version.absolute_path) workspace_path = version.absolute_path # self.create_workspace_file(workspace_path) # self.create_workspace_folders(workspace_path) # export the file MaxPlus.FileManager.SaveSelected(version.absolute_full_path) # save the version to database from stalker.db.session import DBSession DBSession.add(version) DBSession.commit() # create a local copy self.create_local_copy(version) return True
def test_timeLog_prevents_auto_flush_when_expanding_task_schedule_timing(self): """testing timeLog prevents auto flush when expanding task schedule_timing attribute """ from stalker.db.session import DBSession tlog1 = TimeLog(**self.kwargs) DBSession.add(tlog1) DBSession.commit() # create a new time log self.kwargs['start'] = self.kwargs['start'] + self.kwargs['duration'] tlog2 = TimeLog(**self.kwargs)
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 __create_admin__(): """creates the admin """ from stalker.models.auth import User from stalker.models.department import Department # check if there is already an admin in the database admin = User.query.filter_by(name=defaults.admin_name).first() if admin: # there should be an admin user do nothing logger.debug("there is an admin already") return logger.debug("creating the default administrator user") # create the admin department admin_department = Department.query.filter_by(name=defaults.admin_department_name).first() if not admin_department: admin_department = Department(name=defaults.admin_department_name) DBSession.add(admin_department) # create the admins group from stalker.models.auth import Group admins_group = Group.query.filter_by(name=defaults.admin_group_name).first() if not admins_group: admins_group = Group(name=defaults.admin_group_name) DBSession.add(admins_group) # # create the admin user # admin = User.query \ # .filter_by(name=defaults.admin_name) \ # .first() # if not admin: admin = User( name=defaults.admin_name, login=defaults.admin_login, password=defaults.admin_password, email=defaults.admin_email, departments=[admin_department], groups=[admins_group], ) admin.created_by = admin admin.updated_by = admin # update the department as created and updated by admin user admin_department.created_by = admin admin_department.updated_by = admin admins_group.created_by = admin admins_group.updated_by = admin DBSession.add(admin) DBSession.commit()
def list_all(self): """lists other representations """ base_take_name = self.get_base_take_name(self.version) # find any version that starts with the base_repr_name # under the same task from stalker import Version from stalker.db.session import DBSession from sqlalchemy import distinct take_names = map( lambda x: x[0], DBSession.query(distinct(Version.take_name)) .filter(Version.task == self.version.task) .all() ) take_names.sort() repr_names = [] for take_name in take_names: if take_name.startswith(base_take_name): if take_name != base_take_name: repr_names.append( take_name[len(base_take_name) + len(self.repr_separator):] ) else: repr_names.append(self.base_repr_name) return repr_names
def get_filtered_entities(self): """returns the filtered entities according to the filter selection """ project_id = self.get_project_id() entity_type = self.filter_by_entity_type_combo_box.currentText() sequence_id = self.get_sequence_id() task_type_id = self.get_task_type_id() resource_id = self.get_resource_id() from stalker import db, Task from stalker.db.session import DBSession query = DBSession.query(Task.id, Task.name) if project_id != -1: query = query.filter(Task.project_id == project_id) if task_type_id != -1: query = query.filter(Task.type_id == task_type_id) if entity_type != self.generic_selection_text: query = query.filter(Task.entity_type == entity_type) # if entity_type == 'Shot': # from stalker.models.shot import Shot_Sequences # query = query.filter(Shot_Sequences) # query the child tasks query = query.order_by(Task.name) return query.all()
def project_changed(self, project_name): """runs when the project in the combo box changed """ try: project_id = self.projects_combo_box.currentData() except AttributeError: index = self.projects_combo_box.currentIndex() project_id = self.projects_combo_box.itemData(index) # refresh the items on the double list widget self.users_double_list_widget.clear() # get users not in the project from stalker.db.session import DBSession from stalker import User from stalker.models.project import ProjectUser project_users = DBSession.query(User.id, User.name).join(ProjectUser)\ .filter(ProjectUser.project_id == project_id)\ .filter(User.id == ProjectUser.user_id)\ .all() project_user_ids = [u.id for u in project_users] if project_user_ids: users_not_in_project = [ u.name for u in DBSession.query(User.name) .filter(~User.id.in_(project_user_ids)).all() ] else: users_not_in_project = [ u.name for u in DBSession.query(User.name).all() ] self.users_double_list_widget.add_primary_items( users_not_in_project ) users_in_project = \ [u.name for u in project_users] self.users_double_list_widget.add_secondary_items( users_in_project )
def setUp(self): self.config = testing.setUp() db.setup({'sqlalchemy.url': 'sqlite:///:memory:'}) self.test_status1 = Status(name='Test Status 1', code='TS1') self.test_status2 = Status(name='Test Status 2', code='TS2') self.test_status3 = Status(name='Test Status 3', code='TS3') self.test_project_status_list = StatusList( target_entity_type='Project', statuses=[ self.test_status1, self.test_status2, self.test_status3 ] ) self.test_repo = Repository( name='Test Repository', windows_path='T:/', linux_path='/mnt/T', osx_path='/Volumes/T' ) self.test_project = Project( name='Test Project 1', code='TP1', status_list=self.test_project_status_list, repository=self.test_repo ) DBSession.add(self.test_project) transaction.commit() DBSession.add(self.test_project) self.params = { 'mode': 'CREATE' } self.matchdict = { 'project_id': self.test_project.id } self.request = testing.DummyRequest(params=self.params) self.request.matchdict = self.matchdict
def get_current_resource_id(self): """returns the current resource """ resource_name = self.resource_combo_box.currentText() from stalker import User from stalker.db.session import DBSession return DBSession.query(User.id)\ .filter(User.name == resource_name)\ .first()
def login(self): """does the nasty details for user to login """ # check the given user password from stalker import User # get the user first login = self.login_or_email_lineEdit.text() password = self.password_lineEdit.text() # check with the login or email attribute user = User.query \ .filter(or_(User.login == login, User.email == login)) \ .first() if user: self.success = user.check_password(password) if self.success: from stalker.models.auth import LocalSession session = LocalSession() session.store_user(user) session.save() # also store a log import datetime from stalker.models.auth import LOGIN, AuthenticationLog al = AuthenticationLog( user=user, date=datetime.datetime.now(), action=LOGIN ) from stalker.db.session import DBSession DBSession.add(al) DBSession.commit() self.accept() else: QtWidgets.QMessageBox.critical( self, "Error", "login or password is incorrect" )
def setup(settings=None): """Utility function that helps to connect the system to the given database. if the database is None then the it setups using the default database in the settings file. :param settings: This is a dictionary which has keys prefixed with "sqlalchemy" and shows the settings. The most important one is the engine. The default is None, and in this case it uses the settings from stalker.config.Config.database_engine_settings """ if settings is None: settings = defaults.database_engine_settings logger.debug('no settings given, using the default: %s' % settings) logger.debug("settings: %s" % settings) # create engine engine = engine_from_config(settings, 'sqlalchemy.') logger.debug('engine: %s' % engine) # create the Session class DBSession.remove() DBSession.configure( bind=engine, extension=None ) # check alembic versions of the database # and raise an error if it is not matching with the system check_alembic_version() # create the database logger.debug("creating the tables") Base.metadata.create_all(engine) # update defaults update_defaults_with_studio() # create repo env variables create_repo_vars()
def test_absolute_full_path_works_properly(self): """testing if the absolute_full_path attribute works properly """ ft = FilenameTemplate( name="Task Filename Template", target_entity_type="Task", path="{{project.code}}/{%- for parent_task in parent_tasks -%}" "{{parent_task.nice_name}}/{%- endfor -%}", filename="{{task.nice_name}}_{{version.take_name}}" '_v{{"%03d"|format(version.version_number)}}{{extension}}', ) self.test_project.structure.templates.append(ft) new_version1 = Version(**self.kwargs) DBSession.add(new_version1) DBSession.commit() new_version1.update_paths() new_version1.extension = ".ma" self.assertEqual(new_version1.extension, ".ma") self.assertEqual(new_version1.absolute_full_path, "/mnt/T/tp/SH001/Task1/Task1_TestTake_v001.ma")
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 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 upload_thumbnail(task, thumbnail_full_path): """Uploads the given thumbnail for the given entity :param task: An instance of :class:`~stalker.models.entity.SimpleEntity` or a derivative. :param str thumbnail_full_path: A string which is showing the path of the thumbnail image """ extension = os.path.splitext(thumbnail_full_path)[-1] # move the file to the task thumbnail folder # and mimic StalkerPyramids output format thumbnail_original_file_name = 'thumbnail%s' % extension thumbnail_final_full_path = os.path.join( task.absolute_path, 'Thumbnail', thumbnail_original_file_name ) try: os.makedirs(os.path.dirname(thumbnail_final_full_path)) except OSError: pass # # convert the thumbnail to jpg if it is a format that is not supported by # # browsers # ext_not_supported_by_browsers = ['.bmp', '.tga', '.tif', '.tiff', '.exr'] # if extension in ext_not_supported_by_browsers: # # use MediaManager to convert them # from anima.utils import MediaManager # mm = MediaManager() # thumbnail_full_path = mm.generate_image_thumbnail(thumbnail_full_path) shutil.copy(thumbnail_full_path, thumbnail_final_full_path) from stalker import Link, Version, Repository thumbnail_os_independent_path = \ Repository.to_os_independent_path(thumbnail_final_full_path) l_thumb = Link.query\ .filter(Link.full_path == thumbnail_os_independent_path).first() if not l_thumb: l_thumb = Link( full_path=thumbnail_os_independent_path, original_filename=thumbnail_original_file_name ) task.thumbnail = l_thumb # get a version of this Task from stalker.db.session import DBSession v = Version.query.filter(Version.task == task).first() if v: for naming_parent in v.naming_parents: if not naming_parent.thumbnail: naming_parent.thumbnail = l_thumb DBSession.add(naming_parent) DBSession.add(l_thumb) DBSession.commit()
def user_names_lut(self): """fills the _user_names_lut """ if not self._user_names_lut: from anima.utils import do_db_setup do_db_setup() from stalker import User from stalker.db.session import DBSession map( lambda x: self._user_names_lut.__setitem__(x[0], x[1]), DBSession.query(User.id, User.name).all() ) return self._user_names_lut
def test_number_attribute_is_automatically_increased(self): """testing if the number attribute is automatically increased """ # create two new tickets ticket1 = Ticket(**self.kwargs) DBSession.add(ticket1) DBSession.commit() ticket2 = Ticket(**self.kwargs) DBSession.add(ticket2) DBSession.commit() self.assertEqual(ticket1.number + 1, ticket2.number) self.assertEqual(ticket1.number, 2) self.assertEqual(ticket2.number, 3)
def test_start_end_and_duration_values_are_rounded_to_the_Studio_timing_resolution(self): """testing if the start and end dates are rounded to the Studio timing_resolution """ from stalker.models.studio import Studio studio = Studio( name='Test Studio', timing_resolution=datetime.timedelta(minutes=5) ) DBSession.add(studio) DBSession.commit() self.kwargs['start'] = datetime.datetime(2013, 3, 22, 2, 38, 55, 531) self.kwargs['end'] = datetime.datetime(2013, 3, 24, 16, 46, 32, 102) new_foo_obj = DateRangeMixFooMixedInClass(**self.kwargs) # check the start expected_start = datetime.datetime(2013, 3, 22, 2, 40) self.assertEqual(new_foo_obj.start, expected_start) # check the end expected_end = datetime.datetime(2013, 3, 24, 16, 45) self.assertEqual(new_foo_obj.end, expected_end) # check the duration self.assertEqual(new_foo_obj.duration, expected_end - expected_start)
def update_version_inputs(self, parent_ref=None): """updates the references list of the current version :param parent_ref: the parent ref, if given will override the given version argument and a Version instance will be get from the given parent_ref.path. """ logger.debug('parent_ref: %s' % parent_ref) logger.debug('get a version') if not parent_ref: logger.debug('got no parent_ref') version = self.get_current_version() else: logger.debug('have a parent_ref') version = self.get_version_from_full_path(parent_ref.path) if version: logger.debug('got a version: %s' % version.absolute_full_path) # use the original version if it is a Repr version from anima.representation import Representation if Representation.repr_separator in version.take_name \ and version.parent: version = version.parent logger.debug( 'this is a representation switching to its parent: %s' % version ) # update the reference list referenced_versions = self.get_referenced_versions(parent_ref) version.inputs = referenced_versions # commit data to the database from stalker.db.session import DBSession DBSession.add(version) DBSession.commit()
def reference(self, version, use_namespace=True): """Creates an XRef for the given version in the current scene. :param version: The Stalker Verison instance. :param bool use_namespace: Use a namespace or not. :return: """ import os from anima.representation import Representation import pymxs rt = pymxs.runtime file_full_path = version.absolute_full_path namespace = os.path.basename(version.nice_name) namespace = namespace.split(Representation.repr_separator)[0] xref_objects = rt.getMAXFileObjectNames(file_full_path) xref = rt.xrefs.addNewXRefObject( file_full_path, xref_objects, # dupMtlNameAction='#autoRename' ) # append the referenced version to the current versions references # attribute current_version = self.get_current_version() if current_version: current_version.inputs.append(version) from stalker.db.session import DBSession DBSession.commit() # append it to reference path self.append_to_recent_files(file_full_path) return xref
def test_nice_name_attribute_is_working_properly(self): """testing if the nice_name attribute is working properly """ # for self.test_version self.assertEqual(self.test_version.naming_parents, [self.test_shot1, self.test_task1]) # for a new version of a task task1 = Task(name="Test Task 1", project=self.test_project, status_list=self.test_task_status_list) task2 = Task(name="Test Task 2", parent=task1, status_list=self.test_task_status_list) task3 = Task(name="Test Task 3", parent=task2, status_list=self.test_task_status_list) DBSession.add_all([task1, task2, task3]) DBSession.commit() version1 = Version(task=task3, take_name="Take1") DBSession.add(version1) DBSession.commit() self.assertEqual( version1.nice_name, "%s_%s_%s_%s" % (task1.nice_name, task2.nice_name, task3.nice_name, version1.take_name) ) # for a an asset version asset_statuses = StatusList( target_entity_type="Asset", statuses=[self.test_status1, self.test_status2, self.test_status3] ) character_type = Type(target_entity_type="Asset", name="Character", code="Char") asset1 = Asset(name="Asset1", code="Asset1", parent=task1, status_list=asset_statuses, type=character_type) version2 = Version(task=asset1) self.assertEqual(version2.nice_name, "%s_%s" % (asset1.nice_name, version2.take_name)) # for a version of a task of a shot shot2 = Shot(name="SH002", code="SH002", parent=task3, status_list=self.test_shot_status_list) task4 = Task(name="Test Task 4", parent=shot2, status_list=self.test_task_status_list) version3 = Version(task=task4) self.assertEqual(version3.nice_name, "%s_%s_%s" % (shot2.nice_name, task4.nice_name, version3.take_name)) # for an asset of a shot asset2 = Asset(name="Asset2", code="Asset2", parent=shot2, status_list=asset_statuses, type=character_type) version4 = Version(task=asset2) self.assertEqual(version4.nice_name, "%s_%s" % (asset2.nice_name, version4.take_name))
def fill(self): """fills the tree view with data """ logger.debug('start filling tasks_treeView') logger.debug('creating a new model') if not self.project: from sqlalchemy import alias from stalker import Task, Project from stalker.db.session import DBSession # projects = Project.query.order_by(Project.name).all() inner_tasks = alias(Task.__table__) subquery = DBSession.query(inner_tasks.c.id).filter( inner_tasks.c.project_id == Project.id) query = DBSession\ .query( Project.id, Project.name, Project.entity_type, Project.status_id, subquery.exists().label('has_children') ) if not self.show_completed_projects: from stalker import Status status_cmpl = \ Status.query.filter(Status.code == 'CMPL').first() query = query.filter(Project.status != status_cmpl) query = query.order_by(Project.name) projects = query.all() else: self.project.has_children = bool(self.project.tasks) projects = [self.project] logger.debug('projects: %s' % projects) # delete the old model if any if self.model() is not None: self.model().deleteLater() task_tree_model = TaskTreeModel() task_tree_model.populateTree(projects) self.setModel(task_tree_model) self.is_updating = False self.auto_fit_column() logger.debug('finished filling tasks_treeView')