Exemple #1
0
def _render_workflows(request: HttpRequest, **kwargs) -> TemplateResponse:
    ctx = JsonizeContext(request.locale_id, {})

    workflows = list(
        Workflow.objects.filter(
            **kwargs).filter(Q(lesson_slug__isnull=True)
                             | Q(lesson_slug="")).prefetch_related(
                                 "acl", "owner").order_by("-updated_at"))

    clientside_workflows = [
        w.to_clientside(include_tab_slugs=False, include_block_slugs=False)
        for w in workflows
    ]

    json_workflows = [
        jsonize_clientside_workflow(w, ctx, is_init=True)
        for w in clientside_workflows
    ]

    if request.user.is_anonymous:
        json_user = None
    else:
        with transaction.atomic():
            lock_user_by_id(request.user.id, for_write=False)
            json_user = jsonize_clientside_user(
                query_clientside_user(request.user.id))

    init_state = {
        "loggedInUser": json_user,
        "workflows": json_workflows,
    }

    return TemplateResponse(request, "workflows.html",
                            {"initState": init_state})
Exemple #2
0
    def _get_workflow_as_clientside_update(self) -> WorkflowUpdateData:
        """Return (clientside.Update, delta_id).

        Raise Workflow.DoesNotExist if a race deletes the Workflow.
        """
        with self._lookup_requested_workflow_with_auth_and_cooperative_lock(
        ) as workflow:
            if self.scope["user"].is_anonymous:
                user = None
            else:
                user_id = self.scope["user"].id
                lock_user_by_id(user_id, for_write=False)
                user = query_clientside_user(user_id)

            update = clientside.Update(
                user=user,
                workflow=workflow.to_clientside(),
                tabs={
                    tab.slug: tab.to_clientside()
                    for tab in workflow.live_tabs
                },
                steps={
                    step.id: step.to_clientside()
                    for step in Step.live_in_workflow(workflow)
                },
            )
            return WorkflowUpdateData(update, workflow.last_delta_id)
Exemple #3
0
def make_init_state(request, workflow: Workflow,
                    modules: Dict[str, ModuleZipfile]) -> Dict[str, Any]:
    """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.
    """
    try:
        with workflow.cooperative_lock():  # raise DoesNotExist on race
            if request.user.is_anonymous:
                user = None
            else:
                lock_user_by_id(request.user.id, for_write=False)
                user = query_clientside_user(request.user.id)

            workflow.last_viewed_at = datetime.datetime.now()
            workflow.save(update_fields=["last_viewed_at"])

            state = clientside.Init(
                user=user,
                workflow=workflow.to_clientside(),
                tabs={
                    tab.slug: tab.to_clientside()
                    for tab in workflow.live_tabs
                },
                steps={
                    step.id: step.to_clientside(
                        force_module_zipfile=modules.get(step.module_id_name))
                    for step in Step.live_in_workflow(
                        workflow).prefetch_related("tab")
                },
                modules={
                    module_id: clientside.Module(
                        spec=module.get_spec(),
                        js_module=module.get_optional_js_module(),
                    )
                    for module_id, module in modules.items()
                },
                blocks={
                    block.slug: block.to_clientside()
                    for block in workflow.blocks.all()
                },
                settings={
                    "bigTableRowsPerTile": settings.BIG_TABLE_ROWS_PER_TILE,
                    "bigTableColumnsPerTile":
                    settings.BIG_TABLE_COLUMNS_PER_TILE,
                },
            )
    except Workflow.DoesNotExist:
        raise Http404("Workflow was recently deleted")

    ctx = JsonizeContext(request.locale_id, modules)
    return jsonize_clientside_init(state, ctx)
Exemple #4
0
def _render_course(request, course, lesson_url_prefix):
    logged_in_user = None
    if request.user and request.user.is_authenticated:
        with transaction.atomic():
            lock_user_by_id(request.user.id, for_write=False)
            logged_in_user = jsonize_clientside_user(
                query_clientside_user(request.user.id))

    try:
        courses = AllCoursesByLocale[course.locale_id]
    except KeyError:
        courses = []

    # We render using HTML, not React, to make this page SEO-friendly.
    return TemplateResponse(
        request,
        "course.html",
        {
            "initState":
            json.dumps({
                "loggedInUser":
                logged_in_user,
                "courses": [
                    dict(href=course.href, title=course.title)
                    for course in AllCoursesByLocale.get(
                        request.locale_id, [])
                ],
            }),
            "course":
            course,
            "courses":
            courses,
            "lessons":
            list(course.lessons.values()),
            "lesson_url_prefix":
            lesson_url_prefix,
        },
    )