def test_happy_path(self):
     with tempdir_context() as tempdir:
         zip_path = tempdir / "importmodule.1.zip"
         with zipfile.ZipFile(zip_path, mode="w") as zf:
             zf.writestr(
                 "importmodule.yaml",
                 json.dumps(
                     dict(
                         id_name="importmodule",
                         name="Importable module",
                         category="Clean",
                         parameters=[],
                     )).encode("utf-8"),
             )
             zf.writestr("importmodule.py",
                         b"def render(table, params): return table")
         clientside_module = import_zipfile(zip_path)
     self.assertEqual(
         clientside_module,
         clientside.Module(
             spec=ModuleSpec(
                 id_name="importmodule",
                 name="Importable module",
                 category="Clean",
                 parameters=[],
             ),
             js_module="",
         ),
     )
def import_zipfile(path: Path) -> clientside.Module:
    """
    Save a zipfile to database and minio and build a `clientside.Module`.

    Raise `WorkbenchModuleImportError` if `path` points to an invalid module.

    Otherwise, do not raise any errors one can sensibly recover from.
    """
    temp_zipfile = ModuleZipfile(path)
    validate_zipfile(temp_zipfile)  # raise WorkbenchModuleImportError
    module_id = temp_zipfile.module_id
    version = temp_zipfile.version
    module_spec = temp_zipfile.get_spec()
    js_module = temp_zipfile.get_optional_js_module() or ""

    minio.fput_file(minio.ExternalModulesBucket,
                    "%s/%s" % (module_id, path.name), path)
    ModuleVersion.objects.update_or_create(
        id_name=module_id,
        source_version_hash=version,
        spec=asdict(temp_zipfile.get_spec()),
        js_module=js_module,
    )

    return clientside.Module(module_spec, js_module)
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 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
            workflow.last_viewed_at = timezone.now()
            workflow.save(update_fields=["last_viewed_at"])

            state = clientside.Init(
                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 WfModule.live_in_workflow(workflow)
                },
                modules={
                    module_id: clientside.Module(
                        spec=module.get_spec(),
                        js_module=module.get_optional_js_module(),
                    )
                    for module_id, module in modules.items()
                },
            )
    except Workflow.DoesNotExist:
        raise Http404("Workflow was recently deleted")

    ctx = JsonizeContext(request.user, request.session, request.locale_id,
                         modules)
    return jsonize_clientside_init(state, ctx)
Exemple #5
0
 def to_clientside(self) -> clientside.Module:
     return clientside.Module(spec=self.spec, js_module=self.js_module)