コード例 #1
0
def make_init_state(request, workflow=None, modules=None):
    """Build a dict to embed as JSON in `window.initState` in HTML."""
    ret = {}

    if workflow:
        ret['workflowId'] = workflow.id
        ret['workflow'] = WorkflowSerializer(workflow,
                                             context={'request': request}).data
        wf_modules = workflow.wf_modules \
            .prefetch_related('parameter_vals__parameter_spec',
                              'module_version')
        wf_module_data_list = WfModuleSerializer(wf_modules, many=True).data
        ret['wfModules'] = dict([(str(wfm['id']), wfm)
                                 for wfm in wf_module_data_list])
        ret['selected_wf_module'] = workflow.selected_wf_module
        del ret['workflow']['selected_wf_module']

    if modules:
        modules_data_list = ModuleSerializer(modules, many=True).data
        ret['modules'] = dict([(str(m['id']), m) for m in modules_data_list])

    if request.user.is_authenticated():
        ret['loggedInUser'] = UserSerializer(request.user).data

    if workflow and not workflow.request_read_only(request):
        ret['updateTableModuleIds'] = load_update_table_module_ids()

    return ret
コード例 #2
0
    def get_workflow_as_delta_and_needs_render(self):
        """
        Return (apply-delta dict, needs_render), or raise Workflow.DoesNotExist

        needs_render is a (workflow_id, delta_id) pair.
        """
        with Workflow.authorized_lookup_and_cooperative_lock(
                'read',
                self.scope['user'],
                self.scope['session'],
                pk=self.workflow_id) as workflow:
            request = RequestWrapper(self.scope['user'], self.scope['session'])
            ret = {
                'updateWorkflow': (WorkflowSerializer(workflow,
                                                      context={
                                                          'request': request
                                                      }).data),
            }

            tabs = list(workflow.live_tabs)
            ret['updateTabs'] = dict(
                (tab.slug, TabSerializer(tab).data) for tab in tabs)
            wf_modules = list(WfModule.live_in_workflow(workflow.id))
            ret['updateWfModules'] = dict(
                (str(wfm.id), WfModuleSerializer(wfm).data)
                for wfm in wf_modules)

            if workflow.are_all_render_results_fresh():
                needs_render = None
            else:
                needs_render = (workflow.id, workflow.last_delta_id)

            return (ret, needs_render)
コード例 #3
0
def make_init_state(request, workflow=None, modules=None):
    """Build a dict to embed as JSON in `window.initState` in HTML."""
    ret = {}

    if workflow:
        ret['workflowId'] = workflow.id
        ret['workflow'] = WorkflowSerializer(workflow,
                                             context={'request': request}).data
        wf_modules = workflow.wf_modules \
            .prefetch_related('parameter_vals__parameter_spec',
                              'module_version')
        wf_module_data_list = WfModuleSerializer(wf_modules, many=True).data
        ret['wfModules'] = dict([(str(wfm['id']), wfm)
                                 for wfm in wf_module_data_list])
        ret['selected_wf_module'] = workflow.selected_wf_module
        ret['uploadConfig'] = {
            'bucket': minio.UserFilesBucket,
            'accessKey': settings.MINIO_ACCESS_KEY,  # never _SECRET_KEY
            'server': settings.MINIO_EXTERNAL_URL
        }
        ret['user_files_bucket'] = minio.UserFilesBucket
        del ret['workflow']['selected_wf_module']

    if modules:
        modules_data_list = ModuleSerializer(modules, many=True).data
        ret['modules'] = dict([(str(m['id']), m) for m in modules_data_list])

    if request.user.is_authenticated():
        ret['loggedInUser'] = UserSerializer(request.user).data

    if workflow and not workflow.request_read_only(request):
        ret['updateTableModuleIds'] = load_update_table_module_ids()

    return ret
コード例 #4
0
ファイル: workflows.py プロジェクト: mgerring/cjworkbench
def workflow_detail(request, pk, format=None):
    try:
        workflow = Workflow.objects.get(pk=pk)
    except Workflow.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)

    if not workflow.user_authorized(request.user):
        return HttpResponseForbidden()

    if request.method == 'GET':
        serializer = WorkflowSerializer(workflow)
        return Response(serializer.data)

    # We use PATCH to set the order of the modules when the user drags.
    elif request.method == 'PATCH':
        try:
            ReorderModulesCommand.create(workflow, request.data)
        except ValueError as e:
            # Caused by bad id or order keys not in range 0..n-1 (though they don't need to be sorted)
            return Response({'message': str(e), 'status_code':400}, status=status.HTTP_400_BAD_REQUEST)
        return Response(status=status.HTTP_204_NO_CONTENT)

    elif request.method == 'POST':
        try:
            ChangeWorkflowTitleCommand.create(workflow, request.data['newName'])
        except Exception as e:
            return Response({'message': str(e), 'status_code':400}, status=status.HTTP_400_BAD_REQUEST)

        return Response(status=status.HTTP_204_NO_CONTENT)

    elif request.method == 'DELETE':
        workflow.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)
コード例 #5
0
ファイル: workflows.py プロジェクト: mgerring/cjworkbench
def workflow_list(request, format=None):
    if request.method == 'GET':
        workflows = Workflow.objects.filter(owner=request.user)
        serializer = WorkflowSerializerLite(workflows, many=True)
        return Response(serializer.data)

    elif request.method == 'POST':
        serializer = WorkflowSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save(owner=request.user)
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
コード例 #6
0
    async def ws_notify(self):
        """
        Notify WebSocket clients that we just undid or redid.

        This default implementation sends a 'delta' command. It will always
        include a 'set-workflow' property; it may include a 'set-wf-module'
        command and may include a 'clear-wf-module' command.
        """
        data = {}

        with self.workflow.cooperative_lock():
            workflow_data = WorkflowSerializer(self.workflow).data
            # Remove the data we didn't generate correctly because we had no
            # HTTP request.
            del workflow_data['is_anonymous']
            del workflow_data['owner_name']
            del workflow_data['read_only']
            data['updateWorkflow'] = _prepare_json(workflow_data)
            data['updateWfModules'] = {}

            if hasattr(self, '_changed_wf_module_versions'):
                for id, delta_id in self._changed_wf_module_versions.items():
                    data['updateWfModules'][str(id)] = {
                        'last_relevant_delta_id': delta_id,
                        'error_msg': '',
                        # Tell clients this WfModule is "busy". Don't actually
                        # _set_ the busy flag: the busy flag is set exclusively
                        # by "fetch" (`module_dispatch_event`) and we can't
                        # override that safely. We don't need another busy flag
                        # for renders: this transient status is enough.
                        'status': 'busy',
                        'quick_fixes': [],
                        'output_columns': None
                    }

            if hasattr(self, 'wf_module'):
                self.wf_module.refresh_from_db()
                if self.wf_module.workflow_id:
                    wf_module_data = WfModuleSerializer(self.wf_module).data
                    wf_module_data['status'] = 'busy'  # rationale above

                    data['updateWfModules'][str(self.wf_module_id)] = \
                        _prepare_json(wf_module_data)
                else:
                    # When we did or undid this command, we removed the
                    # WfModule from the Workflow.
                    data['clearWfModuleIds'] = [self.wf_module_id]

        await websockets.ws_client_send_delta_async(self.workflow_id, data)
コード例 #7
0
def make_init_state(request, workflow=None, modules=None):
    """
    Build a dict to embed as JSON in `window.initState` in HTML.

    Raise Http404 if the workflow disappeared.
    """
    ret = {}

    if workflow:
        try:
            with workflow.cooperative_lock():  # raise DoesNotExist on race
                ret['workflowId'] = workflow.id
                ret['workflow'] = WorkflowSerializer(workflow,
                                                     context={
                                                         'request': request
                                                     }).data

                tabs = list(workflow.live_tabs)
                ret['tabs'] = dict(
                    (str(tab.slug), TabSerializer(tab).data) for tab in tabs)

                wf_modules = list(WfModule.live_in_workflow(workflow))

                ret['wfModules'] = {
                    str(wfm.id): WfModuleSerializer(wfm).data
                    for wfm in wf_modules
                }
        except Workflow.DoesNotExist:
            raise Http404('Workflow was recently deleted')

        ret['uploadConfig'] = {
            'bucket': minio.UserFilesBucket,
            'accessKey': settings.MINIO_ACCESS_KEY,  # never _SECRET_KEY
            'server': settings.MINIO_EXTERNAL_URL
        }
        ret['user_files_bucket'] = minio.UserFilesBucket

    if modules:
        modules_data_list = ModuleSerializer(modules, many=True).data
        ret['modules'] = dict([(str(m['id_name']), m)
                               for m in modules_data_list])

    if request.user.is_authenticated:
        ret['loggedInUser'] = UserSerializer(request.user).data

    return ret
コード例 #8
0
ファイル: workflows.py プロジェクト: ravinepal/cjworkbench
def make_init_state(request, workflow=None, modules=None):
    ret = {}

    if workflow:
        ret['workflowId'] = workflow.id
        ret['workflow'] = WorkflowSerializer(workflow, context={'user' : request.user}).data
        ret['selected_wf_module'] = workflow.selected_wf_module

    if modules:
        ret['modules'] = ModuleSerializer(modules, many=True).data

    if request.user.is_authenticated():
        ret['loggedInUser'] = UserSerializer(request.user).data
        ret['editCellsModuleId'] = edit_cells_module_id()
        ret['sortModuleId'] = sort_module_id()
        ret['reorderModuleId'] = reorder_module_id()

    return ret
コード例 #9
0
def make_init_state(request, workflow=None, modules=None):
    """
    Build a dict to embed as JSON in `window.initState` in HTML.

    Raise Http404 if the workflow disappeared.

    Side-effect: update workflow.last_viewed_at.
    """
    ret = {}

    if workflow:
        try:
            with workflow.cooperative_lock():  # raise DoesNotExist on race
                ret['workflowId'] = workflow.id
                ret['workflow'] = WorkflowSerializer(workflow,
                                                     context={
                                                         'request': request
                                                     }).data

                tabs = list(workflow.live_tabs)
                ret['tabs'] = dict(
                    (str(tab.slug), TabSerializer(tab).data) for tab in tabs)

                wf_modules = list(WfModule.live_in_workflow(workflow))

                ret['wfModules'] = {
                    str(wfm.id): WfModuleSerializer(wfm).data
                    for wfm in wf_modules
                }
                workflow.last_viewed_at = timezone.now()
                workflow.save(update_fields=['last_viewed_at'])
        except Workflow.DoesNotExist:
            raise Http404('Workflow was recently deleted')

    if modules:
        modules_data_list = ModuleSerializer(modules, many=True).data
        ret['modules'] = dict([(str(m['id_name']), m)
                               for m in modules_data_list])

    if request.user.is_authenticated:
        ret['loggedInUser'] = UserSerializer(request.user).data

    return ret
コード例 #10
0
ファイル: workflows.py プロジェクト: ravinepal/cjworkbench
def workflow_list(request, format=None):
    if request.method == 'GET':
        workflows = Workflow.objects.filter(Q(owner=request.user))

        # turn queryset into array so we can sort it ourselves by reverse chron
        workflows = workflows.all()
        workflows = sorted(workflows, key=lambda wf: wf.last_update(), reverse=True)

        serializer = WorkflowSerializerLite(workflows, many=True)
        return Response(serializer.data)

    elif request.method == 'POST':
        serializer = WorkflowSerializer(data=request.data, context={'user': request.user})
        if serializer.is_valid():
            serializer.save(owner=request.user)
            log_user_event(request.user, 'Create Workflow')
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
コード例 #11
0
ファイル: Delta.py プロジェクト: lijielife/cjworkbench
    def ws_notify(self):
        """
        Notify WebSocket clients that we just undid or redid.

        This default implementation sends a 'delta' command. It will always
        include a 'set-workflow' property; it may include a 'set-wf-module'
        command and may include a 'clear-wf-module' command.
        """
        data = {}

        with self.workflow.cooperative_lock():
            workflow_data = WorkflowSerializer(self.workflow).data
            # Remove the data we didn't generate correctly because we had no
            # HTTP request.
            del workflow_data['is_anonymous']
            del workflow_data['owner_name']
            del workflow_data['read_only']
            data['updateWorkflow'] = _prepare_json(workflow_data)
            data['updateWfModules'] = {}

            if hasattr(self, '_changed_wf_module_versions'):
                for id, delta_id in self._changed_wf_module_versions.items():
                    data['updateWfModules'][str(id)] = {
                        'last_relevant_delta_id': delta_id,
                        'error_msg': '',
                        'output_columns': None
                    }

            if hasattr(self, 'wf_module'):
                self.wf_module.refresh_from_db()
                if self.wf_module.workflow_id:
                    wf_module_data = WfModuleSerializer(self.wf_module).data

                    data['updateWfModules'][str(self.wf_module_id)] = \
                        _prepare_json(wf_module_data)
                else:
                    # When we did or undid this command, we removed the
                    # WfModule from the Workflow.
                    data['clearWfModuleIds'] = [self.wf_module_id]

        websockets.ws_client_send_delta_sync(self.workflow_id, data)
コード例 #12
0
ファイル: workflows.py プロジェクト: ravinepal/cjworkbench
def workflow_detail(request, pk, format=None):

    workflow = get_object_or_404(Workflow, pk=pk)

    if not workflow.user_authorized_read(request.user):
        return Response(status=status.HTTP_404_NOT_FOUND)

    if request.method == 'GET':
        if workflow.name.startswith('Demo'):
            log_user_event(request.user, 'Opened Demo Workflow', {'name': workflow.name})
        with workflow.cooperative_lock():
            serializer = WorkflowSerializer(workflow, context={'user' : request.user})
            return Response(serializer.data)

    # We use PATCH to set the order of the modules when the user drags.
    elif request.method == 'PATCH':
        if not workflow.user_authorized_write(request.user):
            return HttpResponseForbidden()

        try:
            ReorderModulesCommand.create(workflow, request.data)
        except ValueError as e:
            # Caused by bad id or order keys not in range 0..n-1 (though they don't need to be sorted)
            return Response({'message': str(e), 'status_code':400}, status=status.HTTP_400_BAD_REQUEST)
        return Response(status=status.HTTP_204_NO_CONTENT)

    elif request.method == 'POST':
        if not workflow.user_authorized_write(request.user):
            return HttpResponseForbidden()

        try:
            if not set(request.data.keys()).intersection({"newName", "public", "module_library_collapsed", "selected_wf_module"}):
                raise ValueError('Unknown fields: {}'.format(request.data))

            with workflow.cooperative_lock():
                if 'newName' in request.data:
                    ChangeWorkflowTitleCommand.create(workflow, request.data['newName'])

                if 'public' in request.data:
                    # TODO this should be a command, so it's undoable
                    workflow.public = request.data['public']
                    workflow.save()

                if 'module_library_collapsed' in request.data:
                    workflow.module_library_collapsed = request.data['module_library_collapsed']
                    workflow.save()

                if 'selected_wf_module' in request.data:
                    workflow.selected_wf_module = request.data['selected_wf_module']
                    workflow.save()

        except Exception as e:
            return Response({'message': str(e), 'status_code':400}, status=status.HTTP_400_BAD_REQUEST)
        return Response(status=status.HTTP_204_NO_CONTENT)

    elif request.method == 'DELETE':
        if not workflow.user_authorized_write(request.user):
            return HttpResponseForbidden()

        workflow.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)
コード例 #13
0
ファイル: workflows.py プロジェクト: milafrerichs/cjworkbench
def workflow_detail(request, pk, format=None):
    try:
        workflow = Workflow.objects.get(pk=pk)
    except Workflow.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)

    if not workflow.user_authorized_read(request.user):
        return Response(status=status.HTTP_404_NOT_FOUND)

    if request.method == 'GET':
        serializer = WorkflowSerializer(workflow,
                                        context={'user': request.user})
        return Response(serializer.data)

    # We use PATCH to set the order of the modules when the user drags.
    elif request.method == 'PATCH':
        if not workflow.user_authorized_write(request.user):
            return HttpResponseForbidden()

        try:
            ReorderModulesCommand.create(workflow, request.data)
        except ValueError as e:
            # Caused by bad id or order keys not in range 0..n-1 (though they don't need to be sorted)
            return Response({
                'message': str(e),
                'status_code': 400
            },
                            status=status.HTTP_400_BAD_REQUEST)
        return Response(status=status.HTTP_204_NO_CONTENT)

    elif request.method == 'POST':
        if not workflow.user_authorized_write(request.user):
            return HttpResponseForbidden()

        try:
            if not set(request.data.keys()).intersection({"newName", "public"
                                                          }):
                raise ValueError('Unknown fields: {}'.format(request.data))

            if 'newName' in request.data:
                ChangeWorkflowTitleCommand.create(workflow,
                                                  request.data['newName'])

            if 'public' in request.data:
                workflow.public = request.data['public']
                workflow.save()

        except Exception as e:
            return Response({
                'message': str(e),
                'status_code': 400
            },
                            status=status.HTTP_400_BAD_REQUEST)
        return Response(status=status.HTTP_204_NO_CONTENT)

    elif request.method == 'DELETE':
        if not workflow.user_authorized_write(request.user):
            return HttpResponseForbidden()

        workflow.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)