コード例 #1
0
ファイル: comment.py プロジェクト: Arubinu/zou
class Comment(db.Model, BaseMixin, SerializerMixin):
    """
    Comment can occurs on any object but they are mainly used on tasks.
    In the case of comment tasks, they are linked to a task status and
    eventually on a preview file.
    The status means that comment leads to task status change. The preview file
    means that the comment relates to this preview in the context of the task.
    """
    shotgun_id = db.Column(db.Integer)

    object_id = db.Column(UUIDType(binary=False), nullable=False, index=True)
    object_type = db.Column(db.String(80), nullable=False, index=True)
    text = db.Column(db.Text())
    data = db.Column(JSONB)
    checklist = db.Column(JSONB)
    pinned = db.Column(db.Boolean)

    task_status_id = db.Column(UUIDType(binary=False),
                               db.ForeignKey("task_status.id"))
    person_id = db.Column(UUIDType(binary=False),
                          db.ForeignKey("person.id"),
                          nullable=False)
    preview_file_id = db.Column(UUIDType(binary=False),
                                db.ForeignKey("preview_file.id"))
    previews = db.relationship("PreviewFile",
                               secondary=preview_link_table,
                               backref="comments")
    mentions = db.relationship("Person", secondary=mentions_table)

    def __repr__(self):
        return "<Comment of %s>" % self.object_id
コード例 #2
0
class Entity(db.Model, BaseMixin, SerializerMixin):
    """
    Base model to represent assets, shots, sequences, episodes and scenes.
    They have different meaning but they share the same behaviour toward
    tasks and files.
    """
    id = db.Column(UUIDType(binary=False),
                   primary_key=True,
                   default=fields.gen_uuid)

    name = db.Column(db.String(160), nullable=False)
    code = db.Column(db.String(160))  # To store sanitized version of name
    description = db.Column(db.String(1200))
    shotgun_id = db.Column(db.Integer)
    canceled = db.Column(db.Boolean, default=False)

    nb_frames = db.Column(db.Integer)  # Specific to shots

    project_id = db.Column(UUIDType(binary=False),
                           db.ForeignKey("project.id"),
                           nullable=False,
                           index=True)
    entity_type_id = db.Column(UUIDType(binary=False),
                               db.ForeignKey("entity_type.id"),
                               nullable=False,
                               index=True)

    parent_id = db.Column(UUIDType(binary=False),
                          db.ForeignKey("entity.id"),
                          index=True)  # sequence or episode

    source_id = db.Column(
        UUIDType(binary=False),
        db.ForeignKey("entity.id"),
        index=True,
        nullable=True
    )  # if the entity is generated from another one (like shots from scene).

    preview_file_id = db.Column(
        UUIDType(binary=False),
        db.ForeignKey("preview_file.id", name="fk_main_preview"))
    data = db.Column(JSONB)

    entities_out = db.relationship(
        "Entity",
        secondary="entity_link",
        primaryjoin=(id == EntityLink.entity_in_id),
        secondaryjoin=(id == EntityLink.entity_out_id),
        backref="entities_in")

    instance_casting = db.relationship("AssetInstance",
                                       secondary="asset_instance_link",
                                       backref="shots")

    __table_args__ = (db.UniqueConstraint("name",
                                          "project_id",
                                          "entity_type_id",
                                          "parent_id",
                                          name="entity_uc"), )
コード例 #3
0
class Entity(db.Model, BaseMixin, SerializerMixin):
    id = db.Column(
        UUIDType(binary=False),
        primary_key=True,
        default=fields.gen_uuid
    )

    name = db.Column(db.String(160), nullable=False)
    description = db.Column(db.String(300))
    shotgun_id = db.Column(db.Integer)

    project_id = db.Column(
        UUIDType(binary=False), db.ForeignKey('project.id'), nullable=False)
    entity_type_id = db.Column(
        UUIDType(binary=False), db.ForeignKey('entity_type.id'), nullable=False)
    parent_id = db.Column(
        UUIDType(binary=False), db.ForeignKey('entity.id'))
    data = db.Column(JSONB)

    entities_out = db.relationship(
        'Entity',
        secondary=entity_link,
        primaryjoin=(id == entity_link.c.entity_in_id),
        secondaryjoin=(id == entity_link.c.entity_out_id)
    )

    __table_args__ = (
        db.UniqueConstraint(
            'name',
            'project_id',
            'entity_type_id',
            'parent_id',
            name='entity_uc'
        ),
    )
コード例 #4
0
class Task(db.Model, BaseMixin, SerializerMixin):
    """
    Describes a task done by a CG artist on an entity of the CG production.
    The task has a state and assigned to people. It handles notion of time like
    duration, start date and end date.
    """
    name = db.Column(db.String(80), nullable=False)
    description = db.Column(db.String(200))

    priority = db.Column(db.Integer, default=0)
    duration = db.Column(db.Integer, default=0)
    estimation = db.Column(db.Integer, default=0)
    completion_rate = db.Column(db.Integer, default=0)
    sort_order = db.Column(db.Integer, default=0)
    start_date = db.Column(db.DateTime)
    end_date = db.Column(db.DateTime)
    due_date = db.Column(db.DateTime)
    real_start_date = db.Column(db.DateTime)
    shotgun_id = db.Column(db.Integer)

    project_id = db.Column(
        UUIDType(binary=False),
        db.ForeignKey('project.id'),
        index=True
    )
    task_type_id = db.Column(
        UUIDType(binary=False),
        db.ForeignKey('task_type.id')
    )
    task_status_id = db.Column(
        UUIDType(binary=False),
        db.ForeignKey('task_status.id')
    )
    entity_id = db.Column(
        UUIDType(binary=False),
        db.ForeignKey('entity.id'),
        index=True
    )
    assigner_id = db.Column(
        UUIDType(binary=False),
        db.ForeignKey('person.id')
    )

    assignees = db.relationship(
        'Person',
        secondary=association_table
    )

    __table_args__ = (
        db.UniqueConstraint(
            'name',
            'project_id',
            'task_type_id',
            'entity_id',
            name='task_uc'
        ),
    )

    def assignees_as_string(self):
        return ", ".join([x.full_name() for x in self.assignees])
コード例 #5
0
class Person(db.Model, BaseMixin, SerializerMixin):

    first_name = db.Column(db.String(80), nullable=False)
    last_name = db.Column(db.String(80), nullable=False)
    email = db.Column(EmailType, unique=True)
    phone = db.Column(db.String(30))
    active = db.Column(db.Boolean(), default=True)
    last_presence = db.Column(db.Date())
    password = db.Column(db.Binary(60))
    shotgun_id = db.Column(db.Integer, unique=True)
    timezone = db.Column(TimezoneType(backend="pytz"),
                         default=pytz_timezone("Europe/Paris"))
    locale = db.Column(LocaleType, default=Locale("en", "US"))

    data = db.Column(JSONB)

    skills = db.relationship("Department", secondary=department_link)

    def __repr__(self):
        return "<Person %s>" % self.full_name()

    def full_name(self):
        if sys.version_info[0] < 3:
            return "%s %s" % (self.first_name.encode("utf-8"),
                              self.last_name.encode("utf-8"))
        else:
            return "%s %s" % (self.first_name, self.last_name)
コード例 #6
0
ファイル: project.py プロジェクト: Arubinu/zou
class Project(db.Model, BaseMixin, SerializerMixin):
    """
    Describes a CG production the studio works on.
    """
    name = db.Column(db.String(80), nullable=False, unique=True, index=True)
    code = db.Column(db.String(80))
    description = db.Column(db.String(200))
    shotgun_id = db.Column(db.Integer)
    file_tree = db.Column(JSONB)
    data = db.Column(JSONB)
    has_avatar = db.Column(db.Boolean(), default=False)
    fps = db.Column(db.String(10))
    ratio = db.Column(db.String(10))
    resolution = db.Column(db.String(12))
    production_type = db.Column(db.String(20), default="short")
    start_date = db.Column(db.Date())
    end_date = db.Column(db.Date())
    man_days = db.Column(db.Integer)

    project_status_id = db.Column(
        UUIDType(binary=False),
        db.ForeignKey('project_status.id'),
        index=True
    )

    team = db.relationship(
        "Person",
        secondary="project_person_link"
    )
コード例 #7
0
class Task(db.Model, BaseMixin, SerializerMixin):
    name = db.Column(db.String(80), nullable=False)
    description = db.Column(db.String(200))

    duration = db.Column(db.Integer)
    estimation = db.Column(db.Integer)
    completion_rate = db.Column(db.Integer)
    sort_order = db.Column(db.Integer)
    start_date = db.Column(db.DateTime)
    end_date = db.Column(db.DateTime)
    due_date = db.Column(db.DateTime)
    real_start_date = db.Column(db.DateTime)
    shotgun_id = db.Column(db.Integer)

    project_id = \
        db.Column(UUIDType(binary=False), db.ForeignKey('project.id'))
    task_type_id = \
        db.Column(UUIDType(binary=False), db.ForeignKey('task_type.id'))
    task_status_id = \
        db.Column(UUIDType(binary=False), db.ForeignKey('task_status.id'))
    entity_id = \
        db.Column(UUIDType(binary=False), db.ForeignKey('entity.id'))
    assigner_id = \
        db.Column(UUIDType(binary=False), db.ForeignKey('person.id'))

    assignees = db.relationship('Person', secondary=association_table)

    def assignees_as_string(self):
        return ", ".join([x.full_name() for x in self.assignees])
コード例 #8
0
ファイル: metadata_descriptor.py プロジェクト: cgwire/zou
class MetadataDescriptor(db.Model, BaseMixin, SerializerMixin):
    """
    This models allow to identify which metadata are available for a given
    project and a given entity type.
    """

    project_id = db.Column(
        UUIDType(binary=False),
        db.ForeignKey("project.id"),
        nullable=False,
        index=True,
    )
    entity_type = db.Column(db.String(60), nullable=False, index=True)
    name = db.Column(db.String(120), nullable=False)
    field_name = db.Column(db.String(120), nullable=False)
    choices = db.Column(JSONB)
    for_client = db.Column(db.Boolean(), default=False, index=True)
    departments = db.relationship(
        "Department", secondary=department_metadata_descriptor_link
    )

    __table_args__ = (
        db.UniqueConstraint(
            "project_id", "entity_type", "name", name="metadata_descriptor_uc"
        ),
    )

    def __repr__(self):
        return "<MetadataDescriptor %s>" % self.id
コード例 #9
0
class Project(db.Model, BaseMixin, SerializerMixin):
    """
    Describes a CG production the studio works on.
    """

    name = db.Column(db.String(80), nullable=False, unique=True, index=True)
    code = db.Column(db.String(80))
    description = db.Column(db.String(200))
    shotgun_id = db.Column(db.Integer)
    file_tree = db.Column(JSONB)
    data = db.Column(JSONB)
    has_avatar = db.Column(db.Boolean(), default=False)
    fps = db.Column(db.String(10))
    ratio = db.Column(db.String(10))
    resolution = db.Column(db.String(12))
    production_type = db.Column(db.String(20), default="short")
    start_date = db.Column(db.Date())
    end_date = db.Column(db.Date())
    man_days = db.Column(db.Integer)

    project_status_id = db.Column(UUIDType(binary=False),
                                  db.ForeignKey("project_status.id"),
                                  index=True)

    team = db.relationship("Person", secondary="project_person_link")

    def set_team(self, person_ids):
        for person_id in person_ids:
            link = ProjectPersonLink.query.filter_by(
                project_id=self.id, person_id=person_id).first()
            if link is None:
                link = ProjectPersonLink(project_id=self.id,
                                         person_id=person_id)
                db.session.add(link)
        db.session.commit()

    @classmethod
    def create_from_import(cls, data):
        previous_project = cls.get(data["id"])
        person_ids = data.get("team", None)
        del data["team"]
        del data["type"]

        if "project_status_name" in data:
            del data["project_status_name"]

        if previous_project is None:
            previous_project = cls.create(**data)
            previous_project.save()
        else:
            previous_project.update(data)
            previous_project.save()

        if person_ids is not None:
            previous_project.set_team(person_ids)

        return previous_project
コード例 #10
0
class EntityType(db.Model, BaseMixin, SerializerMixin):
    """
    Type of entities. It can describe either an asset type, or tell if target
    entity is a shot, sequence, episode or layout scene.
    """

    name = db.Column(db.String(30), unique=True, nullable=False, index=True)
    task_types = db.relationship("TaskType",
                                 secondary=task_type_link,
                                 lazy="joined")
コード例 #11
0
ファイル: person.py プロジェクト: tokejepsen/zou
class Person(db.Model, BaseMixin, SerializerMixin):
    """
    Describe a member of the studio (and an API user).
    """
    first_name = db.Column(db.String(80), nullable=False)
    last_name = db.Column(db.String(80), nullable=False)
    email = db.Column(EmailType, unique=True)
    phone = db.Column(db.String(30))

    active = db.Column(db.Boolean(), default=True)
    last_presence = db.Column(db.Date())

    password = db.Column(db.Binary(60))
    desktop_login = db.Column(db.String(80))
    shotgun_id = db.Column(db.Integer, unique=True)
    timezone = db.Column(
        TimezoneType(backend="pytz"),
        default=pytz_timezone("Europe/Paris")
    )
    locale = db.Column(LocaleType, default=Locale("en", "US"))
    data = db.Column(JSONB)
    role = db.Column(db.String(30), default="user")
    has_avatar = db.Column(db.Boolean(), default=False)

    skills = db.relationship(
        "Department",
        secondary=department_link
    )

    def __repr__(self):
        if sys.version_info[0] < 3:
            return "<Person %s>" % self.full_name().encode("utf-8")
        else:
            return "<Person %s>" % self.full_name()

    def full_name(self):
        return "%s %s" % (
            self.first_name,
            self.last_name
        )

    def serialize(self, obj_type="Person"):
        data = SerializerMixin.serialize(self, "Person")
        data["full_name"] = self.full_name()
        return data

    def serialize_safe(self):
        data = SerializerMixin.serialize(self, "Person")
        data["full_name"] = self.full_name()
        del data["password"]
        return data
コード例 #12
0
ファイル: entity.py プロジェクト: NeroSouza/zou
class Entity(db.Model, BaseMixin, SerializerMixin):
    """
    Base model to represent assets, shots, sequences, episodes and scenes.
    They have different meaning but they share the same behaviour toward
    tasks and files.
    """
    id = db.Column(
        UUIDType(binary=False),
        primary_key=True,
        default=fields.gen_uuid
    )

    name = db.Column(db.String(160), nullable=False)
    description = db.Column(db.String(600))
    shotgun_id = db.Column(db.Integer)
    canceled = db.Column(db.Boolean, default=False)

    project_id = db.Column(
        UUIDType(binary=False), db.ForeignKey('project.id'), nullable=False)
    entity_type_id = db.Column(
        UUIDType(binary=False), db.ForeignKey('entity_type.id'), nullable=False)
    parent_id = db.Column(
        UUIDType(binary=False), db.ForeignKey('entity.id'))
    preview_file_id = db.Column(
        UUIDType(binary=False),
        db.ForeignKey('preview_file.id', name="fk_main_preview")
    )
    data = db.Column(JSONB)

    entities_out = db.relationship(
        'Entity',
        secondary='entity_link',
        primaryjoin=(id == EntityLink.entity_in_id),
        secondaryjoin=(id == EntityLink.entity_out_id),
        backref="entities_in"
    )

    __table_args__ = (
        db.UniqueConstraint(
            'name',
            'project_id',
            'entity_type_id',
            'parent_id',
            name='entity_uc'
        ),
    )
コード例 #13
0
class Comment(db.Model, BaseMixin, SerializerMixin):
    """
    Comment can occurs on any object but they are mainly used on tasks.
    In the case of comment tasks, they are linked to a task status and
    eventually on a preview file.
    The status means that comment leads to task status change. The preview file
    means that the comment relates to this preview in the context of the task.
    """

    shotgun_id = db.Column(db.Integer)

    object_id = db.Column(UUIDType(binary=False), nullable=False, index=True)
    object_type = db.Column(db.String(80), nullable=False, index=True)
    text = db.Column(db.Text())
    data = db.Column(JSONB)
    checklist = db.Column(JSONB)
    pinned = db.Column(db.Boolean)

    task_status_id = db.Column(UUIDType(binary=False),
                               db.ForeignKey("task_status.id"))
    person_id = db.Column(UUIDType(binary=False),
                          db.ForeignKey("person.id"),
                          nullable=False)
    preview_file_id = db.Column(UUIDType(binary=False),
                                db.ForeignKey("preview_file.id"))
    previews = db.relationship("PreviewFile",
                               secondary=preview_link_table,
                               backref="comments")
    mentions = db.relationship("Person", secondary=mentions_table)
    acknowledgements = db.relationship("Person",
                                       secondary=acknowledgements_table)
    attachment_files = db.relationship("AttachmentFile", backref="comment")

    def __repr__(self):
        return "<Comment of %s>" % self.object_id

    def set_preview_files(self, preview_file_ids):
        from zou.app.models.preview_file import PreviewFile

        self.preview_files = []
        for preview_file_id in preview_file_ids:
            preview_file = PreviewFile.get(preview_file_id)
            if preview_file is not None:
                self.previews.append(preview_file)
        self.save()

    def set_mentions(self, person_ids):
        from zou.app.models.person import Person

        self.mentions = []
        for person_id in person_ids:
            person = Person.get(person_id)
            if person is not None:
                self.mentions.append(person)
        self.save()

    @classmethod
    def create_from_import(cls, data):
        previous_comment = cls.get(data["id"])
        preview_file_ids = data.get("previews", None)
        mention_ids = data.get("mentions", None)
        del data["previews"]
        del data["mentions"]
        del data["type"]

        if previous_comment is None:
            previous_comment = cls.create(**data)
            previous_comment.save()
        else:
            previous_comment.update(data)
            previous_comment.save()

        if preview_file_ids is not None:
            previous_comment.set_preview_files(preview_file_ids)

        if mention_ids is not None:
            previous_comment.set_mentions(mention_ids)

        return previous_comment
コード例 #14
0
ファイル: person.py プロジェクト: unit-image/zou
class Person(db.Model, BaseMixin, SerializerMixin):
    """
    Describe a member of the studio (and an API user).
    """

    first_name = db.Column(db.String(80), nullable=False)
    last_name = db.Column(db.String(80), nullable=False)
    email = db.Column(EmailType, unique=True)
    phone = db.Column(db.String(30))

    active = db.Column(db.Boolean(), default=True)
    last_presence = db.Column(db.Date())

    password = db.Column(db.LargeBinary(60))
    desktop_login = db.Column(db.String(80))
    shotgun_id = db.Column(db.Integer, unique=True)
    timezone = db.Column(TimezoneType(backend="pytz"),
                         default=pytz_timezone("Europe/Paris"))
    locale = db.Column(LocaleType, default=Locale("en", "US"))
    data = db.Column(JSONB)
    role = db.Column(db.String(30), default="user")
    has_avatar = db.Column(db.Boolean(), default=False)

    notifications_enabled = db.Column(db.Boolean(), default=False)
    notifications_slack_enabled = db.Column(db.Boolean(), default=False)
    notifications_slack_userid = db.Column(db.String(60), default="")

    skills = db.relationship("Department", secondary=department_link)

    def __repr__(self):
        if sys.version_info[0] < 3:
            return "<Person %s>" % self.full_name().encode("utf-8")
        else:
            return "<Person %s>" % self.full_name()

    def full_name(self):
        return "%s %s" % (self.first_name, self.last_name)

    def serialize(self, obj_type="Person", relations=False):
        data = SerializerMixin.serialize(self, "Person", relations=relations)
        data["full_name"] = self.full_name()
        return data

    def serialize_safe(self, relations=False):
        data = SerializerMixin.serialize(self, "Person", relations=relations)
        data["full_name"] = self.full_name()
        del data["password"]
        return data

    def present_minimal(self, relations=False):
        data = SerializerMixin.serialize(self, "Person", relations=relations)
        return {
            "id": data["id"],
            "first_name": data["first_name"],
            "last_name": data["last_name"],
            "full_name": self.full_name(),
            "has_avatar": data["has_avatar"],
            "active": data["active"],
            "desktop_login": data["desktop_login"]
        }

    @classmethod
    def create_from_import(cls, person):
        del person["type"]
        del person["full_name"]
        previous_person = cls.get(person["id"])
        if "password" in person:
            person["password"] = person["password"].encode()
        if previous_person is None:
            return (cls.create(**person), False)
        else:
            previous_person.update(person)
            return (previous_person, True)
コード例 #15
0
class Project(db.Model, BaseMixin, SerializerMixin):
    """
    Describes a CG production the studio works on.
    """

    name = db.Column(db.String(80), nullable=False, unique=True, index=True)
    code = db.Column(db.String(80))
    description = db.Column(db.Text())
    shotgun_id = db.Column(db.Integer)
    file_tree = db.Column(JSONB)
    data = db.Column(JSONB)
    has_avatar = db.Column(db.Boolean(), default=False)
    fps = db.Column(db.String(10))
    ratio = db.Column(db.String(10))
    resolution = db.Column(db.String(12))
    production_type = db.Column(db.String(20), default="short")
    start_date = db.Column(db.Date())
    end_date = db.Column(db.Date())
    man_days = db.Column(db.Integer)
    nb_episodes = db.Column(db.Integer, default=0)
    episode_span = db.Column(db.Integer, default=0)

    project_status_id = db.Column(
        UUIDType(binary=False), db.ForeignKey("project_status.id"), index=True
    )

    team = db.relationship("Person", secondary="project_person_link")
    asset_types = db.relationship(
        "EntityType", secondary="project_asset_type_link"
    )
    task_statuses = db.relationship(
        "TaskStatus", secondary="project_task_status_link"
    )
    task_types = db.relationship(
        "TaskType", secondary="project_task_type_link"
    )

    def set_team(self, person_ids):
        for person_id in person_ids:
            link = ProjectPersonLink.query.filter_by(
                project_id=self.id, person_id=person_id
            ).first()
            if link is None:
                link = ProjectPersonLink(
                    project_id=self.id, person_id=person_id
                )
                db.session.add(link)
        db.session.commit()

    def set_task_types(self, task_type_ids):
        return self.set_links(
            task_type_ids,
            ProjectTaskTypeLink,
            "project_id",
            "task_type_id"
        )

    def set_task_statuses(self, task_status_ids):
        return self.set_links(
            task_status_ids,
            ProjectTaskStatusLink,
            "project_id",
            "task_status_id",
        )

    def set_asset_types(self, asset_type_ids):
        return self.set_links(
            asset_type_ids,
            ProjectAssetTypeLink,
            "project_id",
            "asset_type_id"
        )

    @classmethod
    def create_from_import(cls, data):
        is_update = False
        previous_project = cls.get(data["id"])
        data.pop("team", None)
        data.pop("type", None)
        data.pop("project_status_name", None)
        person_ids = data.pop("team", None)
        task_type_ids = data.pop("task_types", None)
        task_status_ids = data.pop("task_statuses", None)
        asset_type_ids = data.pop("asset_types", None)

        if previous_project is None:
            previous_project = cls.create(**data)
            previous_project.save()
        else:
            is_update = True
            previous_project.update(data)
            previous_project.save()

        if person_ids is not None:
            previous_project.set_team(person_ids)

        if task_type_ids is not None:
            previous_project.set_task_types(task_type_ids)

        if task_status_ids is not None:
            previous_project.set_task_statuses(task_status_ids)

        if asset_type_ids is not None:
            previous_project.set_asset_types(asset_type_ids)

        return (previous_project, is_update)
コード例 #16
0
class Entity(db.Model, BaseMixin, SerializerMixin):
    """
    Base model to represent assets, shots, sequences, episodes and scenes.
    They have different meaning but they share the same behaviour toward
    tasks and files.
    """

    id = db.Column(UUIDType(binary=False),
                   primary_key=True,
                   default=fields.gen_uuid)

    name = db.Column(db.String(160), nullable=False)
    code = db.Column(db.String(160))  # To store sanitized version of name
    description = db.Column(db.String(1200))
    shotgun_id = db.Column(db.Integer)
    canceled = db.Column(db.Boolean, default=False)

    nb_frames = db.Column(db.Integer)  # Specific to shots
    nb_entities_out = db.Column(db.Integer, default=0)
    is_casting_standby = db.Column(db.Boolean, default=False)

    project_id = db.Column(
        UUIDType(binary=False),
        db.ForeignKey("project.id"),
        nullable=False,
        index=True,
    )
    entity_type_id = db.Column(
        UUIDType(binary=False),
        db.ForeignKey("entity_type.id"),
        nullable=False,
        index=True,
    )

    parent_id = db.Column(UUIDType(binary=False),
                          db.ForeignKey("entity.id"),
                          index=True)  # sequence or episode

    source_id = db.Column(
        UUIDType(binary=False),
        db.ForeignKey("entity.id"),
        index=True,
        nullable=True,
    )  # if the entity is generated from another one (like shots from scene).

    preview_file_id = db.Column(
        UUIDType(binary=False),
        db.ForeignKey("preview_file.id", name="fk_main_preview"),
    )
    data = db.Column(JSONB)

    ready_for = db.Column(
        UUIDType(binary=False),
        db.ForeignKey("task_type.id", name="fk_ready_for"),
    )

    entities_out = db.relationship(
        "Entity",
        secondary="entity_link",
        primaryjoin=(id == EntityLink.entity_in_id),
        secondaryjoin=(id == EntityLink.entity_out_id),
        backref="entities_in",
    )

    instance_casting = db.relationship("AssetInstance",
                                       secondary="asset_instance_link",
                                       backref="shots")

    __table_args__ = (db.UniqueConstraint(
        "name",
        "project_id",
        "entity_type_id",
        "parent_id",
        name="entity_uc",
    ), )

    def set_entities_out(self, entity_ids):
        self.entities_out = []
        for entity_id in entity_ids:
            entity = Entity.get(entity_id)
            if entity is not None:
                self.entities_out.append(entity)
        self.save()

    @classmethod
    def create_from_import(cls, data):
        is_update = False
        previous_entity = cls.get(data["id"])
        (data, entity_ids) = cls.sanitize_import_data(data)

        if previous_entity is None:
            previous_entity = cls.create(**data)
            previous_entity.save()
        else:
            is_update = True
            previous_entity.update(data)
            previous_entity.save()

        if entity_ids is not None:
            previous_entity.set_entities_out(entity_ids)

        return (previous_entity, is_update)

    @classmethod
    def sanitize_import_data(self, data):
        from zou.app.models.preview_file import PreviewFile
        from zou.app.models.entity_type import EntityType

        entity_ids = []
        model_type = data.get("type", "Shot")

        if "entities_out" in data:
            entity_ids = data["entities_out"]
            del data["entities_out"]

        if "asset_type_id" in data:
            data["entity_type_id"] = data["asset_type_id"]
            del data["asset_type_id"]
            del data["asset_type_name"]

        if "sequence_id" in data:
            data["parent_id"] = data["sequence_id"]
            del data["sequence_id"]

        if ("preview_file_id" in data and data["preview_file_id"] is not None
                and len(data["preview_file_id"]) > 0):
            preview_file = PreviewFile.get(data["preview_file_id"])
            if preview_file is None:
                del data["preview_file_id"]
        elif "preview_file_id" in data:
            del data["preview_file_id"]

        if "frame_in" in data:
            data["data"]["frame_in"] = data["frame_in"]
            del data["frame_in"]

        if "frame_out" in data:
            data["data"]["frame_out"] = data["frame_out"]
            del data["frame_out"]

        if "fps" in data:
            data["data"]["fps"] = data["fps"]
            del data["fps"]

        for field in [
                "entities_in",
                "episode_id",
                "episode_name",
                "project_name",
                "sequence_name",
                "tasks",
                "type",
        ]:
            if field in data:
                del data[field]

        if model_type in ["Shot", "Sequence", "Episode", "Edit"]:
            entity_type = EntityType.get_by(name=model_type)
            data["entity_type_id"] = entity_type.id

        return (data, entity_ids)
コード例 #17
0
class Person(db.Model, BaseMixin, SerializerMixin):
    """
    Describe a member of the studio (and an API user).
    """

    first_name = db.Column(db.String(80), nullable=False)
    last_name = db.Column(db.String(80), nullable=False)
    email = db.Column(EmailType, unique=True)
    phone = db.Column(db.String(30))

    active = db.Column(db.Boolean(), default=True)
    last_presence = db.Column(db.Date())

    password = db.Column(db.LargeBinary(60))
    desktop_login = db.Column(db.String(80))
    shotgun_id = db.Column(db.Integer, unique=True)
    timezone = db.Column(
        TimezoneType(backend="pytz"),
        default=pytz_timezone(config.DEFAULT_TIMEZONE),
    )
    locale = db.Column(LocaleType, default=Locale("en", "US"))
    data = db.Column(JSONB)
    role = db.Column(db.String(30), default="user")
    has_avatar = db.Column(db.Boolean(), default=False)

    notifications_enabled = db.Column(db.Boolean(), default=False)
    notifications_slack_enabled = db.Column(db.Boolean(), default=False)
    notifications_slack_userid = db.Column(db.String(60), default="")
    notifications_mattermost_enabled = db.Column(db.Boolean(), default=False)
    notifications_mattermost_userid = db.Column(db.String(60), default="")
    notifications_discord_enabled = db.Column(db.Boolean(), default=False)
    notifications_discord_userid = db.Column(db.String(60), default="")

    departments = db.relationship("Department",
                                  secondary=department_link,
                                  lazy="joined")

    def __repr__(self):
        if sys.version_info[0] < 3:
            return "<Person %s>" % self.full_name().encode("utf-8")
        else:
            return "<Person %s>" % self.full_name()

    def full_name(self):
        return "%s %s" % (self.first_name, self.last_name)

    def serialize(self, obj_type="Person", relations=False):
        data = SerializerMixin.serialize(self, "Person", relations=relations)
        data["full_name"] = self.full_name()
        return data

    def serialize_safe(self, relations=False):
        data = SerializerMixin.serialize(self, "Person", relations=relations)
        data["full_name"] = self.full_name()
        del data["password"]
        return data

    def present_minimal(self, relations=False):
        data = SerializerMixin.serialize(self, "Person", relations=relations)
        return {
            "id": data["id"],
            "first_name": data["first_name"],
            "last_name": data["last_name"],
            "full_name": self.full_name(),
            "has_avatar": data["has_avatar"],
            "active": data["active"],
            "departments": data.get("departments", []),
            "role": data["role"],
        }

    def set_departments(self, department_ids):
        from zou.app.models.department import Department

        self.departments = []
        for department_id in department_ids:
            department = Department.get(department_id)
            if department is not None:
                self.departments.append(department)
        self.save()

    @classmethod
    def create_from_import(cls, person):
        del person["type"]
        del person["full_name"]
        is_update = False
        previous_person = cls.get(person["id"])

        if "password" in person:
            person["password"] = person["password"].encode()

        department_ids = None
        if "departments" in person:
            department_ids = person.pop("departments", None)

        if previous_person is None:
            previous_person = cls.create(**person)
        else:
            is_update = True
            previous_person.update(person)

        if department_ids is not None:
            previous_person.set_departments(department_ids)

        return (previous_person, is_update)
コード例 #18
0
ファイル: task.py プロジェクト: unit-image/zou
class Task(db.Model, BaseMixin, SerializerMixin):
    """
    Describes a task done by a CG artist on an entity of the CG production.
    The task has a state and assigned to people. It handles notion of time like
    duration, start date and end date.
    """

    name = db.Column(db.String(80), nullable=False)
    description = db.Column(db.String(200))

    priority = db.Column(db.Integer, default=0)
    duration = db.Column(db.Integer, default=0)
    estimation = db.Column(db.Integer, default=0)
    completion_rate = db.Column(db.Integer, default=0)
    retake_count = db.Column(db.Integer, default=0)
    sort_order = db.Column(db.Integer, default=0)
    start_date = db.Column(db.DateTime)
    end_date = db.Column(db.DateTime)
    due_date = db.Column(db.DateTime)
    real_start_date = db.Column(db.DateTime)
    last_comment_date = db.Column(db.DateTime)
    data = db.Column(JSONB)
    shotgun_id = db.Column(db.Integer)

    project_id = db.Column(UUIDType(binary=False),
                           db.ForeignKey("project.id"),
                           index=True)
    task_type_id = db.Column(UUIDType(binary=False),
                             db.ForeignKey("task_type.id"),
                             index=True)
    task_status_id = db.Column(UUIDType(binary=False),
                               db.ForeignKey("task_status.id"),
                               index=True)
    entity_id = db.Column(UUIDType(binary=False),
                          db.ForeignKey("entity.id"),
                          index=True)
    assigner_id = db.Column(UUIDType(binary=False),
                            db.ForeignKey("person.id"),
                            index=True)
    assignees = db.relationship("Person", secondary=assignees_table)

    __table_args__ = (db.UniqueConstraint("name",
                                          "project_id",
                                          "task_type_id",
                                          "entity_id",
                                          name="task_uc"), )

    def assignees_as_string(self):
        return ", ".join([x.full_name() for x in self.assignees])

    def set_assignees(self, person_ids):
        from zou.app.models.person import Person

        self.assignees = []
        for person_id in person_ids:
            person = Person.get(person_id)
            if person is not None:
                self.assignees.append(person)
        self.save()

    @classmethod
    def create_from_import(cls, data):
        previous_task = cls.get(data["id"])
        person_ids = data.get("assignees", None)
        is_update = False
        if "assignees" in data:
            data.pop("assignees", None)
        if "type" in data:
            data.pop("type", None)

        if previous_task is None:
            previous_task = cls.create(**data)
            previous_task.save()
        else:
            is_update = True
            previous_task.update(data)
            previous_task.save()

        if person_ids is not None:
            previous_task.set_assignees(person_ids)

        return (previous_task, is_update)