예제 #1
0
    def execute(self, context):
        unlinked_ids = set()

        # First remove the Attract properties from the strips.
        for strip in context.selected_sequences:
            atc_object_id = getattr(strip, 'atc_object_id')
            remove_atc_props(strip)

            if atc_object_id:
                unlinked_ids.add(atc_object_id)

        # For all Object IDs that are no longer in use in the edit, let Attract know.
        # This should be done with care, as the shot could have been attached to multiple
        # strips.
        id_to_shots = compute_strip_conflicts(context.scene)
        for oid in unlinked_ids:
            if len(id_to_shots[oid]):
                # Still in use
                continue

            node = Node({'_id': oid})
            pillar.sync_call(node.patch, {'op': 'unlink'})

        if len(unlinked_ids) == 1:
            shot_id = unlinked_ids.pop()
            context.window_manager.clipboard = shot_id
            self.report({'INFO'}, 'Copied unlinked shot ID %s to clipboard' % shot_id)
        else:
            self.report({'INFO'}, '%i shots have been marked as Unused.' % len(unlinked_ids))

        draw.tag_redraw_all_sequencer_editors()
        return {'FINISHED'}
예제 #2
0
    def relink(self, strip, atc_object_id, *, refresh=False):
        from .. import pillar

        # The node may have been deleted, so we need to send a 'relink' before we try
        # to fetch the node itself.
        node = Node({'_id': atc_object_id})
        pillar.sync_call(node.patch, {'op': 'relink'})

        try:
            node = pillar.sync_call(Node.find, atc_object_id, caching=False)
        except (sdk_exceptions.ResourceNotFound, sdk_exceptions.MethodNotAllowed):
            verb = 'refresh' if refresh else 'relink'
            self.report({'ERROR'}, 'Shot %r not found on the Attract server, unable to %s.'
                        % (atc_object_id, verb))
            strip.atc_is_synced = False
            return {'CANCELLED'}

        strip.atc_is_synced = True
        if not refresh:
            strip.atc_name = node.name
            strip.atc_object_id = node['_id']

        # We do NOT set the position/cuts of the shot, that always has to come from Blender.
        strip.atc_status = node.properties.status
        strip.atc_notes = node.properties.notes or ''
        strip.atc_description = node.description or ''
        draw.tag_redraw_all_sequencer_editors()
예제 #3
0
def tasks():
    """User-assigned tasks"""
    # Pagination index
    page = request.args.get('page', 1)
    max_results = 50

    api = system_util.pillar_api()
    node_type_list = NodeType.all({'where': "name=='task'"}, api=api)

    if len(node_type_list['_items']) == 0:
        return "Empty NodeType list", 200

    node_type = node_type_list._items[0]

    tasks = Node.all({
        'where': '{"node_type" : "%s", "properties.owners.users": {"$in": ["%s"]}}'\
                % (node_type['_id'], current_user.objectid),
        'max_results': max_results,
        'page': page,
        'embedded': '{"parent":1, "picture":1}',
        'sort' : "order"}, api=api)

    # Build the pagination object
    # pagination = Pagination(int(page), max_results, tasks._meta.total)

    tasks_datatable = []
    for task in tasks._items:
        cut_in = 0
        cut_out = 0
        if task.parent.properties.cut_in:
            cut_in = task.parent.properties.cut_in
        if task.parent.properties.cut_out:
            cut_out = task.parent.properties.cut_out
        data = {
            'DT_RowId': "row_{0}".format(task._id),
            '_id': task._id,
            'order': task.order,
            'picture': None,
            'name': task.name,
            'timing': {
                'cut_in': task.parent.properties.cut_in,
                'cut_out': task.parent.properties.cut_out,
            },
            'parent': task.parent.to_dict(),
            'description': task.description,
            'url_view': url_for('nodes.view', node_id=task._id),
            'url_edit': url_for('nodes.edit', node_id=task._id, embed=1),
            'status': task.properties.status,
            }

        tasks_datatable.append(data)

    return render_template(
        'users/tasks.html',
        title="task",
        tasks_data=json.dumps(tasks_datatable),
        node_type=node_type)
예제 #4
0
def tasks():
    """User-assigned tasks"""
    # Pagination index
    page = request.args.get("page", 1)
    max_results = 50

    api = SystemUtility.attract_api()
    node_type_list = NodeType.all({"where": "name=='task'"}, api=api)

    if len(node_type_list["_items"]) == 0:
        return "Empty NodeType list", 200

    node_type = node_type_list._items[0]

    tasks = Node.all(
        {
            "where": '{"node_type" : "%s", "properties.owners.users": {"$in": ["%s"]}}'
            % (node_type["_id"], current_user.objectid),
            "max_results": max_results,
            "page": page,
            "embedded": '{"parent":1, "picture":1}',
            "sort": "order",
        },
        api=api,
    )

    # Build the pagination object
    # pagination = Pagination(int(page), max_results, tasks._meta.total)

    tasks_datatable = []
    for task in tasks._items:
        cut_in = 0
        cut_out = 0
        if task.parent.properties.cut_in:
            cut_in = task.parent.properties.cut_in
        if task.parent.properties.cut_out:
            cut_out = task.parent.properties.cut_out
        data = {
            "DT_RowId": "row_{0}".format(task._id),
            "_id": task._id,
            "order": task.order,
            "picture": None,
            "name": task.name,
            "timing": {"cut_in": task.parent.properties.cut_in, "cut_out": task.parent.properties.cut_out},
            "parent": task.parent.to_dict(),
            "description": task.description,
            "url_view": url_for("nodes.view", node_id=task._id),
            "url_edit": url_for("nodes.edit", node_id=task._id, embed=1),
            "status": task.properties.status,
        }

        tasks_datatable.append(data)

    return render_template(
        "users/tasks.html", title="task", tasks_data=json.dumps(tasks_datatable), node_type=node_type
    )
예제 #5
0
    def submit_new_strip(self, strip):
        from .. import pillar, blender

        # Define the shot properties
        user_uuid = pillar.pillar_user_uuid()
        if not user_uuid:
            self.report({'ERROR'}, 'Your Blender Cloud user ID is not known, '
                        'update your credentials.')
            return {'CANCELLED'}

        prop = {
            'name': strip.name,
            'description': '',
            'properties': {
                'status': 'todo',
                'notes': '',
                'used_in_edit': True,
                'trim_start_in_frames': strip.frame_offset_start,
                'trim_end_in_frames': strip.frame_offset_end,
                'duration_in_edit_in_frames': strip.frame_final_duration,
                'cut_in_timeline_in_frames': strip.frame_final_start
            },
            'order': 0,
            'node_type': 'attract_shot',
            'project': blender.preferences().attract_project.project,
            'user': user_uuid
        }

        # Create a Node item with the attract API
        node = Node(prop)
        post = pillar.sync_call(node.create)

        # Populate the strip with the freshly generated ObjectID and info
        if not post:
            self.report({'ERROR'},
                        'Error creating node! Check the console for now.')
            return {'CANCELLED'}

        strip.atc_object_id = node['_id']
        strip.atc_is_synced = True
        strip.atc_name = node['name']
        strip.atc_description = node['description']
        strip.atc_notes = node['properties']['notes']
        strip.atc_status = node['properties']['status']

        draw.tag_redraw_all_sequencer_editors()