Beispiel #1
0
    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()
Beispiel #2
0
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()
Beispiel #3
0
    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
            )
Beispiel #4
0
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"}
        )
Beispiel #6
0
    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()
Beispiel #7
0
    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),
        }
Beispiel #8
0
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]
Beispiel #10
0
    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()
Beispiel #12
0
    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)
Beispiel #13
0
    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 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()
Beispiel #15
0
    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
Beispiel #16
0
    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
Beispiel #18
0
    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)
Beispiel #19
0
    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()
Beispiel #20
0
    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"
Beispiel #21
0
    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
        )
Beispiel #22
0
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
Beispiel #23
0
    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()
Beispiel #24
0
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()
Beispiel #25
0
    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)
Beispiel #26
0
    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
Beispiel #27
0
    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)
Beispiel #28
0
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)
Beispiel #29
0
    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)
Beispiel #30
0
    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)
Beispiel #31
0
    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() 
Beispiel #32
0
    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()
Beispiel #33
0
    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
Beispiel #34
0
    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()
Beispiel #35
0
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()
Beispiel #36
0
    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)
Beispiel #38
0
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()
Beispiel #39
0
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
Beispiel #40
0
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()
Beispiel #41
0
    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
Beispiel #42
0
    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()
Beispiel #43
0
    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
        )
Beispiel #44
0
    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
Beispiel #45
0
 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()
Beispiel #46
0
    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"
            )
Beispiel #47
0
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()
Beispiel #48
0
    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")
Beispiel #49
0
 def reject(self):
     QtWidgets.QDialog.reject(self)
     from stalker.db.session import DBSession
     if self.version:
         DBSession.delete(self.version)
         DBSession.commit()
     DBSession.rollback()
Beispiel #50
0
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")
Beispiel #51
0
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()
Beispiel #52
0
 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
Beispiel #53
0
    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)
Beispiel #54
0
    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)
Beispiel #55
0
    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()
Beispiel #56
0
    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
Beispiel #57
0
    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))
Beispiel #58
0
    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')